diff --git a/.gitmodules b/.gitmodules index e22d576279042..c60a0dd2c7c43 100644 --- a/.gitmodules +++ b/.gitmodules @@ -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 diff --git a/Cargo.lock b/Cargo.lock index a4e1ab6c1e4a8..adf14bfddfd7f 100644 --- a/Cargo.lock +++ b/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" diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index 3a65ffe41ae87..db066d7c6a519 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -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, } } diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index dea2a0e2a4399..968e9fa3e2480 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -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], 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_suggestion( + total_span, + "remove these associated items", + String::new(), + Applicability::MachineApplicable, ) - .span_label(ident_span, "auto trait cannot have items") + .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); diff --git a/compiler/rustc_data_structures/src/sso/map.rs b/compiler/rustc_data_structures/src/sso/map.rs index e249886e9bc01..2de05cd4e5679 100644 --- a/compiler/rustc_data_structures/src/sso/map.rs +++ b/compiler/rustc_data_structures/src/sso/map.rs @@ -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) diff --git a/compiler/rustc_data_structures/src/sso/set.rs b/compiler/rustc_data_structures/src/sso/set.rs index 23cff0206c530..29baf4e1ddb66 100644 --- a/compiler/rustc_data_structures/src/sso/set.rs +++ b/compiler/rustc_data_structures/src/sso/set.rs @@ -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 diff --git a/compiler/rustc_lint/src/nonstandard_style.rs b/compiler/rustc_lint/src/nonstandard_style.rs index 03344973bb3e6..bcddc4f3d7643 100644 --- a/compiler/rustc_lint/src/nonstandard_style.rs +++ b/compiler/rustc_lint/src/nonstandard_style.rs @@ -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; } diff --git a/compiler/rustc_macros/src/query.rs b/compiler/rustc_macros/src/query.rs index 7ad36973f46c7..005017185c148 100644 --- a/compiler/rustc_macros/src/query.rs +++ b/compiler/rustc_macros/src/query.rs @@ -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, diff --git a/compiler/rustc_middle/src/dep_graph/dep_node.rs b/compiler/rustc_middle/src/dep_graph/dep_node.rs index e788dd4be85d7..07d42902be5dd 100644 --- a/compiler/rustc_middle/src/dep_graph/dep_node.rs +++ b/compiler/rustc_middle/src/dep_graph/dep_node.rs @@ -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)] diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index 1f2bfa5e7d904..594ac899f158f 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -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"] diff --git a/compiler/rustc_middle/src/ty/query.rs b/compiler/rustc_middle/src/ty/query.rs index 154b26464a804..e5fd38252da53 100644 --- a/compiler/rustc_middle/src/ty/query.rs +++ b/compiler/rustc_middle/src/ty/query.rs @@ -111,11 +111,11 @@ macro_rules! query_storage { ([][$K:ty, $V:ty]) => { >::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)*]) }; } diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index c5417ea23f219..79f46be73f6c2 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -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| { diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index bb686b5ef3f3a..818b798ab55e7 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -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)*]) }; } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index b7f1f64cbfdbc..cd678b9644622 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -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(), diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index be438f02a9710..b31d6d68b0a24 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -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, diff --git a/compiler/rustc_typeck/src/check/pat.rs b/compiler/rustc_typeck/src/check/pat.rs index 0650291bacb10..98bec3f6eac51 100644 --- a/compiler/rustc_typeck/src/check/pat.rs +++ b/compiler/rustc_typeck/src/check/pat.rs @@ -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); + + if let (Some((true, ..)), _) | (_, Some((true, ..))) = (lhs, rhs) { + return self.tcx.ty_error(); + } - common_type + // 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); } }; diff --git a/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs b/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs index 8ecd6034ad695..f4bb5761c19bd 100644 --- a/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs +++ b/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs @@ -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 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) } } diff --git a/library/alloc/src/collections/mod.rs b/library/alloc/src/collections/mod.rs index 4e31df8b4b8c2..77d28bdfe6475 100644 --- a/library/alloc/src/collections/mod.rs +++ b/library/alloc/src/collections/mod.rs @@ -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 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, diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs index 007548ad1ab58..f4de2b2ebe5dc 100644 --- a/library/alloc/src/collections/vec_deque/mod.rs +++ b/library/alloc/src/collections/vec_deque/mod.rs @@ -711,7 +711,6 @@ impl VecDeque { /// # Examples /// /// ``` - /// #![feature(try_reserve)] /// use std::collections::TryReserveError; /// use std::collections::VecDeque; /// @@ -730,7 +729,7 @@ impl VecDeque { /// } /// # 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 VecDeque { /// # Examples /// /// ``` - /// #![feature(try_reserve)] /// use std::collections::TryReserveError; /// use std::collections::VecDeque; /// @@ -768,7 +766,7 @@ impl VecDeque { /// } /// # 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; diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index 92a17cc75ef8b..d88b8e398985a 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -1009,7 +1009,6 @@ impl String { /// # Examples /// /// ``` - /// #![feature(try_reserve)] /// use std::collections::TryReserveError; /// /// fn process_data(data: &str) -> Result { @@ -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 { @@ -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) } diff --git a/library/alloc/src/vec/into_iter.rs b/library/alloc/src/vec/into_iter.rs index 8a2d254a83451..18e191f2b59a2 100644 --- a/library/alloc/src/vec/into_iter.rs +++ b/library/alloc/src/vec/into_iter.rs @@ -266,14 +266,21 @@ unsafe impl TrustedLen for IntoIter {} #[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 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 TrustedRandomAccessNoCoerce for IntoIter where - T: Copy, + T: NonDrop, { const MAY_HAVE_SIDE_EFFECT: bool = false; } diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 320347e58e19f..4f18a054a0d98 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -849,7 +849,6 @@ impl Vec { /// # Examples /// /// ``` - /// #![feature(try_reserve)] /// use std::collections::TryReserveError; /// /// fn process_data(data: &[u32]) -> Result, TryReserveError> { @@ -867,7 +866,7 @@ impl Vec { /// } /// # 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 Vec { /// # Examples /// /// ``` - /// #![feature(try_reserve)] /// use std::collections::TryReserveError; /// /// fn process_data(data: &[u32]) -> Result, TryReserveError> { @@ -910,7 +908,7 @@ impl Vec { /// } /// # 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) } diff --git a/library/alloc/src/vec/source_iter_marker.rs b/library/alloc/src/vec/source_iter_marker.rs index e05788d99c0df..6e78534cf5b10 100644 --- a/library/alloc/src/vec/source_iter_marker.rs +++ b/library/alloc/src/vec/source_iter_marker.rs @@ -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 {} +pub(super) trait InPlaceIterableMarker {} -// The std-internal SourceIter/InPlaceIterable traits are only implemented by chains of -// Adapter>> (all owned by core/std). Additional bounds -// on the adapter implementations (beyond `impl Trait for Adapter`) 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 SourceIterMarker for T where T: SourceIter + InPlaceIterable {} +impl InPlaceIterableMarker for T where T: InPlaceIterable {} impl SpecFromIter for Vec where - I: Iterator + SourceIterMarker, + I: Iterator + SourceIter + InPlaceIterableMarker, { default fn from_iter(mut iterator: I) -> Self { // Additional requirements which cannot expressed via trait bounds. We rely on const eval diff --git a/library/alloc/tests/lib.rs b/library/alloc/tests/lib.rs index c6159539b48d0..8c57c804ad2dc 100644 --- a/library/alloc/tests/lib.rs +++ b/library/alloc/tests/lib.rs @@ -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)] diff --git a/library/core/src/iter/adapters/enumerate.rs b/library/core/src/iter/adapters/enumerate.rs index c877b45095ace..84e4618844a61 100644 --- a/library/core/src/iter/adapters/enumerate.rs +++ b/library/core/src/iter/adapters/enumerate.rs @@ -249,14 +249,14 @@ impl FusedIterator for Enumerate where I: FusedIterator {} unsafe impl TrustedLen for Enumerate where I: TrustedLen {} #[unstable(issue = "none", feature = "inplace_iteration")] -unsafe impl SourceIter for Enumerate +unsafe impl SourceIter for Enumerate where - I: SourceIter, + 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) } } diff --git a/library/core/src/iter/adapters/filter.rs b/library/core/src/iter/adapters/filter.rs index d5f19f127470e..a0afaa326ad63 100644 --- a/library/core/src/iter/adapters/filter.rs +++ b/library/core/src/iter/adapters/filter.rs @@ -135,15 +135,14 @@ where impl FusedIterator for Filter where P: FnMut(&I::Item) -> bool {} #[unstable(issue = "none", feature = "inplace_iteration")] -unsafe impl SourceIter for Filter +unsafe impl SourceIter for Filter where - P: FnMut(&I::Item) -> bool, - I: SourceIter, + 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) } } diff --git a/library/core/src/iter/adapters/filter_map.rs b/library/core/src/iter/adapters/filter_map.rs index 01b7be9d52daf..e0d665c9e12ba 100644 --- a/library/core/src/iter/adapters/filter_map.rs +++ b/library/core/src/iter/adapters/filter_map.rs @@ -129,15 +129,14 @@ where impl FusedIterator for FilterMap where F: FnMut(I::Item) -> Option {} #[unstable(issue = "none", feature = "inplace_iteration")] -unsafe impl SourceIter for FilterMap +unsafe impl SourceIter for FilterMap where - F: FnMut(I::Item) -> Option, - I: SourceIter, + 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) } } diff --git a/library/core/src/iter/adapters/inspect.rs b/library/core/src/iter/adapters/inspect.rs index 36835d12e5685..19839fdfe5bc3 100644 --- a/library/core/src/iter/adapters/inspect.rs +++ b/library/core/src/iter/adapters/inspect.rs @@ -149,15 +149,14 @@ where impl FusedIterator for Inspect where F: FnMut(&I::Item) {} #[unstable(issue = "none", feature = "inplace_iteration")] -unsafe impl SourceIter for Inspect +unsafe impl SourceIter for Inspect where - F: FnMut(&I::Item), - I: SourceIter, + 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) } } diff --git a/library/core/src/iter/adapters/map.rs b/library/core/src/iter/adapters/map.rs index 763e253e75a51..449650a22f435 100644 --- a/library/core/src/iter/adapters/map.rs +++ b/library/core/src/iter/adapters/map.rs @@ -201,15 +201,14 @@ where } #[unstable(issue = "none", feature = "inplace_iteration")] -unsafe impl SourceIter for Map +unsafe impl SourceIter for Map where - F: FnMut(I::Item) -> B, - I: SourceIter, + 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) } } diff --git a/library/core/src/iter/adapters/map_while.rs b/library/core/src/iter/adapters/map_while.rs index 793b05fcf9529..1e8d6bf3e00e1 100644 --- a/library/core/src/iter/adapters/map_while.rs +++ b/library/core/src/iter/adapters/map_while.rs @@ -80,15 +80,14 @@ where } #[unstable(issue = "none", feature = "inplace_iteration")] -unsafe impl SourceIter for MapWhile +unsafe impl SourceIter for MapWhile where - P: FnMut(I::Item) -> Option, - I: SourceIter, + 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) } } diff --git a/library/core/src/iter/adapters/mod.rs b/library/core/src/iter/adapters/mod.rs index 48e7dcfa7d9a3..1e1ce866ff3f2 100644 --- a/library/core/src/iter/adapters/mod.rs +++ b/library/core/src/iter/adapters/mod.rs @@ -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 SourceIter for ResultShunt<'_, I, E> +unsafe impl SourceIter for ResultShunt<'_, I, E> where - I: SourceIter, + 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) } } diff --git a/library/core/src/iter/adapters/peekable.rs b/library/core/src/iter/adapters/peekable.rs index 91fa1a9ad351c..20aca323bab79 100644 --- a/library/core/src/iter/adapters/peekable.rs +++ b/library/core/src/iter/adapters/peekable.rs @@ -321,14 +321,14 @@ impl Peekable { unsafe impl TrustedLen for Peekable where I: TrustedLen {} #[unstable(issue = "none", feature = "inplace_iteration")] -unsafe impl SourceIter for Peekable +unsafe impl SourceIter for Peekable where - I: SourceIter, + 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) } } diff --git a/library/core/src/iter/adapters/scan.rs b/library/core/src/iter/adapters/scan.rs index 96705b01f661f..80bfd2231241b 100644 --- a/library/core/src/iter/adapters/scan.rs +++ b/library/core/src/iter/adapters/scan.rs @@ -90,15 +90,14 @@ where } #[unstable(issue = "none", feature = "inplace_iteration")] -unsafe impl SourceIter for Scan +unsafe impl SourceIter for Scan where - I: SourceIter, - F: FnMut(&mut St, I::Item) -> Option, + 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) } } diff --git a/library/core/src/iter/adapters/skip.rs b/library/core/src/iter/adapters/skip.rs index 9b89ca5a9479d..565fc224f53ca 100644 --- a/library/core/src/iter/adapters/skip.rs +++ b/library/core/src/iter/adapters/skip.rs @@ -222,14 +222,14 @@ where impl FusedIterator for Skip where I: FusedIterator {} #[unstable(issue = "none", feature = "inplace_iteration")] -unsafe impl SourceIter for Skip +unsafe impl SourceIter for Skip where - I: SourceIter, + 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) } } diff --git a/library/core/src/iter/adapters/skip_while.rs b/library/core/src/iter/adapters/skip_while.rs index 93e29edc8df39..f29661779c056 100644 --- a/library/core/src/iter/adapters/skip_while.rs +++ b/library/core/src/iter/adapters/skip_while.rs @@ -105,15 +105,14 @@ where } #[unstable(issue = "none", feature = "inplace_iteration")] -unsafe impl SourceIter for SkipWhile +unsafe impl SourceIter for SkipWhile where - P: FnMut(&I::Item) -> bool, - I: SourceIter, + 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) } } diff --git a/library/core/src/iter/adapters/take.rs b/library/core/src/iter/adapters/take.rs index d0d0128c82b84..81f6c294fac13 100644 --- a/library/core/src/iter/adapters/take.rs +++ b/library/core/src/iter/adapters/take.rs @@ -130,14 +130,14 @@ where } #[unstable(issue = "none", feature = "inplace_iteration")] -unsafe impl SourceIter for Take +unsafe impl SourceIter for Take where - I: SourceIter, + 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) } } diff --git a/library/core/src/iter/adapters/take_while.rs b/library/core/src/iter/adapters/take_while.rs index 93457d20f7c23..ded216da952a3 100644 --- a/library/core/src/iter/adapters/take_while.rs +++ b/library/core/src/iter/adapters/take_while.rs @@ -118,15 +118,14 @@ where } #[unstable(issue = "none", feature = "inplace_iteration")] -unsafe impl SourceIter for TakeWhile +unsafe impl SourceIter for TakeWhile where - P: FnMut(&I::Item) -> bool, - I: SourceIter, + 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) } } diff --git a/library/core/src/iter/adapters/zip.rs b/library/core/src/iter/adapters/zip.rs index 17697fa0e045a..2b7287a413376 100644 --- a/library/core/src/iter/adapters/zip.rs +++ b/library/core/src/iter/adapters/zip.rs @@ -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 SourceIter for Zip +unsafe impl SourceIter for Zip where - A: SourceIter, - 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) } } diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index 526e0c371882c..f1dcdf2c1aa04 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -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 diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index 8ce8266263091..7ef8ea23b5028 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -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::() == 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 diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs index 2de16ce3f86c7..528bb1bf6e9f9 100644 --- a/library/std/src/collections/hash/map.rs +++ b/library/std/src/collections/hash/map.rs @@ -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) } diff --git a/library/std/src/collections/hash/set.rs b/library/std/src/collections/hash/set.rs index 2613fbce15687..dcfe322095082 100644 --- a/library/std/src/collections/hash/set.rs +++ b/library/std/src/collections/hash/set.rs @@ -423,13 +423,12 @@ where /// # Examples /// /// ``` - /// #![feature(try_reserve)] /// use std::collections::HashSet; /// let mut set: HashSet = 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) } diff --git a/library/std/src/collections/mod.rs b/library/std/src/collections/mod.rs index 6ca0525cdbe32..a19c3431989c0 100644 --- a/library/std/src/collections/mod.rs +++ b/library/std/src/collections/mod.rs @@ -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", diff --git a/library/std/src/error.rs b/library/std/src/error.rs index cc4ea27e57e8d..6ae0bc47a9462 100644 --- a/library/std/src/error.rs +++ b/library/std/src/error.rs @@ -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")] diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index b33a3c5d22fe1..0ba4e85886caa 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -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)] diff --git a/library/std/src/path.rs b/library/std/src/path.rs index 9d5778ed48cfe..a45ecf6ea8c63 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -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(); diff --git a/library/std/src/path/tests.rs b/library/std/src/path/tests.rs index ce23cf6cd21b9..3973a6829d3d3 100644 --- a/library/std/src/path/tests.rs +++ b/library/std/src/path/tests.rs @@ -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"); } } diff --git a/src/librustdoc/passes/calculate_doc_coverage.rs b/src/librustdoc/passes/calculate_doc_coverage.rs index 721af3313d27f..5e3bd41b85c7e 100644 --- a/src/librustdoc/passes/calculate_doc_coverage.rs +++ b/src/librustdoc/passes/calculate_doc_coverage.rs @@ -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; diff --git a/src/librustdoc/passes/doc_test_lints.rs b/src/librustdoc/passes/check_doc_test_visibility.rs similarity index 90% rename from src/librustdoc/passes/doc_test_lints.rs rename to src/librustdoc/passes/check_doc_test_visibility.rs index 279d0dbda82ee..1f7d6054233dd 100644 --- a/src/librustdoc/passes/doc_test_lints.rs +++ b/src/librustdoc/passes/check_doc_test_visibility.rs @@ -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 { let dox = item.attrs.collapsed_doc_value().unwrap_or_else(String::new); diff --git a/src/librustdoc/passes/mod.rs b/src/librustdoc/passes/mod.rs index 0e86fe45640f8..99ac87db4ff3f 100644 --- a/src/librustdoc/passes/mod.rs +++ b/src/librustdoc/passes/mod.rs @@ -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), diff --git a/src/llvm-project b/src/llvm-project index 522c3e3d9c097..a7348ae0df3c7 160000 --- a/src/llvm-project +++ b/src/llvm-project @@ -1 +1 @@ -Subproject commit 522c3e3d9c097b53ede7682cc28544b461597b20 +Subproject commit a7348ae0df3c71581dbe3d355fc0fb6ce6332dd0 diff --git a/src/test/ui/associated-types/impl-wf-cycle-1.stderr b/src/test/ui/associated-types/impl-wf-cycle-1.stderr index 1d8d2b0149d21..73167d0831104 100644 --- a/src/test/ui/associated-types/impl-wf-cycle-1.stderr +++ b/src/test/ui/associated-types/impl-wf-cycle-1.stderr @@ -15,7 +15,7 @@ note: required because of the requirements on the impl of `Grault` for `(T,)` | LL | impl 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 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 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 diff --git a/src/test/ui/auto-traits/auto-trait-validation.fixed b/src/test/ui/auto-traits/auto-trait-validation.fixed new file mode 100644 index 0000000000000..da878ac6222bb --- /dev/null +++ b/src/test/ui/auto-traits/auto-trait-validation.fixed @@ -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() {} diff --git a/src/test/ui/auto-traits/auto-trait-validation.rs b/src/test/ui/auto-traits/auto-trait-validation.rs index a997b044c8ff8..d43055e270bd5 100644 --- a/src/test/ui/auto-traits/auto-trait-validation.rs +++ b/src/test/ui/auto-traits/auto-trait-validation.rs @@ -1,9 +1,13 @@ #![feature(auto_traits)] +// run-rustfix + auto trait Generic {} //~^ 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() {} diff --git a/src/test/ui/auto-traits/auto-trait-validation.stderr b/src/test/ui/auto-traits/auto-trait-validation.stderr index 4040e66c6af77..2c380e5b09a6e 100644 --- a/src/test/ui/auto-traits/auto-trait-validation.stderr +++ b/src/test/ui/auto-traits/auto-trait-validation.stderr @@ -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 {} | -------^^^ 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 MyTrait { fn foo() {} } - | ------- ^^^ +LL | auto trait LifetimeBound : 'static {} + | -------------^^^^^^^^^^ help: remove the super traits or lifetime bounds | | - | auto trait cannot have items + | 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() {} } + | ------- ---^^^----- + | | | + | | 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`. diff --git a/src/test/ui/auto-traits/issue-23080-2.stderr b/src/test/ui/auto-traits/issue-23080-2.stderr index efeceafdd2a7d..267a712f62fa0 100644 --- a/src/test/ui/auto-traits/issue-23080-2.stderr +++ b/src/test/ui/auto-traits/issue-23080-2.stderr @@ -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 diff --git a/src/test/ui/auto-traits/issue-23080.stderr b/src/test/ui/auto-traits/issue-23080.stderr index 73ecb1c362e17..c1b16b2f403d7 100644 --- a/src/test/ui/auto-traits/issue-23080.stderr +++ b/src/test/ui/auto-traits/issue-23080.stderr @@ -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 diff --git a/src/test/ui/auto-traits/issue-84075.rs b/src/test/ui/auto-traits/issue-84075.rs new file mode 100644 index 0000000000000..a6afe24ea4c8b --- /dev/null +++ b/src/test/ui/auto-traits/issue-84075.rs @@ -0,0 +1,16 @@ +// Regression test for issue #84075. + +#![feature(auto_traits)] + +auto trait Magic where Self: Copy {} //~ ERROR E0568 +impl Magic for T {} + +fn copy(x: T) -> (T, T) { (x, x) } + +#[derive(Debug)] +struct NoClone; + +fn main() { + let (a, b) = copy(NoClone); + println!("{:?} {:?}", a, b); +} diff --git a/src/test/ui/auto-traits/issue-84075.stderr b/src/test/ui/auto-traits/issue-84075.stderr new file mode 100644 index 0000000000000..02dca598ec250 --- /dev/null +++ b/src/test/ui/auto-traits/issue-84075.stderr @@ -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`. diff --git a/src/test/ui/auto-traits/typeck-auto-trait-no-supertraits-2.rs b/src/test/ui/auto-traits/typeck-auto-trait-no-supertraits-2.rs index 6cceaf821f6bf..98359ef51b764 100644 --- a/src/test/ui/auto-traits/typeck-auto-trait-no-supertraits-2.rs +++ b/src/test/ui/auto-traits/typeck-auto-trait-no-supertraits-2.rs @@ -2,6 +2,7 @@ #![feature(negative_impls)] auto trait Magic : Sized where Option : Magic {} //~ ERROR E0568 +//~^ ERROR E0568 impl Magic for T {} fn copy(x: T) -> (T, T) { (x, x) } diff --git a/src/test/ui/auto-traits/typeck-auto-trait-no-supertraits-2.stderr b/src/test/ui/auto-traits/typeck-auto-trait-no-supertraits-2.stderr index 63b3300f6dbf4..4827916fa5c53 100644 --- a/src/test/ui/auto-traits/typeck-auto-trait-no-supertraits-2.stderr +++ b/src/test/ui/auto-traits/typeck-auto-trait-no-supertraits-2.stderr @@ -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 : 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 : 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`. diff --git a/src/test/ui/auto-traits/typeck-auto-trait-no-supertraits.stderr b/src/test/ui/auto-traits/typeck-auto-trait-no-supertraits.stderr index 796638fc54dce..d7716f4b61f04 100644 --- a/src/test/ui/auto-traits/typeck-auto-trait-no-supertraits.stderr +++ b/src/test/ui/auto-traits/typeck-auto-trait-no-supertraits.stderr @@ -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 diff --git a/src/test/ui/closures/issue-87814-2.rs b/src/test/ui/closures/issue-87814-2.rs index 7a5facdac58c3..efe77f90f0658 100644 --- a/src/test/ui/closures/issue-87814-2.rs +++ b/src/test/ui/closures/issue-87814-2.rs @@ -1,5 +1,4 @@ // check-pass -#![feature(try_reserve)] fn main() { let mut schema_all: (Vec, Vec) = (vec![], vec![]); diff --git a/src/test/ui/feature-gates/feature-gate-try_reserve.rs b/src/test/ui/feature-gates/feature-gate-try_reserve.rs deleted file mode 100644 index a19dd58da11b3..0000000000000 --- a/src/test/ui/feature-gates/feature-gate-try_reserve.rs +++ /dev/null @@ -1,4 +0,0 @@ -fn main() { - let v = Vec::new(); - v.try_reserve(10); //~ ERROR: use of unstable library feature 'try_reserve' -} diff --git a/src/test/ui/feature-gates/feature-gate-try_reserve.stderr b/src/test/ui/feature-gates/feature-gate-try_reserve.stderr deleted file mode 100644 index 4da9a23a1bd5f..0000000000000 --- a/src/test/ui/feature-gates/feature-gate-try_reserve.stderr +++ /dev/null @@ -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 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`. diff --git a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89118.rs b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89118.rs new file mode 100644 index 0000000000000..fffb54f86ca03 --- /dev/null +++ b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89118.rs @@ -0,0 +1,32 @@ +trait BufferMut {} +struct Ctx(D); + +trait BufferUdpStateContext {} +impl BufferUdpStateContext for C {} + +trait StackContext +where + Ctx<()>: for<'a> BufferUdpStateContext<&'a ()>, +{ + type Dispatcher; +} + +trait TimerContext { + type Handler; +} +impl TimerContext for C +where + C: StackContext, + //~^ ERROR: is not satisfied [E0277] +{ + type Handler = Ctx; + //~^ ERROR: is not satisfied [E0277] +} + +struct EthernetWorker(C) +where + Ctx<()>: for<'a> BufferUdpStateContext<&'a ()>; +impl EthernetWorker {} +//~^ ERROR: is not satisfied [E0277] + +fn main() {} diff --git a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89118.stderr b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89118.stderr new file mode 100644 index 0000000000000..7f45fb83cef08 --- /dev/null +++ b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89118.stderr @@ -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 BufferUdpStateContext 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; + | ^^^^^^^^^^^^^^^^^^ 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 BufferUdpStateContext 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 EthernetWorker {} + | ^^^^^^^^^^^^^^^^^ 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 BufferUdpStateContext for C {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ ^ +note: required by a bound in `EthernetWorker` + --> $DIR/issue-89118.rs:28:14 + | +LL | struct EthernetWorker(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`. diff --git a/src/test/ui/lint/issue-89469.rs b/src/test/ui/lint/issue-89469.rs new file mode 100644 index 0000000000000..3a6ab452840ac --- /dev/null +++ b/src/test/ui/lint/issue-89469.rs @@ -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() {} diff --git a/src/test/ui/parser/issue-89396.fixed b/src/test/ui/parser/issue-89396.fixed new file mode 100644 index 0000000000000..823ad8cd1f8df --- /dev/null +++ b/src/test/ui/parser/issue-89396.fixed @@ -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 + }; +} diff --git a/src/test/ui/parser/issue-89396.rs b/src/test/ui/parser/issue-89396.rs new file mode 100644 index 0000000000000..f1d9efa524f46 --- /dev/null +++ b/src/test/ui/parser/issue-89396.rs @@ -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 + }; +} diff --git a/src/test/ui/parser/issue-89396.stderr b/src/test/ui/parser/issue-89396.stderr new file mode 100644 index 0000000000000..504420574e249 --- /dev/null +++ b/src/test/ui/parser/issue-89396.stderr @@ -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 + diff --git a/src/test/ui/pattern/issue-88074-pat-range-type-inference-err.rs b/src/test/ui/pattern/issue-88074-pat-range-type-inference-err.rs new file mode 100644 index 0000000000000..16df272df6bd9 --- /dev/null +++ b/src/test/ui/pattern/issue-88074-pat-range-type-inference-err.rs @@ -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(); +} diff --git a/src/test/ui/pattern/issue-88074-pat-range-type-inference-err.stderr b/src/test/ui/pattern/issue-88074-pat-range-type-inference-err.stderr new file mode 100644 index 0000000000000..06a279925edbc --- /dev/null +++ b/src/test/ui/pattern/issue-88074-pat-range-type-inference-err.stderr @@ -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`. diff --git a/src/test/ui/pattern/issue-88074-pat-range-type-inference.rs b/src/test/ui/pattern/issue-88074-pat-range-type-inference.rs new file mode 100644 index 0000000000000..27db7d8c7ab9d --- /dev/null +++ b/src/test/ui/pattern/issue-88074-pat-range-type-inference.rs @@ -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 => {}, + _ => {}, + } +} diff --git a/src/test/ui/pattern/patkind-litrange-no-expr.rs b/src/test/ui/pattern/patkind-litrange-no-expr.rs index 9464f277fb088..7ef541cb58528 100644 --- a/src/test/ui/pattern/patkind-litrange-no-expr.rs +++ b/src/test/ui/pattern/patkind-litrange-no-expr.rs @@ -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() {} diff --git a/src/test/ui/pattern/patkind-litrange-no-expr.stderr b/src/test/ui/pattern/patkind-litrange-no-expr.stderr index 51af167a7c1d1..eb1ee7e45673d 100644 --- a/src/test/ui/pattern/patkind-litrange-no-expr.stderr +++ b/src/test/ui/pattern/patkind-litrange-no-expr.stderr @@ -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 3 previous errors +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0029`. diff --git a/src/test/ui/specialization/min_specialization/spec-marker-supertraits.rs b/src/test/ui/specialization/min_specialization/spec-marker-supertraits.rs new file mode 100644 index 0000000000000..3bb2480e9e2be --- /dev/null +++ b/src/test/ui/specialization/min_specialization/spec-marker-supertraits.rs @@ -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 Spec for T { + default fn spec_me(&self) {} +} + +impl Spec for T { + //~^ ERROR cannot specialize on trait `HasMethod` + fn spec_me(&self) { + self.method(); + } +} + +fn main() {} diff --git a/src/test/ui/specialization/min_specialization/spec-marker-supertraits.stderr b/src/test/ui/specialization/min_specialization/spec-marker-supertraits.stderr new file mode 100644 index 0000000000000..964109dd10f47 --- /dev/null +++ b/src/test/ui/specialization/min_specialization/spec-marker-supertraits.stderr @@ -0,0 +1,13 @@ +error: cannot specialize on trait `HasMethod` + --> $DIR/spec-marker-supertraits.rs:22:1 + | +LL | / impl Spec for T { +LL | | +LL | | fn spec_me(&self) { +LL | | self.method(); +LL | | } +LL | | } + | |_^ + +error: aborting due to previous error + diff --git a/src/test/ui/traits/inductive-overflow/supertrait-auto-trait.stderr b/src/test/ui/traits/inductive-overflow/supertrait-auto-trait.stderr index 7895e50eef5c4..8405d7ddc7aa5 100644 --- a/src/test/ui/traits/inductive-overflow/supertrait-auto-trait.stderr +++ b/src/test/ui/traits/inductive-overflow/supertrait-auto-trait.stderr @@ -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 diff --git a/src/tools/miri b/src/tools/miri index 035933186957c..18667a8565967 160000 --- a/src/tools/miri +++ b/src/tools/miri @@ -1 +1 @@ -Subproject commit 035933186957cf81c488261fb48a98bf523e8006 +Subproject commit 18667a856596713fc4479f99b96afc7f03aa995c diff --git a/src/tools/rust-analyzer b/src/tools/rust-analyzer index 009e6ceb1ddcd..4b7675fcc30d3 160000 --- a/src/tools/rust-analyzer +++ b/src/tools/rust-analyzer @@ -1 +1 @@ -Subproject commit 009e6ceb1ddcd27a9ced3bcb7d0ef823379185a1 +Subproject commit 4b7675fcc30d3e2c05eafc68a5724db66b58142c