mirror of https://github.com/rust-lang/rust.git
Auto merge of #89545 - workingjubilee:rollup-ooxf3p2, r=workingjubilee
Rollup of 15 pull requests Successful merges: - #87993 (Stabilize try_reserve) - #88090 (Perform type inference in range pattern) - #88780 (Added abs_diff for integer types.) - #89270 (path.push() should work as expected on windows verbatim paths) - #89413 (Correctly handle supertraits for min_specialization) - #89456 (Update to the final LLVM 13.0.0 release) - #89466 (Fix bug with query modifier parsing) - #89473 (Fix extra `non_snake_case` warning for shorthand field bindings) - #89474 (rustdoc: Improve doctest pass's name and module's name) - #89478 (Fixed numerus of error message) - #89480 (Add test for issue 89118.) - #89487 (Try to recover from a `=>` -> `=` or `->` typo in a match arm) - #89494 (Deny `where` clauses on `auto` traits) - #89511 (⬆️ rust-analyzer) - #89536 (update Miri) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
a804c4b112
|
@ -34,7 +34,7 @@
|
|||
[submodule "src/llvm-project"]
|
||||
path = src/llvm-project
|
||||
url = https://github.com/rust-lang/llvm-project.git
|
||||
branch = rustc/13.0-2021-08-08
|
||||
branch = rustc/13.0-2021-09-30
|
||||
[submodule "src/doc/embedded-book"]
|
||||
path = src/doc/embedded-book
|
||||
url = https://github.com/rust-embedded/book.git
|
||||
|
|
32
Cargo.lock
32
Cargo.lock
|
@ -360,7 +360,7 @@ version = "0.1.0"
|
|||
dependencies = [
|
||||
"directories",
|
||||
"rustc-workspace-hack",
|
||||
"rustc_version",
|
||||
"rustc_version 0.3.3",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"vergen",
|
||||
|
@ -1092,19 +1092,6 @@ dependencies = [
|
|||
"termcolor",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "env_logger"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "54532e3223c5af90a6a757c90b5c5521564b07e5e7a958681bcd2afad421cdcd"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"humantime 2.0.1",
|
||||
"log",
|
||||
"regex",
|
||||
"termcolor",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "env_logger"
|
||||
version = "0.9.0"
|
||||
|
@ -2250,7 +2237,7 @@ version = "0.1.0"
|
|||
dependencies = [
|
||||
"colored",
|
||||
"compiletest_rs",
|
||||
"env_logger 0.8.1",
|
||||
"env_logger 0.9.0",
|
||||
"getrandom 0.2.0",
|
||||
"hex 0.4.2",
|
||||
"libc",
|
||||
|
@ -2258,7 +2245,7 @@ dependencies = [
|
|||
"measureme",
|
||||
"rand 0.8.4",
|
||||
"rustc-workspace-hack",
|
||||
"rustc_version",
|
||||
"rustc_version 0.4.0",
|
||||
"shell-escape",
|
||||
"smallvec",
|
||||
]
|
||||
|
@ -4548,6 +4535,15 @@ dependencies = [
|
|||
"semver 0.11.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
|
||||
dependencies = [
|
||||
"semver 1.0.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustdoc"
|
||||
version = "0.0.0"
|
||||
|
@ -4908,9 +4904,9 @@ checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
|
|||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.6.1"
|
||||
version = "1.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e"
|
||||
checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309"
|
||||
|
||||
[[package]]
|
||||
name = "snap"
|
||||
|
|
|
@ -295,6 +295,7 @@ impl TokenKind {
|
|||
match *self {
|
||||
Comma => Some(vec![Dot, Lt, Semi]),
|
||||
Semi => Some(vec![Colon, Comma]),
|
||||
FatArrow => Some(vec![Eq, RArrow]),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -683,31 +683,53 @@ impl<'a> AstValidator<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn emit_e0568(&self, span: Span, ident_span: Span) {
|
||||
struct_span_err!(
|
||||
self.session,
|
||||
span,
|
||||
E0568,
|
||||
"auto traits cannot have super traits or lifetime bounds"
|
||||
)
|
||||
.span_label(ident_span, "auto trait cannot have super traits or lifetime bounds")
|
||||
.span_suggestion(
|
||||
span,
|
||||
"remove the super traits or lifetime bounds",
|
||||
String::new(),
|
||||
Applicability::MachineApplicable,
|
||||
)
|
||||
.emit();
|
||||
}
|
||||
|
||||
fn deny_super_traits(&self, bounds: &GenericBounds, ident_span: Span) {
|
||||
if let [first @ last] | [first, .., last] = &bounds[..] {
|
||||
let span = first.span().to(last.span());
|
||||
struct_span_err!(self.session, span, E0568, "auto traits cannot have super traits")
|
||||
.span_label(ident_span, "auto trait cannot have super traits")
|
||||
.span_suggestion(
|
||||
span,
|
||||
"remove the super traits",
|
||||
String::new(),
|
||||
Applicability::MachineApplicable,
|
||||
)
|
||||
.emit();
|
||||
if let [.., last] = &bounds[..] {
|
||||
let span = ident_span.shrink_to_hi().to(last.span());
|
||||
self.emit_e0568(span, ident_span);
|
||||
}
|
||||
}
|
||||
|
||||
fn deny_where_clause(&self, where_clause: &WhereClause, ident_span: Span) {
|
||||
if !where_clause.predicates.is_empty() {
|
||||
self.emit_e0568(where_clause.span, ident_span);
|
||||
}
|
||||
}
|
||||
|
||||
fn deny_items(&self, trait_items: &[P<AssocItem>], ident_span: Span) {
|
||||
if !trait_items.is_empty() {
|
||||
let spans: Vec<_> = trait_items.iter().map(|i| i.ident.span).collect();
|
||||
let total_span = trait_items.first().unwrap().span.to(trait_items.last().unwrap().span);
|
||||
struct_span_err!(
|
||||
self.session,
|
||||
spans,
|
||||
E0380,
|
||||
"auto traits cannot have methods or associated items"
|
||||
"auto traits cannot have associated items"
|
||||
)
|
||||
.span_label(ident_span, "auto trait cannot have items")
|
||||
.span_suggestion(
|
||||
total_span,
|
||||
"remove these associated items",
|
||||
String::new(),
|
||||
Applicability::MachineApplicable,
|
||||
)
|
||||
.span_label(ident_span, "auto trait cannot have associated items")
|
||||
.emit();
|
||||
}
|
||||
}
|
||||
|
@ -1184,6 +1206,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||
// Auto traits cannot have generics, super traits nor contain items.
|
||||
self.deny_generic_params(generics, item.ident.span);
|
||||
self.deny_super_traits(bounds, item.ident.span);
|
||||
self.deny_where_clause(&generics.where_clause, item.ident.span);
|
||||
self.deny_items(trait_items, item.ident.span);
|
||||
}
|
||||
self.no_questions_in_bounds(bounds, "supertraits", true);
|
||||
|
|
|
@ -31,7 +31,7 @@ const SSO_ARRAY_SIZE: usize = 8;
|
|||
//
|
||||
// Missing HashMap API:
|
||||
// all hasher-related
|
||||
// try_reserve (unstable)
|
||||
// try_reserve
|
||||
// shrink_to (unstable)
|
||||
// drain_filter (unstable)
|
||||
// into_keys/into_values (unstable)
|
||||
|
|
|
@ -13,7 +13,7 @@ use super::map::SsoHashMap;
|
|||
//
|
||||
// Missing HashSet API:
|
||||
// all hasher-related
|
||||
// try_reserve (unstable)
|
||||
// try_reserve
|
||||
// shrink_to (unstable)
|
||||
// drain_filter (unstable)
|
||||
// replace
|
||||
|
|
|
@ -437,12 +437,13 @@ impl<'tcx> LateLintPass<'tcx> for NonSnakeCase {
|
|||
if let hir::Node::Pat(parent_pat) = cx.tcx.hir().get(cx.tcx.hir().get_parent_node(hid))
|
||||
{
|
||||
if let PatKind::Struct(_, field_pats, _) = &parent_pat.kind {
|
||||
for field in field_pats.iter() {
|
||||
if field.ident != ident {
|
||||
// Only check if a new name has been introduced, to avoid warning
|
||||
// on both the struct definition and this pattern.
|
||||
self.check_snake_case(cx, "variable", &ident);
|
||||
}
|
||||
if field_pats
|
||||
.iter()
|
||||
.any(|field| !field.is_shorthand && field.pat.hir_id == p.hir_id)
|
||||
{
|
||||
// Only check if a new name has been introduced, to avoid warning
|
||||
// on both the struct definition and this pattern.
|
||||
self.check_snake_case(cx, "variable", &ident);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -455,28 +455,28 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream {
|
|||
|
||||
// Pass on the fatal_cycle modifier
|
||||
if let Some(fatal_cycle) = &modifiers.fatal_cycle {
|
||||
attributes.push(quote! { #fatal_cycle });
|
||||
attributes.push(quote! { (#fatal_cycle) });
|
||||
};
|
||||
// Pass on the storage modifier
|
||||
if let Some(ref ty) = modifiers.storage {
|
||||
let span = ty.span();
|
||||
attributes.push(quote_spanned! {span=> storage(#ty) });
|
||||
attributes.push(quote_spanned! {span=> (storage #ty) });
|
||||
};
|
||||
// Pass on the cycle_delay_bug modifier
|
||||
if let Some(cycle_delay_bug) = &modifiers.cycle_delay_bug {
|
||||
attributes.push(quote! { #cycle_delay_bug });
|
||||
attributes.push(quote! { (#cycle_delay_bug) });
|
||||
};
|
||||
// Pass on the no_hash modifier
|
||||
if let Some(no_hash) = &modifiers.no_hash {
|
||||
attributes.push(quote! { #no_hash });
|
||||
attributes.push(quote! { (#no_hash) });
|
||||
};
|
||||
// Pass on the anon modifier
|
||||
if let Some(anon) = &modifiers.anon {
|
||||
attributes.push(quote! { #anon });
|
||||
attributes.push(quote! { (#anon) });
|
||||
};
|
||||
// Pass on the eval_always modifier
|
||||
if let Some(eval_always) = &modifiers.eval_always {
|
||||
attributes.push(quote! { #eval_always });
|
||||
attributes.push(quote! { (#eval_always) });
|
||||
};
|
||||
|
||||
// This uses the span of the query definition for the commas,
|
||||
|
|
|
@ -140,11 +140,11 @@ macro_rules! is_eval_always_attr {
|
|||
}
|
||||
|
||||
macro_rules! contains_anon_attr {
|
||||
($($attr:ident $(($($attr_args:tt)*))* ),*) => ({$(is_anon_attr!($attr) | )* false});
|
||||
($(($attr:ident $($attr_args:tt)* )),*) => ({$(is_anon_attr!($attr) | )* false});
|
||||
}
|
||||
|
||||
macro_rules! contains_eval_always_attr {
|
||||
($($attr:ident $(($($attr_args:tt)*))* ),*) => ({$(is_eval_always_attr!($attr) | )* false});
|
||||
($(($attr:ident $($attr_args:tt)* )),*) => ({$(is_eval_always_attr!($attr) | )* false});
|
||||
}
|
||||
|
||||
#[allow(non_upper_case_globals)]
|
||||
|
|
|
@ -52,7 +52,6 @@
|
|||
#![feature(thread_local_const_init)]
|
||||
#![feature(trusted_step)]
|
||||
#![feature(try_blocks)]
|
||||
#![feature(try_reserve)]
|
||||
#![feature(try_reserve_kind)]
|
||||
#![feature(nonzero_ops)]
|
||||
#![recursion_limit = "512"]
|
||||
|
|
|
@ -111,11 +111,11 @@ macro_rules! query_storage {
|
|||
([][$K:ty, $V:ty]) => {
|
||||
<DefaultCacheSelector as CacheSelector<$K, $V>>::Cache
|
||||
};
|
||||
([storage($ty:ty) $($rest:tt)*][$K:ty, $V:ty]) => {
|
||||
([(storage $ty:ty) $($rest:tt)*][$K:ty, $V:ty]) => {
|
||||
<$ty as CacheSelector<$K, $V>>::Cache
|
||||
};
|
||||
([$other:ident $(($($other_args:tt)*))* $(, $($modifiers:tt)*)*][$($args:tt)*]) => {
|
||||
query_storage!([$($($modifiers)*)*][$($args)*])
|
||||
([$other:tt $($modifiers:tt)*][$($args:tt)*]) => {
|
||||
query_storage!([$($modifiers)*][$($args)*])
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -2322,7 +2322,24 @@ impl<'a> Parser<'a> {
|
|||
None
|
||||
};
|
||||
let arrow_span = this.token.span;
|
||||
this.expect(&token::FatArrow)?;
|
||||
if let Err(mut err) = this.expect(&token::FatArrow) {
|
||||
// We might have a `=>` -> `=` or `->` typo (issue #89396).
|
||||
if TokenKind::FatArrow
|
||||
.similar_tokens()
|
||||
.map_or(false, |similar_tokens| similar_tokens.contains(&this.token.kind))
|
||||
{
|
||||
err.span_suggestion(
|
||||
this.token.span,
|
||||
"try using a fat arrow here",
|
||||
"=>".to_string(),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
err.emit();
|
||||
this.bump();
|
||||
} else {
|
||||
return Err(err);
|
||||
}
|
||||
}
|
||||
let arm_start_span = this.token.span;
|
||||
|
||||
let expr = this.parse_expr_res(Restrictions::STMT_EXPR, None).map_err(|mut err| {
|
||||
|
|
|
@ -253,17 +253,17 @@ macro_rules! handle_cycle_error {
|
|||
$error.emit();
|
||||
Value::from_cycle_error($tcx)
|
||||
}};
|
||||
([fatal_cycle $($rest:tt)*][$tcx:expr, $error:expr]) => {{
|
||||
([(fatal_cycle) $($rest:tt)*][$tcx:expr, $error:expr]) => {{
|
||||
$error.emit();
|
||||
$tcx.sess.abort_if_errors();
|
||||
unreachable!()
|
||||
}};
|
||||
([cycle_delay_bug $($rest:tt)*][$tcx:expr, $error:expr]) => {{
|
||||
([(cycle_delay_bug) $($rest:tt)*][$tcx:expr, $error:expr]) => {{
|
||||
$error.delay_as_bug();
|
||||
Value::from_cycle_error($tcx)
|
||||
}};
|
||||
([$other:ident $(($($other_args:tt)*))* $(, $($modifiers:tt)*)*][$($args:tt)*]) => {
|
||||
handle_cycle_error!([$($($modifiers)*)*][$($args)*])
|
||||
([$other:tt $($modifiers:tt)*][$($args:tt)*]) => {
|
||||
handle_cycle_error!([$($modifiers)*][$($args)*])
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -271,11 +271,11 @@ macro_rules! is_anon {
|
|||
([]) => {{
|
||||
false
|
||||
}};
|
||||
([anon $($rest:tt)*]) => {{
|
||||
([(anon) $($rest:tt)*]) => {{
|
||||
true
|
||||
}};
|
||||
([$other:ident $(($($other_args:tt)*))* $(, $($modifiers:tt)*)*]) => {
|
||||
is_anon!([$($($modifiers)*)*])
|
||||
([$other:tt $($modifiers:tt)*]) => {
|
||||
is_anon!([$($modifiers)*])
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -283,11 +283,11 @@ macro_rules! is_eval_always {
|
|||
([]) => {{
|
||||
false
|
||||
}};
|
||||
([eval_always $($rest:tt)*]) => {{
|
||||
([(eval_always) $($rest:tt)*]) => {{
|
||||
true
|
||||
}};
|
||||
([$other:ident $(($($other_args:tt)*))* $(, $($modifiers:tt)*)*]) => {
|
||||
is_eval_always!([$($($modifiers)*)*])
|
||||
([$other:tt $($modifiers:tt)*]) => {
|
||||
is_eval_always!([$($modifiers)*])
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -295,11 +295,11 @@ macro_rules! hash_result {
|
|||
([][$hcx:expr, $result:expr]) => {{
|
||||
dep_graph::hash_result($hcx, &$result)
|
||||
}};
|
||||
([no_hash $($rest:tt)*][$hcx:expr, $result:expr]) => {{
|
||||
([(no_hash) $($rest:tt)*][$hcx:expr, $result:expr]) => {{
|
||||
None
|
||||
}};
|
||||
([$other:ident $(($($other_args:tt)*))* $(, $($modifiers:tt)*)*][$($args:tt)*]) => {
|
||||
hash_result!([$($($modifiers)*)*][$($args)*])
|
||||
([$other:tt $($modifiers:tt)*][$($args:tt)*]) => {
|
||||
hash_result!([$($modifiers)*][$($args)*])
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,9 @@ use crate::traits::normalize_projection_type;
|
|||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use rustc_errors::{error_code, struct_span_err, Applicability, DiagnosticBuilder, Style};
|
||||
use rustc_errors::{
|
||||
error_code, pluralize, struct_span_err, Applicability, DiagnosticBuilder, Style,
|
||||
};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::DefId;
|
||||
|
@ -2273,7 +2275,11 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
parent_trait_ref = child_trait_ref;
|
||||
}
|
||||
if count > 0 {
|
||||
err.note(&format!("{} redundant requirements hidden", count));
|
||||
err.note(&format!(
|
||||
"{} redundant requirement{} hidden",
|
||||
count,
|
||||
pluralize!(count)
|
||||
));
|
||||
err.note(&format!(
|
||||
"required because of the requirements on the impl of `{}` for `{}`",
|
||||
parent_trait_ref.print_only_trait_path(),
|
||||
|
|
|
@ -64,7 +64,9 @@ pub use self::specialize::specialization_graph::FutureCompatOverlapErrorKind;
|
|||
pub use self::specialize::{specialization_graph, translate_substs, OverlapError};
|
||||
pub use self::structural_match::search_for_structural_match_violation;
|
||||
pub use self::structural_match::NonStructuralMatchTy;
|
||||
pub use self::util::{elaborate_predicates, elaborate_trait_ref, elaborate_trait_refs};
|
||||
pub use self::util::{
|
||||
elaborate_obligations, elaborate_predicates, elaborate_trait_ref, elaborate_trait_refs,
|
||||
};
|
||||
pub use self::util::{expand_trait_aliases, TraitAliasExpander};
|
||||
pub use self::util::{
|
||||
get_vtable_index_of_object_method, impl_item_is_final, predicate_for_trait_def, upcast_choices,
|
||||
|
|
|
@ -449,16 +449,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
ti: TopInfo<'tcx>,
|
||||
) -> Ty<'tcx> {
|
||||
let calc_side = |opt_expr: Option<&'tcx hir::Expr<'tcx>>| match opt_expr {
|
||||
None => (None, None),
|
||||
None => None,
|
||||
Some(expr) => {
|
||||
let ty = self.check_expr(expr);
|
||||
// Check that the end-point is of numeric or char type.
|
||||
let fail = !(ty.is_numeric() || ty.is_char() || ty.references_error());
|
||||
(Some(ty), Some((fail, ty, expr.span)))
|
||||
// Check that the end-point is possibly of numeric or char type.
|
||||
// The early check here is not for correctness, but rather better
|
||||
// diagnostics (e.g. when `&str` is being matched, `expected` will
|
||||
// be peeled to `str` while ty here is still `&str`, if we don't
|
||||
// err ealy here, a rather confusing unification error will be
|
||||
// emitted instead).
|
||||
let fail =
|
||||
!(ty.is_numeric() || ty.is_char() || ty.is_ty_var() || ty.references_error());
|
||||
Some((fail, ty, expr.span))
|
||||
}
|
||||
};
|
||||
let (lhs_ty, lhs) = calc_side(lhs);
|
||||
let (rhs_ty, rhs) = calc_side(rhs);
|
||||
let mut lhs = calc_side(lhs);
|
||||
let mut rhs = calc_side(rhs);
|
||||
|
||||
if let (Some((true, ..)), _) | (_, Some((true, ..))) = (lhs, rhs) {
|
||||
// There exists a side that didn't meet our criteria that the end-point
|
||||
|
@ -467,25 +473,42 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
return self.tcx.ty_error();
|
||||
}
|
||||
|
||||
// Now that we know the types can be unified we find the unified type
|
||||
// and use it to type the entire expression.
|
||||
let common_type = self.resolve_vars_if_possible(lhs_ty.or(rhs_ty).unwrap_or(expected));
|
||||
|
||||
// Unify each side with `expected`.
|
||||
// Subtyping doesn't matter here, as the value is some kind of scalar.
|
||||
let demand_eqtype = |x, y| {
|
||||
if let Some((_, x_ty, x_span)) = x {
|
||||
let demand_eqtype = |x: &mut _, y| {
|
||||
if let Some((ref mut fail, x_ty, x_span)) = *x {
|
||||
if let Some(mut err) = self.demand_eqtype_pat_diag(x_span, expected, x_ty, ti) {
|
||||
if let Some((_, y_ty, y_span)) = y {
|
||||
self.endpoint_has_type(&mut err, y_span, y_ty);
|
||||
}
|
||||
err.emit();
|
||||
*fail = true;
|
||||
};
|
||||
}
|
||||
};
|
||||
demand_eqtype(lhs, rhs);
|
||||
demand_eqtype(rhs, lhs);
|
||||
demand_eqtype(&mut lhs, rhs);
|
||||
demand_eqtype(&mut rhs, lhs);
|
||||
|
||||
common_type
|
||||
if let (Some((true, ..)), _) | (_, Some((true, ..))) = (lhs, rhs) {
|
||||
return self.tcx.ty_error();
|
||||
}
|
||||
|
||||
// Find the unified type and check if it's of numeric or char type again.
|
||||
// This check is needed if both sides are inference variables.
|
||||
// We require types to be resolved here so that we emit inference failure
|
||||
// rather than "_ is not a char or numeric".
|
||||
let ty = self.structurally_resolved_type(span, expected);
|
||||
if !(ty.is_numeric() || ty.is_char() || ty.references_error()) {
|
||||
if let Some((ref mut fail, _, _)) = lhs {
|
||||
*fail = true;
|
||||
}
|
||||
if let Some((ref mut fail, _, _)) = rhs {
|
||||
*fail = true;
|
||||
}
|
||||
self.emit_err_pat_range(span, lhs, rhs);
|
||||
return self.tcx.ty_error();
|
||||
}
|
||||
ty
|
||||
}
|
||||
|
||||
fn endpoint_has_type(&self, err: &mut DiagnosticBuilder<'_>, span: Span, ty: Ty<'_>) {
|
||||
|
@ -512,10 +535,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
E0029,
|
||||
"only `char` and numeric types are allowed in range patterns"
|
||||
);
|
||||
let msg = |ty| format!("this is of type `{}` but it should be `char` or numeric", ty);
|
||||
let msg = |ty| {
|
||||
let ty = self.resolve_vars_if_possible(ty);
|
||||
format!("this is of type `{}` but it should be `char` or numeric", ty)
|
||||
};
|
||||
let mut one_side_err = |first_span, first_ty, second: Option<(bool, Ty<'tcx>, Span)>| {
|
||||
err.span_label(first_span, &msg(first_ty));
|
||||
if let Some((_, ty, sp)) = second {
|
||||
let ty = self.resolve_vars_if_possible(ty);
|
||||
self.endpoint_has_type(&mut err, sp, ty);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -74,7 +74,7 @@ use rustc_infer::infer::{InferCtxt, RegionckMode, TyCtxtInferExt};
|
|||
use rustc_infer::traits::specialization_graph::Node;
|
||||
use rustc_middle::ty::subst::{GenericArg, InternalSubsts, SubstsRef};
|
||||
use rustc_middle::ty::trait_def::TraitSpecializationKind;
|
||||
use rustc_middle::ty::{self, InstantiatedPredicates, TyCtxt, TypeFoldable};
|
||||
use rustc_middle::ty::{self, TyCtxt, TypeFoldable};
|
||||
use rustc_span::Span;
|
||||
use rustc_trait_selection::traits::{self, translate_substs, wf};
|
||||
|
||||
|
@ -294,13 +294,27 @@ fn check_predicates<'tcx>(
|
|||
span: Span,
|
||||
) {
|
||||
let tcx = infcx.tcx;
|
||||
let impl1_predicates = tcx.predicates_of(impl1_def_id).instantiate(tcx, impl1_substs);
|
||||
let impl1_predicates: Vec<_> = traits::elaborate_predicates(
|
||||
tcx,
|
||||
tcx.predicates_of(impl1_def_id).instantiate(tcx, impl1_substs).predicates.into_iter(),
|
||||
)
|
||||
.map(|obligation| obligation.predicate)
|
||||
.collect();
|
||||
|
||||
let mut impl2_predicates = if impl2_node.is_from_trait() {
|
||||
// Always applicable traits have to be always applicable without any
|
||||
// assumptions.
|
||||
InstantiatedPredicates::empty()
|
||||
Vec::new()
|
||||
} else {
|
||||
tcx.predicates_of(impl2_node.def_id()).instantiate(tcx, impl2_substs)
|
||||
traits::elaborate_predicates(
|
||||
tcx,
|
||||
tcx.predicates_of(impl2_node.def_id())
|
||||
.instantiate(tcx, impl2_substs)
|
||||
.predicates
|
||||
.into_iter(),
|
||||
)
|
||||
.map(|obligation| obligation.predicate)
|
||||
.collect()
|
||||
};
|
||||
debug!(
|
||||
"check_always_applicable(\nimpl1_predicates={:?},\nimpl2_predicates={:?}\n)",
|
||||
|
@ -322,13 +336,12 @@ fn check_predicates<'tcx>(
|
|||
// which is sound because we forbid impls like the following
|
||||
//
|
||||
// impl<D: Debug> AlwaysApplicable for D { }
|
||||
let always_applicable_traits =
|
||||
impl1_predicates.predicates.iter().copied().filter(|&predicate| {
|
||||
matches!(
|
||||
trait_predicate_kind(tcx, predicate),
|
||||
Some(TraitSpecializationKind::AlwaysApplicable)
|
||||
)
|
||||
});
|
||||
let always_applicable_traits = impl1_predicates.iter().copied().filter(|&predicate| {
|
||||
matches!(
|
||||
trait_predicate_kind(tcx, predicate),
|
||||
Some(TraitSpecializationKind::AlwaysApplicable)
|
||||
)
|
||||
});
|
||||
|
||||
// Include the well-formed predicates of the type parameters of the impl.
|
||||
for arg in tcx.impl_trait_ref(impl1_def_id).unwrap().substs {
|
||||
|
@ -340,18 +353,19 @@ fn check_predicates<'tcx>(
|
|||
arg,
|
||||
span,
|
||||
) {
|
||||
impl2_predicates
|
||||
.predicates
|
||||
.extend(obligations.into_iter().map(|obligation| obligation.predicate))
|
||||
impl2_predicates.extend(
|
||||
traits::elaborate_obligations(tcx, obligations)
|
||||
.map(|obligation| obligation.predicate),
|
||||
)
|
||||
}
|
||||
}
|
||||
impl2_predicates.predicates.extend(
|
||||
impl2_predicates.extend(
|
||||
traits::elaborate_predicates(tcx, always_applicable_traits)
|
||||
.map(|obligation| obligation.predicate),
|
||||
);
|
||||
|
||||
for predicate in impl1_predicates.predicates {
|
||||
if !impl2_predicates.predicates.contains(&predicate) {
|
||||
for predicate in impl1_predicates {
|
||||
if !impl2_predicates.contains(&predicate) {
|
||||
check_specialization_on(tcx, predicate, span)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ use core::fmt::Display;
|
|||
|
||||
/// The error type for `try_reserve` methods.
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
#[unstable(feature = "try_reserve", reason = "new API", issue = "48043")]
|
||||
#[stable(feature = "try_reserve", since = "1.57.0")]
|
||||
pub struct TryReserveError {
|
||||
kind: TryReserveErrorKind,
|
||||
}
|
||||
|
@ -126,7 +126,7 @@ impl From<LayoutError> for TryReserveErrorKind {
|
|||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "try_reserve", reason = "new API", issue = "48043")]
|
||||
#[stable(feature = "try_reserve", since = "1.57.0")]
|
||||
impl Display for TryReserveError {
|
||||
fn fmt(
|
||||
&self,
|
||||
|
|
|
@ -711,7 +711,6 @@ impl<T, A: Allocator> VecDeque<T, A> {
|
|||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(try_reserve)]
|
||||
/// use std::collections::TryReserveError;
|
||||
/// use std::collections::VecDeque;
|
||||
///
|
||||
|
@ -730,7 +729,7 @@ impl<T, A: Allocator> VecDeque<T, A> {
|
|||
/// }
|
||||
/// # process_data(&[1, 2, 3]).expect("why is the test harness OOMing on 12 bytes?");
|
||||
/// ```
|
||||
#[unstable(feature = "try_reserve", reason = "new API", issue = "48043")]
|
||||
#[stable(feature = "try_reserve", since = "1.57.0")]
|
||||
pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), TryReserveError> {
|
||||
self.try_reserve(additional)
|
||||
}
|
||||
|
@ -749,7 +748,6 @@ impl<T, A: Allocator> VecDeque<T, A> {
|
|||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(try_reserve)]
|
||||
/// use std::collections::TryReserveError;
|
||||
/// use std::collections::VecDeque;
|
||||
///
|
||||
|
@ -768,7 +766,7 @@ impl<T, A: Allocator> VecDeque<T, A> {
|
|||
/// }
|
||||
/// # process_data(&[1, 2, 3]).expect("why is the test harness OOMing on 12 bytes?");
|
||||
/// ```
|
||||
#[unstable(feature = "try_reserve", reason = "new API", issue = "48043")]
|
||||
#[stable(feature = "try_reserve", since = "1.57.0")]
|
||||
pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
|
||||
let old_cap = self.cap();
|
||||
let used_cap = self.len() + 1;
|
||||
|
|
|
@ -1009,7 +1009,6 @@ impl String {
|
|||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(try_reserve)]
|
||||
/// use std::collections::TryReserveError;
|
||||
///
|
||||
/// fn process_data(data: &str) -> Result<String, TryReserveError> {
|
||||
|
@ -1025,7 +1024,7 @@ impl String {
|
|||
/// }
|
||||
/// # process_data("rust").expect("why is the test harness OOMing on 4 bytes?");
|
||||
/// ```
|
||||
#[unstable(feature = "try_reserve", reason = "new API", issue = "48043")]
|
||||
#[stable(feature = "try_reserve", since = "1.57.0")]
|
||||
pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
|
||||
self.vec.try_reserve(additional)
|
||||
}
|
||||
|
@ -1049,7 +1048,6 @@ impl String {
|
|||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(try_reserve)]
|
||||
/// use std::collections::TryReserveError;
|
||||
///
|
||||
/// fn process_data(data: &str) -> Result<String, TryReserveError> {
|
||||
|
@ -1065,7 +1063,7 @@ impl String {
|
|||
/// }
|
||||
/// # process_data("rust").expect("why is the test harness OOMing on 4 bytes?");
|
||||
/// ```
|
||||
#[unstable(feature = "try_reserve", reason = "new API", issue = "48043")]
|
||||
#[stable(feature = "try_reserve", since = "1.57.0")]
|
||||
pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), TryReserveError> {
|
||||
self.vec.try_reserve_exact(additional)
|
||||
}
|
||||
|
|
|
@ -266,14 +266,21 @@ unsafe impl<T, A: Allocator> TrustedLen for IntoIter<T, A> {}
|
|||
|
||||
#[doc(hidden)]
|
||||
#[unstable(issue = "none", feature = "std_internals")]
|
||||
#[rustc_unsafe_specialization_marker]
|
||||
pub trait NonDrop {}
|
||||
|
||||
// T: Copy as approximation for !Drop since get_unchecked does not advance self.ptr
|
||||
// and thus we can't implement drop-handling
|
||||
//
|
||||
#[unstable(issue = "none", feature = "std_internals")]
|
||||
impl<T: Copy> NonDrop for T {}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[unstable(issue = "none", feature = "std_internals")]
|
||||
// TrustedRandomAccess (without NoCoerce) must not be implemented because
|
||||
// subtypes/supertypes of `T` might not be `Copy`
|
||||
// subtypes/supertypes of `T` might not be `NonDrop`
|
||||
unsafe impl<T, A: Allocator> TrustedRandomAccessNoCoerce for IntoIter<T, A>
|
||||
where
|
||||
T: Copy,
|
||||
T: NonDrop,
|
||||
{
|
||||
const MAY_HAVE_SIDE_EFFECT: bool = false;
|
||||
}
|
||||
|
|
|
@ -849,7 +849,6 @@ impl<T, A: Allocator> Vec<T, A> {
|
|||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(try_reserve)]
|
||||
/// use std::collections::TryReserveError;
|
||||
///
|
||||
/// fn process_data(data: &[u32]) -> Result<Vec<u32>, TryReserveError> {
|
||||
|
@ -867,7 +866,7 @@ impl<T, A: Allocator> Vec<T, A> {
|
|||
/// }
|
||||
/// # process_data(&[1, 2, 3]).expect("why is the test harness OOMing on 12 bytes?");
|
||||
/// ```
|
||||
#[unstable(feature = "try_reserve", reason = "new API", issue = "48043")]
|
||||
#[stable(feature = "try_reserve", since = "1.57.0")]
|
||||
pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
|
||||
self.buf.try_reserve(self.len, additional)
|
||||
}
|
||||
|
@ -892,7 +891,6 @@ impl<T, A: Allocator> Vec<T, A> {
|
|||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(try_reserve)]
|
||||
/// use std::collections::TryReserveError;
|
||||
///
|
||||
/// fn process_data(data: &[u32]) -> Result<Vec<u32>, TryReserveError> {
|
||||
|
@ -910,7 +908,7 @@ impl<T, A: Allocator> Vec<T, A> {
|
|||
/// }
|
||||
/// # process_data(&[1, 2, 3]).expect("why is the test harness OOMing on 12 bytes?");
|
||||
/// ```
|
||||
#[unstable(feature = "try_reserve", reason = "new API", issue = "48043")]
|
||||
#[stable(feature = "try_reserve", since = "1.57.0")]
|
||||
pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), TryReserveError> {
|
||||
self.buf.try_reserve_exact(self.len, additional)
|
||||
}
|
||||
|
|
|
@ -6,24 +6,14 @@ use super::{AsIntoIter, InPlaceDrop, SpecFromIter, SpecFromIterNested, Vec};
|
|||
|
||||
/// Specialization marker for collecting an iterator pipeline into a Vec while reusing the
|
||||
/// source allocation, i.e. executing the pipeline in place.
|
||||
///
|
||||
/// The SourceIter parent trait is necessary for the specializing function to access the allocation
|
||||
/// which is to be reused. But it is not sufficient for the specialization to be valid. See
|
||||
/// additional bounds on the impl.
|
||||
#[rustc_unsafe_specialization_marker]
|
||||
pub(super) trait SourceIterMarker: SourceIter<Source: AsIntoIter> {}
|
||||
pub(super) trait InPlaceIterableMarker {}
|
||||
|
||||
// The std-internal SourceIter/InPlaceIterable traits are only implemented by chains of
|
||||
// Adapter<Adapter<Adapter<IntoIter>>> (all owned by core/std). Additional bounds
|
||||
// on the adapter implementations (beyond `impl<I: Trait> Trait for Adapter<I>`) only depend on other
|
||||
// traits already marked as specialization traits (Copy, TrustedRandomAccess, FusedIterator).
|
||||
// I.e. the marker does not depend on lifetimes of user-supplied types. Modulo the Copy hole, which
|
||||
// several other specializations already depend on.
|
||||
impl<T> SourceIterMarker for T where T: SourceIter<Source: AsIntoIter> + InPlaceIterable {}
|
||||
impl<T> InPlaceIterableMarker for T where T: InPlaceIterable {}
|
||||
|
||||
impl<T, I> SpecFromIter<T, I> for Vec<T>
|
||||
where
|
||||
I: Iterator<Item = T> + SourceIterMarker,
|
||||
I: Iterator<Item = T> + SourceIter<Source: AsIntoIter> + InPlaceIterableMarker,
|
||||
{
|
||||
default fn from_iter(mut iterator: I) -> Self {
|
||||
// Additional requirements which cannot expressed via trait bounds. We rely on const eval
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
#![feature(new_uninit)]
|
||||
#![feature(pattern)]
|
||||
#![feature(trusted_len)]
|
||||
#![feature(try_reserve)]
|
||||
#![feature(try_reserve_kind)]
|
||||
#![feature(unboxed_closures)]
|
||||
#![feature(associated_type_bounds)]
|
||||
|
|
|
@ -249,14 +249,14 @@ impl<I> FusedIterator for Enumerate<I> where I: FusedIterator {}
|
|||
unsafe impl<I> TrustedLen for Enumerate<I> where I: TrustedLen {}
|
||||
|
||||
#[unstable(issue = "none", feature = "inplace_iteration")]
|
||||
unsafe impl<S: Iterator, I: Iterator> SourceIter for Enumerate<I>
|
||||
unsafe impl<I> SourceIter for Enumerate<I>
|
||||
where
|
||||
I: SourceIter<Source = S>,
|
||||
I: SourceIter,
|
||||
{
|
||||
type Source = S;
|
||||
type Source = I::Source;
|
||||
|
||||
#[inline]
|
||||
unsafe fn as_inner(&mut self) -> &mut S {
|
||||
unsafe fn as_inner(&mut self) -> &mut I::Source {
|
||||
// SAFETY: unsafe function forwarding to unsafe function with the same requirements
|
||||
unsafe { SourceIter::as_inner(&mut self.iter) }
|
||||
}
|
||||
|
|
|
@ -135,15 +135,14 @@ where
|
|||
impl<I: FusedIterator, P> FusedIterator for Filter<I, P> where P: FnMut(&I::Item) -> bool {}
|
||||
|
||||
#[unstable(issue = "none", feature = "inplace_iteration")]
|
||||
unsafe impl<S: Iterator, P, I: Iterator> SourceIter for Filter<I, P>
|
||||
unsafe impl<P, I> SourceIter for Filter<I, P>
|
||||
where
|
||||
P: FnMut(&I::Item) -> bool,
|
||||
I: SourceIter<Source = S>,
|
||||
I: SourceIter,
|
||||
{
|
||||
type Source = S;
|
||||
type Source = I::Source;
|
||||
|
||||
#[inline]
|
||||
unsafe fn as_inner(&mut self) -> &mut S {
|
||||
unsafe fn as_inner(&mut self) -> &mut I::Source {
|
||||
// SAFETY: unsafe function forwarding to unsafe function with the same requirements
|
||||
unsafe { SourceIter::as_inner(&mut self.iter) }
|
||||
}
|
||||
|
|
|
@ -129,15 +129,14 @@ where
|
|||
impl<B, I: FusedIterator, F> FusedIterator for FilterMap<I, F> where F: FnMut(I::Item) -> Option<B> {}
|
||||
|
||||
#[unstable(issue = "none", feature = "inplace_iteration")]
|
||||
unsafe impl<S: Iterator, B, I: Iterator, F> SourceIter for FilterMap<I, F>
|
||||
unsafe impl<I, F> SourceIter for FilterMap<I, F>
|
||||
where
|
||||
F: FnMut(I::Item) -> Option<B>,
|
||||
I: SourceIter<Source = S>,
|
||||
I: SourceIter,
|
||||
{
|
||||
type Source = S;
|
||||
type Source = I::Source;
|
||||
|
||||
#[inline]
|
||||
unsafe fn as_inner(&mut self) -> &mut S {
|
||||
unsafe fn as_inner(&mut self) -> &mut I::Source {
|
||||
// SAFETY: unsafe function forwarding to unsafe function with the same requirements
|
||||
unsafe { SourceIter::as_inner(&mut self.iter) }
|
||||
}
|
||||
|
|
|
@ -149,15 +149,14 @@ where
|
|||
impl<I: FusedIterator, F> FusedIterator for Inspect<I, F> where F: FnMut(&I::Item) {}
|
||||
|
||||
#[unstable(issue = "none", feature = "inplace_iteration")]
|
||||
unsafe impl<S: Iterator, I: Iterator, F> SourceIter for Inspect<I, F>
|
||||
unsafe impl<I, F> SourceIter for Inspect<I, F>
|
||||
where
|
||||
F: FnMut(&I::Item),
|
||||
I: SourceIter<Source = S>,
|
||||
I: SourceIter,
|
||||
{
|
||||
type Source = S;
|
||||
type Source = I::Source;
|
||||
|
||||
#[inline]
|
||||
unsafe fn as_inner(&mut self) -> &mut S {
|
||||
unsafe fn as_inner(&mut self) -> &mut I::Source {
|
||||
// SAFETY: unsafe function forwarding to unsafe function with the same requirements
|
||||
unsafe { SourceIter::as_inner(&mut self.iter) }
|
||||
}
|
||||
|
|
|
@ -201,15 +201,14 @@ where
|
|||
}
|
||||
|
||||
#[unstable(issue = "none", feature = "inplace_iteration")]
|
||||
unsafe impl<S: Iterator, B, I: Iterator, F> SourceIter for Map<I, F>
|
||||
unsafe impl<I, F> SourceIter for Map<I, F>
|
||||
where
|
||||
F: FnMut(I::Item) -> B,
|
||||
I: SourceIter<Source = S>,
|
||||
I: SourceIter,
|
||||
{
|
||||
type Source = S;
|
||||
type Source = I::Source;
|
||||
|
||||
#[inline]
|
||||
unsafe fn as_inner(&mut self) -> &mut S {
|
||||
unsafe fn as_inner(&mut self) -> &mut I::Source {
|
||||
// SAFETY: unsafe function forwarding to unsafe function with the same requirements
|
||||
unsafe { SourceIter::as_inner(&mut self.iter) }
|
||||
}
|
||||
|
|
|
@ -80,15 +80,14 @@ where
|
|||
}
|
||||
|
||||
#[unstable(issue = "none", feature = "inplace_iteration")]
|
||||
unsafe impl<S: Iterator, B, I: Iterator, P> SourceIter for MapWhile<I, P>
|
||||
unsafe impl<I, P> SourceIter for MapWhile<I, P>
|
||||
where
|
||||
P: FnMut(I::Item) -> Option<B>,
|
||||
I: SourceIter<Source = S>,
|
||||
I: SourceIter,
|
||||
{
|
||||
type Source = S;
|
||||
type Source = I::Source;
|
||||
|
||||
#[inline]
|
||||
unsafe fn as_inner(&mut self) -> &mut S {
|
||||
unsafe fn as_inner(&mut self) -> &mut I::Source {
|
||||
// SAFETY: unsafe function forwarding to unsafe function with the same requirements
|
||||
unsafe { SourceIter::as_inner(&mut self.iter) }
|
||||
}
|
||||
|
|
|
@ -92,9 +92,10 @@ pub use self::zip::zip;
|
|||
/// [`as_inner`]: SourceIter::as_inner
|
||||
#[unstable(issue = "none", feature = "inplace_iteration")]
|
||||
#[doc(hidden)]
|
||||
#[rustc_specialization_trait]
|
||||
pub unsafe trait SourceIter {
|
||||
/// A source stage in an iterator pipeline.
|
||||
type Source: Iterator;
|
||||
type Source;
|
||||
|
||||
/// Retrieve the source of an iterator pipeline.
|
||||
///
|
||||
|
@ -200,14 +201,14 @@ where
|
|||
}
|
||||
|
||||
#[unstable(issue = "none", feature = "inplace_iteration")]
|
||||
unsafe impl<S: Iterator, I, E> SourceIter for ResultShunt<'_, I, E>
|
||||
unsafe impl<I, E> SourceIter for ResultShunt<'_, I, E>
|
||||
where
|
||||
I: SourceIter<Source = S>,
|
||||
I: SourceIter,
|
||||
{
|
||||
type Source = S;
|
||||
type Source = I::Source;
|
||||
|
||||
#[inline]
|
||||
unsafe fn as_inner(&mut self) -> &mut S {
|
||||
unsafe fn as_inner(&mut self) -> &mut Self::Source {
|
||||
// SAFETY: unsafe function forwarding to unsafe function with the same requirements
|
||||
unsafe { SourceIter::as_inner(&mut self.iter) }
|
||||
}
|
||||
|
|
|
@ -321,14 +321,14 @@ impl<I: Iterator> Peekable<I> {
|
|||
unsafe impl<I> TrustedLen for Peekable<I> where I: TrustedLen {}
|
||||
|
||||
#[unstable(issue = "none", feature = "inplace_iteration")]
|
||||
unsafe impl<S: Iterator, I: Iterator> SourceIter for Peekable<I>
|
||||
unsafe impl<I: Iterator> SourceIter for Peekable<I>
|
||||
where
|
||||
I: SourceIter<Source = S>,
|
||||
I: SourceIter,
|
||||
{
|
||||
type Source = S;
|
||||
type Source = I::Source;
|
||||
|
||||
#[inline]
|
||||
unsafe fn as_inner(&mut self) -> &mut S {
|
||||
unsafe fn as_inner(&mut self) -> &mut I::Source {
|
||||
// SAFETY: unsafe function forwarding to unsafe function with the same requirements
|
||||
unsafe { SourceIter::as_inner(&mut self.iter) }
|
||||
}
|
||||
|
|
|
@ -90,15 +90,14 @@ where
|
|||
}
|
||||
|
||||
#[unstable(issue = "none", feature = "inplace_iteration")]
|
||||
unsafe impl<St, F, B, S: Iterator, I: Iterator> SourceIter for Scan<I, St, F>
|
||||
unsafe impl<St, F, I> SourceIter for Scan<I, St, F>
|
||||
where
|
||||
I: SourceIter<Source = S>,
|
||||
F: FnMut(&mut St, I::Item) -> Option<B>,
|
||||
I: SourceIter,
|
||||
{
|
||||
type Source = S;
|
||||
type Source = I::Source;
|
||||
|
||||
#[inline]
|
||||
unsafe fn as_inner(&mut self) -> &mut S {
|
||||
unsafe fn as_inner(&mut self) -> &mut I::Source {
|
||||
// SAFETY: unsafe function forwarding to unsafe function with the same requirements
|
||||
unsafe { SourceIter::as_inner(&mut self.iter) }
|
||||
}
|
||||
|
|
|
@ -222,14 +222,14 @@ where
|
|||
impl<I> FusedIterator for Skip<I> where I: FusedIterator {}
|
||||
|
||||
#[unstable(issue = "none", feature = "inplace_iteration")]
|
||||
unsafe impl<S: Iterator, I: Iterator> SourceIter for Skip<I>
|
||||
unsafe impl<I> SourceIter for Skip<I>
|
||||
where
|
||||
I: SourceIter<Source = S>,
|
||||
I: SourceIter,
|
||||
{
|
||||
type Source = S;
|
||||
type Source = I::Source;
|
||||
|
||||
#[inline]
|
||||
unsafe fn as_inner(&mut self) -> &mut S {
|
||||
unsafe fn as_inner(&mut self) -> &mut I::Source {
|
||||
// SAFETY: unsafe function forwarding to unsafe function with the same requirements
|
||||
unsafe { SourceIter::as_inner(&mut self.iter) }
|
||||
}
|
||||
|
|
|
@ -105,15 +105,14 @@ where
|
|||
}
|
||||
|
||||
#[unstable(issue = "none", feature = "inplace_iteration")]
|
||||
unsafe impl<S: Iterator, P, I: Iterator> SourceIter for SkipWhile<I, P>
|
||||
unsafe impl<P, I> SourceIter for SkipWhile<I, P>
|
||||
where
|
||||
P: FnMut(&I::Item) -> bool,
|
||||
I: SourceIter<Source = S>,
|
||||
I: SourceIter,
|
||||
{
|
||||
type Source = S;
|
||||
type Source = I::Source;
|
||||
|
||||
#[inline]
|
||||
unsafe fn as_inner(&mut self) -> &mut S {
|
||||
unsafe fn as_inner(&mut self) -> &mut I::Source {
|
||||
// SAFETY: unsafe function forwarding to unsafe function with the same requirements
|
||||
unsafe { SourceIter::as_inner(&mut self.iter) }
|
||||
}
|
||||
|
|
|
@ -130,14 +130,14 @@ where
|
|||
}
|
||||
|
||||
#[unstable(issue = "none", feature = "inplace_iteration")]
|
||||
unsafe impl<S: Iterator, I: Iterator> SourceIter for Take<I>
|
||||
unsafe impl<I> SourceIter for Take<I>
|
||||
where
|
||||
I: SourceIter<Source = S>,
|
||||
I: SourceIter,
|
||||
{
|
||||
type Source = S;
|
||||
type Source = I::Source;
|
||||
|
||||
#[inline]
|
||||
unsafe fn as_inner(&mut self) -> &mut S {
|
||||
unsafe fn as_inner(&mut self) -> &mut I::Source {
|
||||
// SAFETY: unsafe function forwarding to unsafe function with the same requirements
|
||||
unsafe { SourceIter::as_inner(&mut self.iter) }
|
||||
}
|
||||
|
|
|
@ -118,15 +118,14 @@ where
|
|||
}
|
||||
|
||||
#[unstable(issue = "none", feature = "inplace_iteration")]
|
||||
unsafe impl<S: Iterator, P, I: Iterator> SourceIter for TakeWhile<I, P>
|
||||
unsafe impl<P, I> SourceIter for TakeWhile<I, P>
|
||||
where
|
||||
P: FnMut(&I::Item) -> bool,
|
||||
I: SourceIter<Source = S>,
|
||||
I: SourceIter,
|
||||
{
|
||||
type Source = S;
|
||||
type Source = I::Source;
|
||||
|
||||
#[inline]
|
||||
unsafe fn as_inner(&mut self) -> &mut S {
|
||||
unsafe fn as_inner(&mut self) -> &mut I::Source {
|
||||
// SAFETY: unsafe function forwarding to unsafe function with the same requirements
|
||||
unsafe { SourceIter::as_inner(&mut self.iter) }
|
||||
}
|
||||
|
|
|
@ -414,16 +414,14 @@ where
|
|||
// Arbitrarily selects the left side of the zip iteration as extractable "source"
|
||||
// it would require negative trait bounds to be able to try both
|
||||
#[unstable(issue = "none", feature = "inplace_iteration")]
|
||||
unsafe impl<S, A, B> SourceIter for Zip<A, B>
|
||||
unsafe impl<A, B> SourceIter for Zip<A, B>
|
||||
where
|
||||
A: SourceIter<Source = S>,
|
||||
B: Iterator,
|
||||
S: Iterator,
|
||||
A: SourceIter,
|
||||
{
|
||||
type Source = S;
|
||||
type Source = A::Source;
|
||||
|
||||
#[inline]
|
||||
unsafe fn as_inner(&mut self) -> &mut S {
|
||||
unsafe fn as_inner(&mut self) -> &mut A::Source {
|
||||
// SAFETY: unsafe function forwarding to unsafe function with the same requirements
|
||||
unsafe { SourceIter::as_inner(&mut self.a) }
|
||||
}
|
||||
|
|
|
@ -2235,6 +2235,46 @@ macro_rules! int_impl {
|
|||
}
|
||||
}
|
||||
|
||||
/// Computes the absolute difference between `self` and `other`.
|
||||
///
|
||||
/// This function always returns the correct answer without overflow or
|
||||
/// panics by returning an unsigned integer.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(int_abs_diff)]
|
||||
#[doc = concat!("assert_eq!(100", stringify!($SelfT), ".abs_diff(80), 20", stringify!($UnsignedT), ");")]
|
||||
#[doc = concat!("assert_eq!(100", stringify!($SelfT), ".abs_diff(110), 10", stringify!($UnsignedT), ");")]
|
||||
#[doc = concat!("assert_eq!((-100", stringify!($SelfT), ").abs_diff(80), 180", stringify!($UnsignedT), ");")]
|
||||
#[doc = concat!("assert_eq!((-100", stringify!($SelfT), ").abs_diff(-120), 20", stringify!($UnsignedT), ");")]
|
||||
#[doc = concat!("assert_eq!(", stringify!($SelfT), "::MIN.abs_diff(", stringify!($SelfT), "::MAX), ", stringify!($UnsignedT), "::MAX);")]
|
||||
/// ```
|
||||
#[unstable(feature = "int_abs_diff", issue = "89492")]
|
||||
#[inline]
|
||||
pub const fn abs_diff(self, other: Self) -> $UnsignedT {
|
||||
if self < other {
|
||||
// Converting a non-negative x from signed to unsigned by using
|
||||
// `x as U` is left unchanged, but a negative x is converted
|
||||
// to value x + 2^N. Thus if `s` and `o` are binary variables
|
||||
// respectively indicating whether `self` and `other` are
|
||||
// negative, we are computing the mathematical value:
|
||||
//
|
||||
// (other + o*2^N) - (self + s*2^N) mod 2^N
|
||||
// other - self + (o-s)*2^N mod 2^N
|
||||
// other - self mod 2^N
|
||||
//
|
||||
// Finally, taking the mod 2^N of the mathematical value of
|
||||
// `other - self` does not change it as it already is
|
||||
// in the range [0, 2^N).
|
||||
(other as $UnsignedT).wrapping_sub(self as $UnsignedT)
|
||||
} else {
|
||||
(self as $UnsignedT).wrapping_sub(other as $UnsignedT)
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a number representing sign of `self`.
|
||||
///
|
||||
/// - `0` if the number is zero
|
||||
|
|
|
@ -1490,6 +1490,33 @@ macro_rules! uint_impl {
|
|||
(c, b | d)
|
||||
}
|
||||
|
||||
/// Computes the absolute difference between `self` and `other`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(int_abs_diff)]
|
||||
#[doc = concat!("assert_eq!(100", stringify!($SelfT), ".abs_diff(80), 20", stringify!($SelfT), ");")]
|
||||
#[doc = concat!("assert_eq!(100", stringify!($SelfT), ".abs_diff(110), 10", stringify!($SelfT), ");")]
|
||||
/// ```
|
||||
#[unstable(feature = "int_abs_diff", issue = "89492")]
|
||||
#[inline]
|
||||
pub const fn abs_diff(self, other: Self) -> Self {
|
||||
if mem::size_of::<Self>() == 1 {
|
||||
// Trick LLVM into generating the psadbw instruction when SSE2
|
||||
// is available and this function is autovectorized for u8's.
|
||||
(self as i32).wrapping_sub(other as i32).abs() as Self
|
||||
} else {
|
||||
if self < other {
|
||||
other - self
|
||||
} else {
|
||||
self - other
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Calculates the multiplication of `self` and `rhs`.
|
||||
///
|
||||
/// Returns a tuple of the multiplication along with a boolean
|
||||
|
|
|
@ -625,14 +625,13 @@ where
|
|||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(try_reserve)]
|
||||
/// use std::collections::HashMap;
|
||||
///
|
||||
/// let mut map: HashMap<&str, isize> = HashMap::new();
|
||||
/// map.try_reserve(10).expect("why is the test harness OOMing on 10 bytes?");
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "try_reserve", reason = "new API", issue = "48043")]
|
||||
#[stable(feature = "try_reserve", since = "1.57.0")]
|
||||
pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
|
||||
self.base.try_reserve(additional).map_err(map_try_reserve_error)
|
||||
}
|
||||
|
|
|
@ -423,13 +423,12 @@ where
|
|||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(try_reserve)]
|
||||
/// use std::collections::HashSet;
|
||||
/// let mut set: HashSet<i32> = HashSet::new();
|
||||
/// set.try_reserve(10).expect("why is the test harness OOMing on 10 bytes?");
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "try_reserve", reason = "new API", issue = "48043")]
|
||||
#[stable(feature = "try_reserve", since = "1.57.0")]
|
||||
pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
|
||||
self.base.try_reserve(additional).map_err(map_try_reserve_error)
|
||||
}
|
||||
|
|
|
@ -420,7 +420,7 @@ pub use self::hash_map::HashMap;
|
|||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use self::hash_set::HashSet;
|
||||
|
||||
#[unstable(feature = "try_reserve", reason = "new API", issue = "48043")]
|
||||
#[stable(feature = "try_reserve", since = "1.57.0")]
|
||||
pub use alloc_crate::collections::TryReserveError;
|
||||
#[unstable(
|
||||
feature = "try_reserve_kind",
|
||||
|
|
|
@ -595,7 +595,7 @@ impl Error for char::ParseCharError {
|
|||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "try_reserve", reason = "new API", issue = "48043")]
|
||||
#[stable(feature = "try_reserve", since = "1.57.0")]
|
||||
impl Error for alloc::collections::TryReserveError {}
|
||||
|
||||
#[unstable(feature = "duration_checked_float", issue = "83400")]
|
||||
|
|
|
@ -331,7 +331,6 @@
|
|||
#![feature(total_cmp)]
|
||||
#![feature(trace_macros)]
|
||||
#![feature(try_blocks)]
|
||||
#![feature(try_reserve)]
|
||||
#![feature(try_reserve_kind)]
|
||||
#![feature(unboxed_closures)]
|
||||
#![feature(unwrap_infallible)]
|
||||
|
|
|
@ -1231,20 +1231,59 @@ impl PathBuf {
|
|||
let mut need_sep = self.as_mut_vec().last().map(|c| !is_sep_byte(*c)).unwrap_or(false);
|
||||
|
||||
// in the special case of `C:` on Windows, do *not* add a separator
|
||||
let comps = self.components();
|
||||
|
||||
if comps.prefix_len() > 0
|
||||
&& comps.prefix_len() == comps.path.len()
|
||||
&& comps.prefix.unwrap().is_drive()
|
||||
{
|
||||
let comps = self.components();
|
||||
if comps.prefix_len() > 0
|
||||
&& comps.prefix_len() == comps.path.len()
|
||||
&& comps.prefix.unwrap().is_drive()
|
||||
{
|
||||
need_sep = false
|
||||
}
|
||||
need_sep = false
|
||||
}
|
||||
|
||||
// absolute `path` replaces `self`
|
||||
if path.is_absolute() || path.prefix().is_some() {
|
||||
self.as_mut_vec().truncate(0);
|
||||
|
||||
// verbatim paths need . and .. removed
|
||||
} else if comps.prefix_verbatim() {
|
||||
let mut buf: Vec<_> = comps.collect();
|
||||
for c in path.components() {
|
||||
match c {
|
||||
Component::RootDir => {
|
||||
buf.truncate(1);
|
||||
buf.push(c);
|
||||
}
|
||||
Component::CurDir => (),
|
||||
Component::ParentDir => {
|
||||
if let Some(Component::Normal(_)) = buf.last() {
|
||||
buf.pop();
|
||||
}
|
||||
}
|
||||
_ => buf.push(c),
|
||||
}
|
||||
}
|
||||
|
||||
let mut res = OsString::new();
|
||||
let mut need_sep = false;
|
||||
|
||||
for c in buf {
|
||||
if need_sep && c != Component::RootDir {
|
||||
res.push(MAIN_SEP_STR);
|
||||
}
|
||||
res.push(c.as_os_str());
|
||||
|
||||
need_sep = match c {
|
||||
Component::RootDir => false,
|
||||
Component::Prefix(prefix) => {
|
||||
!prefix.parsed.is_drive() && prefix.parsed.len() > 0
|
||||
}
|
||||
_ => true,
|
||||
}
|
||||
}
|
||||
|
||||
self.inner = res;
|
||||
return;
|
||||
|
||||
// `path` has a root but no prefix, e.g., `\windows` (Windows only)
|
||||
} else if path.has_root() {
|
||||
let prefix_len = self.components().prefix_remaining();
|
||||
|
|
|
@ -1262,6 +1262,15 @@ pub fn test_push() {
|
|||
tp!("\\\\.\\foo", "..\\bar", "\\\\.\\foo\\..\\bar");
|
||||
|
||||
tp!("\\\\?\\C:", "foo", "\\\\?\\C:\\foo"); // this is a weird one
|
||||
|
||||
tp!(r"\\?\C:\bar", "../foo", r"\\?\C:\foo");
|
||||
tp!(r"\\?\C:\bar", "../../foo", r"\\?\C:\foo");
|
||||
tp!(r"\\?\C:\", "../foo", r"\\?\C:\foo");
|
||||
tp!(r"\\?\C:", r"D:\foo/./", r"D:\foo/./");
|
||||
tp!(r"\\?\C:", r"\\?\D:\foo\.\", r"\\?\D:\foo\.\");
|
||||
tp!(r"\\?\A:\x\y", "/foo", r"\\?\A:\foo");
|
||||
tp!(r"\\?\A:", r"..\foo\.", r"\\?\A:\foo");
|
||||
tp!(r"\\?\A:\x\y", r".\foo\.", r"\\?\A:\x\y\foo");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ use crate::clean;
|
|||
use crate::core::DocContext;
|
||||
use crate::fold::{self, DocFolder};
|
||||
use crate::html::markdown::{find_testable_code, ErrorCodes};
|
||||
use crate::passes::doc_test_lints::{should_have_doc_example, Tests};
|
||||
use crate::passes::check_doc_test_visibility::{should_have_doc_example, Tests};
|
||||
use crate::passes::Pass;
|
||||
use rustc_hir as hir;
|
||||
use rustc_lint::builtin::MISSING_DOCS;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//! This pass is overloaded and runs two different lints.
|
||||
//!
|
||||
//! - MISSING_DOC_CODE_EXAMPLES: this lint is **UNSTABLE** and looks for public items missing doctests
|
||||
//! - MISSING_DOC_CODE_EXAMPLES: this lint is **UNSTABLE** and looks for public items missing doctests.
|
||||
//! - PRIVATE_DOC_TESTS: this lint is **STABLE** and looks for private items with doctests.
|
||||
|
||||
use super::Pass;
|
||||
|
@ -15,23 +15,23 @@ use rustc_middle::lint::LintLevelSource;
|
|||
use rustc_session::lint;
|
||||
use rustc_span::symbol::sym;
|
||||
|
||||
crate const CHECK_PRIVATE_ITEMS_DOC_TESTS: Pass = Pass {
|
||||
name: "check-private-items-doc-tests",
|
||||
run: check_private_items_doc_tests,
|
||||
description: "check private items doc tests",
|
||||
crate const CHECK_DOC_TEST_VISIBILITY: Pass = Pass {
|
||||
name: "check_doc_test_visibility",
|
||||
run: check_doc_test_visibility,
|
||||
description: "run various visibility-related lints on doctests",
|
||||
};
|
||||
|
||||
struct PrivateItemDocTestLinter<'a, 'tcx> {
|
||||
struct DocTestVisibilityLinter<'a, 'tcx> {
|
||||
cx: &'a mut DocContext<'tcx>,
|
||||
}
|
||||
|
||||
crate fn check_private_items_doc_tests(krate: Crate, cx: &mut DocContext<'_>) -> Crate {
|
||||
let mut coll = PrivateItemDocTestLinter { cx };
|
||||
crate fn check_doc_test_visibility(krate: Crate, cx: &mut DocContext<'_>) -> Crate {
|
||||
let mut coll = DocTestVisibilityLinter { cx };
|
||||
|
||||
coll.fold_crate(krate)
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> DocFolder for PrivateItemDocTestLinter<'a, 'tcx> {
|
||||
impl<'a, 'tcx> DocFolder for DocTestVisibilityLinter<'a, 'tcx> {
|
||||
fn fold_item(&mut self, item: Item) -> Option<Item> {
|
||||
let dox = item.attrs.collapsed_doc_value().unwrap_or_else(String::new);
|
||||
|
|
@ -33,8 +33,8 @@ crate use self::propagate_doc_cfg::PROPAGATE_DOC_CFG;
|
|||
crate mod collect_intra_doc_links;
|
||||
crate use self::collect_intra_doc_links::COLLECT_INTRA_DOC_LINKS;
|
||||
|
||||
mod doc_test_lints;
|
||||
crate use self::doc_test_lints::CHECK_PRIVATE_ITEMS_DOC_TESTS;
|
||||
mod check_doc_test_visibility;
|
||||
crate use self::check_doc_test_visibility::CHECK_DOC_TEST_VISIBILITY;
|
||||
|
||||
mod collect_trait_impls;
|
||||
crate use self::collect_trait_impls::COLLECT_TRAIT_IMPLS;
|
||||
|
@ -79,7 +79,7 @@ crate enum Condition {
|
|||
|
||||
/// The full list of passes.
|
||||
crate const PASSES: &[Pass] = &[
|
||||
CHECK_PRIVATE_ITEMS_DOC_TESTS,
|
||||
CHECK_DOC_TEST_VISIBILITY,
|
||||
STRIP_HIDDEN,
|
||||
UNINDENT_COMMENTS,
|
||||
STRIP_PRIVATE,
|
||||
|
@ -97,7 +97,7 @@ crate const PASSES: &[Pass] = &[
|
|||
crate const DEFAULT_PASSES: &[ConditionalPass] = &[
|
||||
ConditionalPass::always(COLLECT_TRAIT_IMPLS),
|
||||
ConditionalPass::always(UNINDENT_COMMENTS),
|
||||
ConditionalPass::always(CHECK_PRIVATE_ITEMS_DOC_TESTS),
|
||||
ConditionalPass::always(CHECK_DOC_TEST_VISIBILITY),
|
||||
ConditionalPass::new(STRIP_HIDDEN, WhenNotDocumentHidden),
|
||||
ConditionalPass::new(STRIP_PRIVATE, WhenNotDocumentPrivate),
|
||||
ConditionalPass::new(STRIP_PRIV_IMPORTS, WhenDocumentPrivate),
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 522c3e3d9c097b53ede7682cc28544b461597b20
|
||||
Subproject commit a7348ae0df3c71581dbe3d355fc0fb6ce6332dd0
|
|
@ -15,7 +15,7 @@ note: required because of the requirements on the impl of `Grault` for `(T,)`
|
|||
|
|
||||
LL | impl<T: Grault> Grault for (T,)
|
||||
| ^^^^^^ ^^^^
|
||||
= note: 1 redundant requirements hidden
|
||||
= note: 1 redundant requirement hidden
|
||||
= note: required because of the requirements on the impl of `Grault` for `(T,)`
|
||||
|
||||
error[E0275]: overflow evaluating the requirement `<(T,) as Grault>::A == _`
|
||||
|
@ -29,7 +29,7 @@ note: required because of the requirements on the impl of `Grault` for `(T,)`
|
|||
|
|
||||
LL | impl<T: Grault> Grault for (T,)
|
||||
| ^^^^^^ ^^^^
|
||||
= note: 1 redundant requirements hidden
|
||||
= note: 1 redundant requirement hidden
|
||||
= note: required because of the requirements on the impl of `Grault` for `(T,)`
|
||||
|
||||
error[E0275]: overflow evaluating the requirement `<(T,) as Grault>::A == _`
|
||||
|
@ -43,7 +43,7 @@ note: required because of the requirements on the impl of `Grault` for `(T,)`
|
|||
|
|
||||
LL | impl<T: Grault> Grault for (T,)
|
||||
| ^^^^^^ ^^^^
|
||||
= note: 1 redundant requirements hidden
|
||||
= note: 1 redundant requirement hidden
|
||||
= note: required because of the requirements on the impl of `Grault` for `(T,)`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
#![feature(auto_traits)]
|
||||
|
||||
// run-rustfix
|
||||
|
||||
auto trait Generic {}
|
||||
//~^ auto traits cannot have generic parameters [E0567]
|
||||
auto trait Bound {}
|
||||
//~^ auto traits cannot have super traits or lifetime bounds [E0568]
|
||||
auto trait LifetimeBound {}
|
||||
//~^ auto traits cannot have super traits or lifetime bounds [E0568]
|
||||
auto trait MyTrait { }
|
||||
//~^ auto traits cannot have associated items [E0380]
|
||||
fn main() {}
|
|
@ -1,9 +1,13 @@
|
|||
#![feature(auto_traits)]
|
||||
|
||||
// run-rustfix
|
||||
|
||||
auto trait Generic<T> {}
|
||||
//~^ auto traits cannot have generic parameters [E0567]
|
||||
auto trait Bound : Copy {}
|
||||
//~^ auto traits cannot have super traits [E0568]
|
||||
//~^ auto traits cannot have super traits or lifetime bounds [E0568]
|
||||
auto trait LifetimeBound : 'static {}
|
||||
//~^ auto traits cannot have super traits or lifetime bounds [E0568]
|
||||
auto trait MyTrait { fn foo() {} }
|
||||
//~^ auto traits cannot have methods or associated items [E0380]
|
||||
//~^ auto traits cannot have associated items [E0380]
|
||||
fn main() {}
|
||||
|
|
|
@ -1,28 +1,37 @@
|
|||
error[E0567]: auto traits cannot have generic parameters
|
||||
--> $DIR/auto-trait-validation.rs:3:19
|
||||
--> $DIR/auto-trait-validation.rs:5:19
|
||||
|
|
||||
LL | auto trait Generic<T> {}
|
||||
| -------^^^ help: remove the parameters
|
||||
| |
|
||||
| auto trait cannot have generic parameters
|
||||
|
||||
error[E0568]: auto traits cannot have super traits
|
||||
--> $DIR/auto-trait-validation.rs:5:20
|
||||
error[E0568]: auto traits cannot have super traits or lifetime bounds
|
||||
--> $DIR/auto-trait-validation.rs:7:17
|
||||
|
|
||||
LL | auto trait Bound : Copy {}
|
||||
| ----- ^^^^ help: remove the super traits
|
||||
| -----^^^^^^^ help: remove the super traits or lifetime bounds
|
||||
| |
|
||||
| auto trait cannot have super traits
|
||||
| auto trait cannot have super traits or lifetime bounds
|
||||
|
||||
error[E0380]: auto traits cannot have methods or associated items
|
||||
--> $DIR/auto-trait-validation.rs:7:25
|
||||
error[E0568]: auto traits cannot have super traits or lifetime bounds
|
||||
--> $DIR/auto-trait-validation.rs:9:25
|
||||
|
|
||||
LL | auto trait LifetimeBound : 'static {}
|
||||
| -------------^^^^^^^^^^ help: remove the super traits or lifetime bounds
|
||||
| |
|
||||
| auto trait cannot have super traits or lifetime bounds
|
||||
|
||||
error[E0380]: auto traits cannot have associated items
|
||||
--> $DIR/auto-trait-validation.rs:11:25
|
||||
|
|
||||
LL | auto trait MyTrait { fn foo() {} }
|
||||
| ------- ^^^
|
||||
| |
|
||||
| auto trait cannot have items
|
||||
| ------- ---^^^-----
|
||||
| | |
|
||||
| | help: remove these associated items
|
||||
| auto trait cannot have associated items
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0380, E0567, E0568.
|
||||
For more information about an error, try `rustc --explain E0380`.
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
error[E0380]: auto traits cannot have methods or associated items
|
||||
error[E0380]: auto traits cannot have associated items
|
||||
--> $DIR/issue-23080-2.rs:5:10
|
||||
|
|
||||
LL | unsafe auto trait Trait {
|
||||
| ----- auto trait cannot have items
|
||||
| ----- auto trait cannot have associated items
|
||||
LL | type Output;
|
||||
| ^^^^^^
|
||||
| -----^^^^^^- help: remove these associated items
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
error[E0380]: auto traits cannot have methods or associated items
|
||||
error[E0380]: auto traits cannot have associated items
|
||||
--> $DIR/issue-23080.rs:5:8
|
||||
|
|
||||
LL | unsafe auto trait Trait {
|
||||
| ----- auto trait cannot have items
|
||||
LL | fn method(&self) {
|
||||
| ^^^^^^
|
||||
LL | unsafe auto trait Trait {
|
||||
| ----- auto trait cannot have associated items
|
||||
LL | fn method(&self) {
|
||||
| _____- ^^^^^^
|
||||
LL | | println!("Hello");
|
||||
LL | | }
|
||||
| |_____- help: remove these associated items
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
// Regression test for issue #84075.
|
||||
|
||||
#![feature(auto_traits)]
|
||||
|
||||
auto trait Magic where Self: Copy {} //~ ERROR E0568
|
||||
impl<T: Magic> Magic for T {}
|
||||
|
||||
fn copy<T: Magic>(x: T) -> (T, T) { (x, x) }
|
||||
|
||||
#[derive(Debug)]
|
||||
struct NoClone;
|
||||
|
||||
fn main() {
|
||||
let (a, b) = copy(NoClone);
|
||||
println!("{:?} {:?}", a, b);
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
error[E0568]: auto traits cannot have super traits or lifetime bounds
|
||||
--> $DIR/issue-84075.rs:5:18
|
||||
|
|
||||
LL | auto trait Magic where Self: Copy {}
|
||||
| ----- ^^^^^^^^^^^^^^^^ help: remove the super traits or lifetime bounds
|
||||
| |
|
||||
| auto trait cannot have super traits or lifetime bounds
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0568`.
|
|
@ -2,6 +2,7 @@
|
|||
#![feature(negative_impls)]
|
||||
|
||||
auto trait Magic : Sized where Option<Self> : Magic {} //~ ERROR E0568
|
||||
//~^ ERROR E0568
|
||||
impl<T:Magic> Magic for T {}
|
||||
|
||||
fn copy<T: Magic>(x: T) -> (T, T) { (x, x) }
|
||||
|
|
|
@ -1,11 +1,19 @@
|
|||
error[E0568]: auto traits cannot have super traits
|
||||
--> $DIR/typeck-auto-trait-no-supertraits-2.rs:4:20
|
||||
error[E0568]: auto traits cannot have super traits or lifetime bounds
|
||||
--> $DIR/typeck-auto-trait-no-supertraits-2.rs:4:17
|
||||
|
|
||||
LL | auto trait Magic : Sized where Option<Self> : Magic {}
|
||||
| ----- ^^^^^ help: remove the super traits
|
||||
| -----^^^^^^^^ help: remove the super traits or lifetime bounds
|
||||
| |
|
||||
| auto trait cannot have super traits
|
||||
| auto trait cannot have super traits or lifetime bounds
|
||||
|
||||
error: aborting due to previous error
|
||||
error[E0568]: auto traits cannot have super traits or lifetime bounds
|
||||
--> $DIR/typeck-auto-trait-no-supertraits-2.rs:4:26
|
||||
|
|
||||
LL | auto trait Magic : Sized where Option<Self> : Magic {}
|
||||
| ----- ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the super traits or lifetime bounds
|
||||
| |
|
||||
| auto trait cannot have super traits or lifetime bounds
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0568`.
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
error[E0568]: auto traits cannot have super traits
|
||||
--> $DIR/typeck-auto-trait-no-supertraits.rs:28:19
|
||||
error[E0568]: auto traits cannot have super traits or lifetime bounds
|
||||
--> $DIR/typeck-auto-trait-no-supertraits.rs:28:17
|
||||
|
|
||||
LL | auto trait Magic: Copy {}
|
||||
| ----- ^^^^ help: remove the super traits
|
||||
| -----^^^^^^ help: remove the super traits or lifetime bounds
|
||||
| |
|
||||
| auto trait cannot have super traits
|
||||
| auto trait cannot have super traits or lifetime bounds
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
// check-pass
|
||||
#![feature(try_reserve)]
|
||||
|
||||
fn main() {
|
||||
let mut schema_all: (Vec<String>, Vec<String>) = (vec![], vec![]);
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
fn main() {
|
||||
let v = Vec::new();
|
||||
v.try_reserve(10); //~ ERROR: use of unstable library feature 'try_reserve'
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
error[E0658]: use of unstable library feature 'try_reserve': new API
|
||||
--> $DIR/feature-gate-try_reserve.rs:3:7
|
||||
|
|
||||
LL | v.try_reserve(10);
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #48043 <https://github.com/rust-lang/rust/issues/48043> for more information
|
||||
= help: add `#![feature(try_reserve)]` to the crate attributes to enable
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
|
@ -0,0 +1,32 @@
|
|||
trait BufferMut {}
|
||||
struct Ctx<D>(D);
|
||||
|
||||
trait BufferUdpStateContext<B> {}
|
||||
impl<B: BufferMut, C> BufferUdpStateContext<B> for C {}
|
||||
|
||||
trait StackContext
|
||||
where
|
||||
Ctx<()>: for<'a> BufferUdpStateContext<&'a ()>,
|
||||
{
|
||||
type Dispatcher;
|
||||
}
|
||||
|
||||
trait TimerContext {
|
||||
type Handler;
|
||||
}
|
||||
impl<C> TimerContext for C
|
||||
where
|
||||
C: StackContext,
|
||||
//~^ ERROR: is not satisfied [E0277]
|
||||
{
|
||||
type Handler = Ctx<C::Dispatcher>;
|
||||
//~^ ERROR: is not satisfied [E0277]
|
||||
}
|
||||
|
||||
struct EthernetWorker<C>(C)
|
||||
where
|
||||
Ctx<()>: for<'a> BufferUdpStateContext<&'a ()>;
|
||||
impl<C> EthernetWorker<C> {}
|
||||
//~^ ERROR: is not satisfied [E0277]
|
||||
|
||||
fn main() {}
|
|
@ -0,0 +1,63 @@
|
|||
error[E0277]: the trait bound `for<'a> &'a (): BufferMut` is not satisfied
|
||||
--> $DIR/issue-89118.rs:19:8
|
||||
|
|
||||
LL | C: StackContext,
|
||||
| ^^^^^^^^^^^^ the trait `for<'a> BufferMut` is not implemented for `&'a ()`
|
||||
|
|
||||
note: required because of the requirements on the impl of `for<'a> BufferUdpStateContext<&'a ()>` for `Ctx<()>`
|
||||
--> $DIR/issue-89118.rs:5:23
|
||||
|
|
||||
LL | impl<B: BufferMut, C> BufferUdpStateContext<B> for C {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ ^
|
||||
note: required by a bound in `StackContext`
|
||||
--> $DIR/issue-89118.rs:9:14
|
||||
|
|
||||
LL | trait StackContext
|
||||
| ------------ required by a bound in this
|
||||
LL | where
|
||||
LL | Ctx<()>: for<'a> BufferUdpStateContext<&'a ()>,
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `StackContext`
|
||||
|
||||
error[E0277]: the trait bound `for<'a> &'a (): BufferMut` is not satisfied
|
||||
--> $DIR/issue-89118.rs:22:20
|
||||
|
|
||||
LL | type Handler = Ctx<C::Dispatcher>;
|
||||
| ^^^^^^^^^^^^^^^^^^ the trait `for<'a> BufferMut` is not implemented for `&'a ()`
|
||||
|
|
||||
note: required because of the requirements on the impl of `for<'a> BufferUdpStateContext<&'a ()>` for `Ctx<()>`
|
||||
--> $DIR/issue-89118.rs:5:23
|
||||
|
|
||||
LL | impl<B: BufferMut, C> BufferUdpStateContext<B> for C {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ ^
|
||||
note: required by a bound in `StackContext`
|
||||
--> $DIR/issue-89118.rs:9:14
|
||||
|
|
||||
LL | trait StackContext
|
||||
| ------------ required by a bound in this
|
||||
LL | where
|
||||
LL | Ctx<()>: for<'a> BufferUdpStateContext<&'a ()>,
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `StackContext`
|
||||
|
||||
error[E0277]: the trait bound `for<'a> &'a (): BufferMut` is not satisfied
|
||||
--> $DIR/issue-89118.rs:29:9
|
||||
|
|
||||
LL | impl<C> EthernetWorker<C> {}
|
||||
| ^^^^^^^^^^^^^^^^^ the trait `for<'a> BufferMut` is not implemented for `&'a ()`
|
||||
|
|
||||
note: required because of the requirements on the impl of `for<'a> BufferUdpStateContext<&'a ()>` for `Ctx<()>`
|
||||
--> $DIR/issue-89118.rs:5:23
|
||||
|
|
||||
LL | impl<B: BufferMut, C> BufferUdpStateContext<B> for C {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ ^
|
||||
note: required by a bound in `EthernetWorker`
|
||||
--> $DIR/issue-89118.rs:28:14
|
||||
|
|
||||
LL | struct EthernetWorker<C>(C)
|
||||
| -------------- required by a bound in this
|
||||
LL | where
|
||||
LL | Ctx<()>: for<'a> BufferUdpStateContext<&'a ()>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `EthernetWorker`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
|
@ -0,0 +1,20 @@
|
|||
// Regression test for #89469, where an extra non_snake_case warning was
|
||||
// reported for a shorthand field binding.
|
||||
|
||||
// check-pass
|
||||
#![deny(non_snake_case)]
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
struct Entry {
|
||||
A: u16,
|
||||
a: u16
|
||||
}
|
||||
|
||||
fn foo() -> Entry {todo!()}
|
||||
|
||||
pub fn f() {
|
||||
let Entry { A, a } = foo();
|
||||
let _ = (A, a);
|
||||
}
|
||||
|
||||
fn main() {}
|
|
@ -0,0 +1,16 @@
|
|||
// Regression test for issue #89396: Try to recover from a
|
||||
// `=>` -> `=` or `->` typo in a match arm.
|
||||
|
||||
// run-rustfix
|
||||
|
||||
fn main() {
|
||||
let opt = Some(42);
|
||||
let _ = match opt {
|
||||
Some(_) => true,
|
||||
//~^ ERROR: expected one of
|
||||
//~| HELP: try using a fat arrow here
|
||||
None => false,
|
||||
//~^ ERROR: expected one of
|
||||
//~| HELP: try using a fat arrow here
|
||||
};
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
// Regression test for issue #89396: Try to recover from a
|
||||
// `=>` -> `=` or `->` typo in a match arm.
|
||||
|
||||
// run-rustfix
|
||||
|
||||
fn main() {
|
||||
let opt = Some(42);
|
||||
let _ = match opt {
|
||||
Some(_) = true,
|
||||
//~^ ERROR: expected one of
|
||||
//~| HELP: try using a fat arrow here
|
||||
None -> false,
|
||||
//~^ ERROR: expected one of
|
||||
//~| HELP: try using a fat arrow here
|
||||
};
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
error: expected one of `=>`, `if`, or `|`, found `=`
|
||||
--> $DIR/issue-89396.rs:9:17
|
||||
|
|
||||
LL | Some(_) = true,
|
||||
| ^
|
||||
| |
|
||||
| expected one of `=>`, `if`, or `|`
|
||||
| help: try using a fat arrow here: `=>`
|
||||
|
||||
error: expected one of `=>`, `@`, `if`, or `|`, found `->`
|
||||
--> $DIR/issue-89396.rs:12:14
|
||||
|
|
||||
LL | None -> false,
|
||||
| ^^
|
||||
| |
|
||||
| expected one of `=>`, `@`, `if`, or `|`
|
||||
| help: try using a fat arrow here: `=>`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
trait Zero {
|
||||
const ZERO: Self;
|
||||
}
|
||||
|
||||
impl Zero for String {
|
||||
const ZERO: Self = String::new();
|
||||
}
|
||||
|
||||
fn foo() {
|
||||
match String::new() {
|
||||
Zero::ZERO ..= Zero::ZERO => {},
|
||||
//~^ ERROR only `char` and numeric types are allowed in range patterns
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
|
||||
fn bar() {
|
||||
match Zero::ZERO {
|
||||
Zero::ZERO ..= Zero::ZERO => {},
|
||||
//~^ ERROR type annotations needed [E0282]
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
foo();
|
||||
bar();
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
error[E0029]: only `char` and numeric types are allowed in range patterns
|
||||
--> $DIR/issue-88074-pat-range-type-inference-err.rs:11:9
|
||||
|
|
||||
LL | Zero::ZERO ..= Zero::ZERO => {},
|
||||
| ----------^^^^^----------
|
||||
| | |
|
||||
| | this is of type `String` but it should be `char` or numeric
|
||||
| this is of type `String` but it should be `char` or numeric
|
||||
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/issue-88074-pat-range-type-inference-err.rs:19:9
|
||||
|
|
||||
LL | Zero::ZERO ..= Zero::ZERO => {},
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type
|
||||
|
|
||||
= note: type must be known at this point
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0029, E0282.
|
||||
For more information about an error, try `rustc --explain E0029`.
|
|
@ -0,0 +1,16 @@
|
|||
// check-pass
|
||||
|
||||
trait Zero {
|
||||
const ZERO: Self;
|
||||
}
|
||||
|
||||
impl Zero for i32 {
|
||||
const ZERO: Self = 0;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
match 1 {
|
||||
Zero::ZERO ..= 1 => {},
|
||||
_ => {},
|
||||
}
|
||||
}
|
|
@ -19,7 +19,6 @@ enum_number!(Change {
|
|||
Neg = -1,
|
||||
Arith = 1 + 1, //~ ERROR arbitrary expressions aren't allowed in patterns
|
||||
//~| ERROR arbitrary expressions aren't allowed in patterns
|
||||
//~| ERROR only `char` and numeric types are allowed in range patterns
|
||||
});
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -10,15 +10,5 @@ error: arbitrary expressions aren't allowed in patterns
|
|||
LL | Arith = 1 + 1,
|
||||
| ^^^^^
|
||||
|
||||
error[E0029]: only `char` and numeric types are allowed in range patterns
|
||||
--> $DIR/patkind-litrange-no-expr.rs:20:13
|
||||
|
|
||||
LL | $( $value ..= 42 => Some($name::$variant), )* // PatKind::Range
|
||||
| -- this is of type `{integer}`
|
||||
...
|
||||
LL | Arith = 1 + 1,
|
||||
| ^^^^^ this is of type `_` but it should be `char` or numeric
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0029`.
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
// Check that supertraits cannot be used to work around min_specialization
|
||||
// limitations.
|
||||
|
||||
#![feature(min_specialization)]
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
trait HasMethod {
|
||||
fn method(&self);
|
||||
}
|
||||
|
||||
#[rustc_unsafe_specialization_marker]
|
||||
trait Marker: HasMethod {}
|
||||
|
||||
trait Spec {
|
||||
fn spec_me(&self);
|
||||
}
|
||||
|
||||
impl<T> Spec for T {
|
||||
default fn spec_me(&self) {}
|
||||
}
|
||||
|
||||
impl<T: Marker> Spec for T {
|
||||
//~^ ERROR cannot specialize on trait `HasMethod`
|
||||
fn spec_me(&self) {
|
||||
self.method();
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
|
@ -0,0 +1,13 @@
|
|||
error: cannot specialize on trait `HasMethod`
|
||||
--> $DIR/spec-marker-supertraits.rs:22:1
|
||||
|
|
||||
LL | / impl<T: Marker> Spec for T {
|
||||
LL | |
|
||||
LL | | fn spec_me(&self) {
|
||||
LL | | self.method();
|
||||
LL | | }
|
||||
LL | | }
|
||||
| |_^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
error[E0568]: auto traits cannot have super traits
|
||||
--> $DIR/supertrait-auto-trait.rs:8:19
|
||||
error[E0568]: auto traits cannot have super traits or lifetime bounds
|
||||
--> $DIR/supertrait-auto-trait.rs:8:17
|
||||
|
|
||||
LL | auto trait Magic: Copy {}
|
||||
| ----- ^^^^ help: remove the super traits
|
||||
| -----^^^^^^ help: remove the super traits or lifetime bounds
|
||||
| |
|
||||
| auto trait cannot have super traits
|
||||
| auto trait cannot have super traits or lifetime bounds
|
||||
|
||||
error[E0277]: the trait bound `NoClone: Copy` is not satisfied
|
||||
--> $DIR/supertrait-auto-trait.rs:16:23
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 035933186957cf81c488261fb48a98bf523e8006
|
||||
Subproject commit 18667a856596713fc4479f99b96afc7f03aa995c
|
|
@ -1 +1 @@
|
|||
Subproject commit 009e6ceb1ddcd27a9ced3bcb7d0ef823379185a1
|
||||
Subproject commit 4b7675fcc30d3e2c05eafc68a5724db66b58142c
|
Loading…
Reference in New Issue