diff options
474 files changed, 2644 insertions, 3247 deletions
diff --git a/Cargo.lock b/Cargo.lock index b5932607128..3f617af19b3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1686,9 +1686,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.19" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28560757fe2bb34e79f907794bb6b22ae8b0e5c669b638a1132f2592b19035b4" +checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" dependencies = [ "futures-channel", "futures-core", @@ -1701,9 +1701,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.19" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3dda0b6588335f360afc675d0564c17a77a2bda81ca178a4b6081bd86c7f0b" +checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" dependencies = [ "futures-core", "futures-sink", @@ -1711,15 +1711,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.19" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0c8ff0461b82559810cdccfde3215c3f373807f5e5232b71479bff7bb2583d7" +checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" [[package]] name = "futures-executor" -version = "0.3.19" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29d6d2ff5bb10fb95c85b8ce46538a2e5f5e7fdc755623a7d4529ab8a4ed9d2a" +checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" dependencies = [ "futures-core", "futures-task", @@ -1728,38 +1728,38 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.19" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f9d34af5a1aac6fb380f735fe510746c38067c5bf16c7fd250280503c971b2" +checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" [[package]] name = "futures-macro" -version = "0.3.19" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dbd947adfffb0efc70599b3ddcf7b5597bb5fa9e245eb99f62b3a5f7bb8bd3c" +checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 1.0.102", + "syn 2.0.8", ] [[package]] name = "futures-sink" -version = "0.3.19" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3055baccb68d74ff6480350f8d6eb8fcfa3aa11bdc1a1ae3afdd0514617d508" +checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" [[package]] name = "futures-task" -version = "0.3.19" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ee7c6485c30167ce4dfb83ac568a849fe53274c831081476ee13e0dce1aad72" +checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" [[package]] name = "futures-util" -version = "0.3.19" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b5cf40b47a271f77a8b1bec03ca09044d99d2372c0de244e66430761127164" +checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" dependencies = [ "futures-channel", "futures-core", @@ -2769,13 +2769,11 @@ dependencies = [ "anyhow", "clap 3.2.20", "flate2", - "lazy_static", "num_cpus", "rayon", "remove_dir_all", "tar", "walkdir", - "winapi", "xz2", ] @@ -4576,6 +4574,7 @@ dependencies = [ "elsa", "ena", "indexmap", + "itertools", "jobserver", "libc", "measureme", diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index fb9d71b52a8..df1a716755b 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -167,9 +167,6 @@ pub enum GenericArgs { AngleBracketed(AngleBracketedArgs), /// The `(A, B)` and `C` in `Foo(A, B) -> C`. Parenthesized(ParenthesizedArgs), - /// Associated return type bounds, like `T: Trait<method(..): Send>` - /// which applies the `Send` bound to the return-type of `method`. - ReturnTypeNotation(Span), } impl GenericArgs { @@ -181,7 +178,6 @@ impl GenericArgs { match self { AngleBracketed(data) => data.span, Parenthesized(data) => data.span, - ReturnTypeNotation(span) => *span, } } } diff --git a/compiler/rustc_ast/src/format.rs b/compiler/rustc_ast/src/format.rs index 356b9bb6371..699946f307b 100644 --- a/compiler/rustc_ast/src/format.rs +++ b/compiler/rustc_ast/src/format.rs @@ -94,7 +94,7 @@ impl FormatArguments { } if !matches!(arg.kind, FormatArgumentKind::Captured(..)) { // This is an explicit argument. - // Make sure that all arguments so far are explcit. + // Make sure that all arguments so far are explicit. assert_eq!( self.num_explicit_args, self.arguments.len(), diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 2424073ae53..694d31d8f1f 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -561,7 +561,6 @@ pub fn noop_visit_generic_args<T: MutVisitor>(generic_args: &mut GenericArgs, vi match generic_args { GenericArgs::AngleBracketed(data) => vis.visit_angle_bracketed_parameter_data(data), GenericArgs::Parenthesized(data) => vis.visit_parenthesized_parameter_data(data), - GenericArgs::ReturnTypeNotation(_span) => {} } } diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 3b08467fde2..ac9b321b71c 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -482,7 +482,6 @@ where walk_list!(visitor, visit_ty, &data.inputs); walk_fn_ret_ty(visitor, &data.output); } - GenericArgs::ReturnTypeNotation(_span) => {} } } diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs index f4e55619ebb..3e9f9b43623 100644 --- a/compiler/rustc_ast_lowering/src/errors.rs +++ b/compiler/rustc_ast_lowering/src/errors.rs @@ -137,7 +137,7 @@ pub struct AsyncNonMoveClosureNotSupported { #[derive(Diagnostic, Clone, Copy)] #[diag(ast_lowering_functional_record_update_destructuring_assignment)] -pub struct FunctionalRecordUpdateDestructuringAssignemnt { +pub struct FunctionalRecordUpdateDestructuringAssignment { #[primary_span] #[suggestion(code = "", applicability = "machine-applicable")] pub span: Span, @@ -353,13 +353,7 @@ pub enum BadReturnTypeNotation { #[diag(ast_lowering_bad_return_type_notation_inputs)] Inputs { #[primary_span] - #[suggestion(code = "(..)", applicability = "maybe-incorrect")] - span: Span, - }, - #[diag(ast_lowering_bad_return_type_notation_needs_dots)] - NeedsDots { - #[primary_span] - #[suggestion(code = "(..)", applicability = "maybe-incorrect")] + #[suggestion(code = "()", applicability = "maybe-incorrect")] span: Span, }, #[diag(ast_lowering_bad_return_type_notation_output)] diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 3247802345b..1b1c4765bc0 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -1,6 +1,6 @@ use super::errors::{ AsyncGeneratorsNotSupported, AsyncNonMoveClosureNotSupported, AwaitOnlyInAsyncFnAndBlocks, - BaseExpressionDoubleDot, ClosureCannotBeStatic, FunctionalRecordUpdateDestructuringAssignemnt, + BaseExpressionDoubleDot, ClosureCannotBeStatic, FunctionalRecordUpdateDestructuringAssignment, GeneratorTooManyParameters, InclusiveRangeWithNoEnd, NotSupportedForLifetimeBinderAsyncClosure, UnderscoreExprLhsAssign, }; @@ -434,7 +434,7 @@ impl<'hir> LoweringContext<'_, 'hir> { // `if let pat = val` or `if foo && let pat = val`, as we _do_ want `val` to live beyond the // condition in this case. // - // In order to mantain the drop behavior for the non `let` parts of the condition, + // In order to maintain the drop behavior for the non `let` parts of the condition, // we still wrap them in terminating scopes, e.g. `if foo && let pat = val` essentially // gets transformed into `if { let _t = foo; _t } && let pat = val` match &cond.kind { @@ -1232,7 +1232,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ); let fields_omitted = match &se.rest { StructRest::Base(e) => { - self.tcx.sess.emit_err(FunctionalRecordUpdateDestructuringAssignemnt { + self.tcx.sess.emit_err(FunctionalRecordUpdateDestructuringAssignment { span: e.span, }); true diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index ca659db4dbe..f7ae96b7c4a 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -987,15 +987,22 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { GenericArgs::AngleBracketed(data) => { self.lower_angle_bracketed_parameter_data(data, ParamMode::Explicit, itctx).0 } - &GenericArgs::ReturnTypeNotation(span) => GenericArgsCtor { - args: Default::default(), - bindings: &[], - parenthesized: hir::GenericArgsParentheses::ReturnTypeNotation, - span, - }, GenericArgs::Parenthesized(data) => { - if let Some(start_char) = constraint.ident.as_str().chars().next() - && start_char.is_ascii_lowercase() + if data.inputs.is_empty() && matches!(data.output, FnRetTy::Default(..)) { + let parenthesized = if self.tcx.features().return_type_notation { + hir::GenericArgsParentheses::ReturnTypeNotation + } else { + self.emit_bad_parenthesized_trait_in_assoc_ty(data); + hir::GenericArgsParentheses::No + }; + GenericArgsCtor { + args: Default::default(), + bindings: &[], + parenthesized, + span: data.inputs_span, + } + } else if let Some(first_char) = constraint.ident.as_str().chars().next() + && first_char.is_ascii_lowercase() { let mut err = if !data.inputs.is_empty() { self.tcx.sess.create_err(errors::BadReturnTypeNotation::Inputs { @@ -1006,9 +1013,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { span: data.inputs_span.shrink_to_hi().to(ty.span), }) } else { - self.tcx.sess.create_err(errors::BadReturnTypeNotation::NeedsDots { - span: data.inputs_span, - }) + unreachable!("inputs are empty and return type is not provided") }; if !self.tcx.features().return_type_notation && self.tcx.sess.is_nightly_build() diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs index 1c47a969696..8eb84c036a0 100644 --- a/compiler/rustc_ast_lowering/src/path.rs +++ b/compiler/rustc_ast_lowering/src/path.rs @@ -13,7 +13,6 @@ use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::{BytePos, Span, DUMMY_SP}; use smallvec::{smallvec, SmallVec}; -use thin_vec::ThinVec; impl<'a, 'hir> LoweringContext<'a, 'hir> { #[instrument(level = "trace", skip(self))] @@ -219,18 +218,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ) } }, - &GenericArgs::ReturnTypeNotation(span) => { - self.tcx.sess.emit_err(GenericTypeWithParentheses { span, sub: None }); - ( - self.lower_angle_bracketed_parameter_data( - &AngleBracketedArgs { span, args: ThinVec::default() }, - param_mode, - itctx, - ) - .0, - false, - ) - } } } else { ( diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index e7cdfeca6f9..c79626ccd76 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -1080,7 +1080,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> { self.with_impl_trait(None, |this| this.visit_ty(ty)); } } - GenericArgs::ReturnTypeNotation(_span) => {} } } @@ -1391,7 +1390,6 @@ fn deny_equality_constraints( match &mut assoc_path.segments[len].args { Some(args) => match args.deref_mut() { GenericArgs::Parenthesized(_) => continue, - GenericArgs::ReturnTypeNotation(_span) => continue, GenericArgs::AngleBracketed(args) => { args.args.push(arg); } diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 007d64f681f..17bcd24ee39 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -121,24 +121,34 @@ impl<'a> PostExpansionVisitor<'a> { } /// Feature gate `impl Trait` inside `type Alias = $type_expr;`. - fn check_impl_trait(&self, ty: &ast::Ty) { + fn check_impl_trait(&self, ty: &ast::Ty, in_associated_ty: bool) { struct ImplTraitVisitor<'a> { vis: &'a PostExpansionVisitor<'a>, + in_associated_ty: bool, } impl Visitor<'_> for ImplTraitVisitor<'_> { fn visit_ty(&mut self, ty: &ast::Ty) { if let ast::TyKind::ImplTrait(..) = ty.kind { - gate_feature_post!( - &self.vis, - type_alias_impl_trait, - ty.span, - "`impl Trait` in type aliases is unstable" - ); + if self.in_associated_ty { + gate_feature_post!( + &self.vis, + impl_trait_in_assoc_type, + ty.span, + "`impl Trait` in associated types is unstable" + ); + } else { + gate_feature_post!( + &self.vis, + type_alias_impl_trait, + ty.span, + "`impl Trait` in type aliases is unstable" + ); + } } visit::walk_ty(self, ty); } } - ImplTraitVisitor { vis: self }.visit_ty(ty); + ImplTraitVisitor { vis: self, in_associated_ty }.visit_ty(ty); } fn check_late_bound_lifetime_defs(&self, params: &[ast::GenericParam]) { @@ -294,7 +304,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } ast::ItemKind::TyAlias(box ast::TyAlias { ty: Some(ty), .. }) => { - self.check_impl_trait(&ty) + self.check_impl_trait(&ty, false) } _ => {} @@ -485,20 +495,23 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { fn visit_assoc_constraint(&mut self, constraint: &'a AssocConstraint) { if let AssocConstraintKind::Bound { .. } = constraint.kind { - if let Some(args) = constraint.gen_args.as_ref() - && matches!( - args, - ast::GenericArgs::ReturnTypeNotation(..) - ) + if let Some(ast::GenericArgs::Parenthesized(args)) = constraint.gen_args.as_ref() + && args.inputs.is_empty() + && matches!(args.output, ast::FnRetTy::Default(..)) { - // RTN is gated below with a `gate_all`. + gate_feature_post!( + &self, + return_type_notation, + constraint.span, + "return type notation is experimental" + ); } else { gate_feature_post!( &self, associated_type_bounds, constraint.span, "associated type bounds are unstable" - ) + ); } } visit::walk_assoc_constraint(self, constraint) @@ -517,7 +530,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { ); } if let Some(ty) = ty { - self.check_impl_trait(ty); + self.check_impl_trait(ty, true); } false } @@ -589,7 +602,6 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) { gate_all!(yeet_expr, "`do yeet` expression is experimental"); gate_all!(dyn_star, "`dyn*` trait objects are experimental"); gate_all!(const_closures, "const closures are experimental"); - gate_all!(return_type_notation, "return type notation is experimental"); // All uses of `gate_all!` below this point were added in #65742, // and subsequently disabled (with the non-early gating readded). @@ -605,6 +617,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) { gate_all!(trait_alias, "trait aliases are experimental"); gate_all!(associated_type_bounds, "associated type bounds are unstable"); + gate_all!(return_type_notation, "return type notation is experimental"); gate_all!(decl_macro, "`macro` is experimental"); gate_all!(box_patterns, "box pattern syntax is experimental"); gate_all!(exclusive_range_pattern, "exclusive range pattern syntax is experimental"); diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 1f6838a0278..849336c8669 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -936,10 +936,6 @@ impl<'a> PrintState<'a> for State<'a> { self.word(")"); self.print_fn_ret_ty(&data.output); } - - ast::GenericArgs::ReturnTypeNotation(_span) => { - self.word("(..)"); - } } } } diff --git a/compiler/rustc_borrowck/src/borrow_set.rs b/compiler/rustc_borrowck/src/borrow_set.rs index fa0552e012d..4824f6346d4 100644 --- a/compiler/rustc_borrowck/src/borrow_set.rs +++ b/compiler/rustc_borrowck/src/borrow_set.rs @@ -1,6 +1,5 @@ #![deny(rustc::untranslatable_diagnostic)] #![deny(rustc::diagnostic_outside_of_impl)] -use crate::nll::ToRegionVid; use crate::path_utils::allow_two_phase_borrow; use crate::place_ext::PlaceExt; use crate::BorrowIndex; @@ -204,7 +203,7 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherBorrows<'a, 'tcx> { return; } - let region = region.to_region_vid(); + let region = region.as_var(); let borrow = BorrowData { kind, @@ -279,7 +278,7 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherBorrows<'a, 'tcx> { let borrow_data = &self.location_map[&location]; assert_eq!(borrow_data.reserve_location, location); assert_eq!(borrow_data.kind, kind); - assert_eq!(borrow_data.region, region.to_region_vid()); + assert_eq!(borrow_data.region, region.as_var()); assert_eq!(borrow_data.borrowed_place, place); } diff --git a/compiler/rustc_borrowck/src/constraint_generation.rs b/compiler/rustc_borrowck/src/constraint_generation.rs index 1427f5cb31d..2aa09a3f26c 100644 --- a/compiler/rustc_borrowck/src/constraint_generation.rs +++ b/compiler/rustc_borrowck/src/constraint_generation.rs @@ -12,8 +12,8 @@ use rustc_middle::ty::visit::TypeVisitable; use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt}; use crate::{ - borrow_set::BorrowSet, facts::AllFacts, location::LocationTable, nll::ToRegionVid, - places_conflict, region_infer::values::LivenessValues, + borrow_set::BorrowSet, facts::AllFacts, location::LocationTable, places_conflict, + region_infer::values::LivenessValues, }; pub(super) fn generate_constraints<'tcx>( @@ -170,7 +170,7 @@ impl<'cx, 'tcx> ConstraintGeneration<'cx, 'tcx> { debug!("add_regular_live_constraint(live_ty={:?}, location={:?})", live_ty, location); self.infcx.tcx.for_each_free_region(&live_ty, |live_region| { - let vid = live_region.to_region_vid(); + let vid = live_region.as_var(); self.liveness_constraints.add_element(vid, location); }); } diff --git a/compiler/rustc_borrowck/src/constraints/graph.rs b/compiler/rustc_borrowck/src/constraints/graph.rs index c780d047992..f5a34cb0561 100644 --- a/compiler/rustc_borrowck/src/constraints/graph.rs +++ b/compiler/rustc_borrowck/src/constraints/graph.rs @@ -13,7 +13,7 @@ use crate::{ /// The construct graph organizes the constraints by their end-points. /// It can be used to view a `R1: R2` constraint as either an edge `R1 /// -> R2` or `R2 -> R1` depending on the direction type `D`. -pub(crate) struct ConstraintGraph<D: ConstraintGraphDirecton> { +pub(crate) struct ConstraintGraph<D: ConstraintGraphDirection> { _direction: D, first_constraints: IndexVec<RegionVid, Option<OutlivesConstraintIndex>>, next_constraints: IndexVec<OutlivesConstraintIndex, Option<OutlivesConstraintIndex>>, @@ -25,7 +25,7 @@ pub(crate) type ReverseConstraintGraph = ConstraintGraph<Reverse>; /// Marker trait that controls whether a `R1: R2` constraint /// represents an edge `R1 -> R2` or `R2 -> R1`. -pub(crate) trait ConstraintGraphDirecton: Copy + 'static { +pub(crate) trait ConstraintGraphDirection: Copy + 'static { fn start_region(c: &OutlivesConstraint<'_>) -> RegionVid; fn end_region(c: &OutlivesConstraint<'_>) -> RegionVid; fn is_normal() -> bool; @@ -38,7 +38,7 @@ pub(crate) trait ConstraintGraphDirecton: Copy + 'static { #[derive(Copy, Clone, Debug)] pub(crate) struct Normal; -impl ConstraintGraphDirecton for Normal { +impl ConstraintGraphDirection for Normal { fn start_region(c: &OutlivesConstraint<'_>) -> RegionVid { c.sup } @@ -59,7 +59,7 @@ impl ConstraintGraphDirecton for Normal { #[derive(Copy, Clone, Debug)] pub(crate) struct Reverse; -impl ConstraintGraphDirecton for Reverse { +impl ConstraintGraphDirection for Reverse { fn start_region(c: &OutlivesConstraint<'_>) -> RegionVid { c.sub } @@ -73,7 +73,7 @@ impl ConstraintGraphDirecton for Reverse { } } -impl<D: ConstraintGraphDirecton> ConstraintGraph<D> { +impl<D: ConstraintGraphDirection> ConstraintGraph<D> { /// Creates a "dependency graph" where each region constraint `R1: /// R2` is treated as an edge `R1 -> R2`. We use this graph to /// construct SCCs for region inference but also for error @@ -133,7 +133,7 @@ impl<D: ConstraintGraphDirecton> ConstraintGraph<D> { } } -pub(crate) struct Edges<'s, 'tcx, D: ConstraintGraphDirecton> { +pub(crate) struct Edges<'s, 'tcx, D: ConstraintGraphDirection> { graph: &'s ConstraintGraph<D>, constraints: &'s OutlivesConstraintSet<'tcx>, pointer: Option<OutlivesConstraintIndex>, @@ -141,7 +141,7 @@ pub(crate) struct Edges<'s, 'tcx, D: ConstraintGraphDirecton> { static_region: RegionVid, } -impl<'s, 'tcx, D: ConstraintGraphDirecton> Iterator for Edges<'s, 'tcx, D> { +impl<'s, 'tcx, D: ConstraintGraphDirection> Iterator for Edges<'s, 'tcx, D> { type Item = OutlivesConstraint<'tcx>; fn next(&mut self) -> Option<Self::Item> { @@ -174,13 +174,13 @@ impl<'s, 'tcx, D: ConstraintGraphDirecton> Iterator for Edges<'s, 'tcx, D> { /// This struct brings together a constraint set and a (normal, not /// reverse) constraint graph. It implements the graph traits and is /// usd for doing the SCC computation. -pub(crate) struct RegionGraph<'s, 'tcx, D: ConstraintGraphDirecton> { +pub(crate) struct RegionGraph<'s, 'tcx, D: ConstraintGraphDirection> { set: &'s OutlivesConstraintSet<'tcx>, constraint_graph: &'s ConstraintGraph<D>, static_region: RegionVid, } -impl<'s, 'tcx, D: ConstraintGraphDirecton> RegionGraph<'s, 'tcx, D> { +impl<'s, 'tcx, D: ConstraintGraphDirection> RegionGraph<'s, 'tcx, D> { /// Creates a "dependency graph" where each region constraint `R1: /// R2` is treated as an edge `R1 -> R2`. We use this graph to /// construct SCCs for region inference but also for error @@ -202,11 +202,11 @@ impl<'s, 'tcx, D: ConstraintGraphDirecton> RegionGraph<'s, 'tcx, D> { } } -pub(crate) struct Successors<'s, 'tcx, D: ConstraintGraphDirecton> { +pub(crate) struct Successors<'s, 'tcx, D: ConstraintGraphDirection> { edges: Edges<'s, 'tcx, D>, } -impl<'s, 'tcx, D: ConstraintGraphDirecton> Iterator for Successors<'s, 'tcx, D> { +impl<'s, 'tcx, D: ConstraintGraphDirection> Iterator for Successors<'s, 'tcx, D> { type Item = RegionVid; fn next(&mut self) -> Option<Self::Item> { @@ -214,23 +214,25 @@ impl<'s, 'tcx, D: ConstraintGraphDirecton> Iterator for Successors<'s, 'tcx, D> } } -impl<'s, 'tcx, D: ConstraintGraphDirecton> graph::DirectedGraph for RegionGraph<'s, 'tcx, D> { +impl<'s, 'tcx, D: ConstraintGraphDirection> graph::DirectedGraph for RegionGraph<'s, 'tcx, D> { type Node = RegionVid; } -impl<'s, 'tcx, D: ConstraintGraphDirecton> graph::WithNumNodes for RegionGraph<'s, 'tcx, D> { +impl<'s, 'tcx, D: ConstraintGraphDirection> graph::WithNumNodes for RegionGraph<'s, 'tcx, D> { fn num_nodes(&self) -> usize { self.constraint_graph.first_constraints.len() } } -impl<'s, 'tcx, D: ConstraintGraphDirecton> graph::WithSuccessors for RegionGraph<'s, 'tcx, D> { +impl<'s, 'tcx, D: ConstraintGraphDirection> graph::WithSuccessors for RegionGraph<'s, 'tcx, D> { fn successors(&self, node: Self::Node) -> <Self as graph::GraphSuccessors<'_>>::Iter { self.outgoing_regions(node) } } -impl<'s, 'tcx, D: ConstraintGraphDirecton> graph::GraphSuccessors<'_> for RegionGraph<'s, 'tcx, D> { +impl<'s, 'tcx, D: ConstraintGraphDirection> graph::GraphSuccessors<'_> + for RegionGraph<'s, 'tcx, D> +{ type Item = RegionVid; type Iter = Successors<'s, 'tcx, D>; } diff --git a/compiler/rustc_borrowck/src/dataflow.rs b/compiler/rustc_borrowck/src/dataflow.rs index 2cbd2e3bc0d..94939c7e4cd 100644 --- a/compiler/rustc_borrowck/src/dataflow.rs +++ b/compiler/rustc_borrowck/src/dataflow.rs @@ -11,9 +11,7 @@ use rustc_mir_dataflow::{self, fmt::DebugWithContext, CallReturnPlaces, GenKill} use rustc_mir_dataflow::{Analysis, Direction, Results}; use std::fmt; -use crate::{ - places_conflict, BorrowSet, PlaceConflictBias, PlaceExt, RegionInferenceContext, ToRegionVid, -}; +use crate::{places_conflict, BorrowSet, PlaceConflictBias, PlaceExt, RegionInferenceContext}; /// A tuple with named fields that can hold either the results or the transient state of the /// dataflow analyses used by the borrow checker. @@ -242,7 +240,7 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> { ) -> Self { let mut prec = OutOfScopePrecomputer::new(body, nonlexical_regioncx); for (borrow_index, borrow_data) in borrow_set.iter_enumerated() { - let borrow_region = borrow_data.region.to_region_vid(); + let borrow_region = borrow_data.region; let location = borrow_data.reserve_location; prec.precompute_borrows_out_of_scope(borrow_index, borrow_region, location); diff --git a/compiler/rustc_borrowck/src/diagnostics/find_use.rs b/compiler/rustc_borrowck/src/diagnostics/find_use.rs index e2d04324f3b..2495613fea1 100644 --- a/compiler/rustc_borrowck/src/diagnostics/find_use.rs +++ b/compiler/rustc_borrowck/src/diagnostics/find_use.rs @@ -6,7 +6,6 @@ use std::rc::Rc; use crate::{ def_use::{self, DefUse}, - nll::ToRegionVid, region_infer::{Cause, RegionInferenceContext}, }; use rustc_data_structures::fx::FxIndexSet; @@ -117,7 +116,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for DefUseVisitor<'cx, 'tcx> { let mut found_it = false; self.tcx.for_each_free_region(&local_ty, |r| { - if r.to_region_vid() == self.region_vid { + if r.as_var() == self.region_vid { found_it = true; } }); diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs index cc5a1f5ab12..f69c4829ae2 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs @@ -10,7 +10,7 @@ use rustc_middle::ty::{self, RegionVid, Ty}; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{Span, DUMMY_SP}; -use crate::{nll::ToRegionVid, universal_regions::DefiningTy, MirBorrowckCtxt}; +use crate::{universal_regions::DefiningTy, MirBorrowckCtxt}; /// A name for a particular region used in emitting diagnostics. This name could be a generated /// name like `'1`, a name used by the user like `'a`, or a name like `'static`. @@ -497,7 +497,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { // & // - let's call the lifetime of this reference `'1` (ty::Ref(region, referent_ty, _), hir::TyKind::Ref(_lifetime, referent_hir_ty)) => { - if region.to_region_vid() == needle_fr { + if region.as_var() == needle_fr { // Just grab the first character, the `&`. let source_map = self.infcx.tcx.sess.source_map(); let ampersand_span = source_map.start_point(hir_ty.span); @@ -598,7 +598,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { for (kind, hir_arg) in iter::zip(substs, args.args) { match (kind.unpack(), hir_arg) { (GenericArgKind::Lifetime(r), hir::GenericArg::Lifetime(lt)) => { - if r.to_region_vid() == needle_fr { + if r.as_var() == needle_fr { return Some(lt); } } @@ -666,7 +666,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { let return_ty = self.regioncx.universal_regions().unnormalized_output_ty; debug!("give_name_if_anonymous_region_appears_in_output: return_ty = {:?}", return_ty); - if !tcx.any_free_region_meets(&return_ty, |r| r.to_region_vid() == fr) { + if !tcx.any_free_region_meets(&return_ty, |r| r.as_var() == fr) { return None; } @@ -803,7 +803,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { let tcx = self.infcx.tcx; - if !tcx.any_free_region_meets(&yield_ty, |r| r.to_region_vid() == fr) { + if !tcx.any_free_region_meets(&yield_ty, |r| r.as_var() == fr) { return None; } diff --git a/compiler/rustc_borrowck/src/diagnostics/var_name.rs b/compiler/rustc_borrowck/src/diagnostics/var_name.rs index 80b2787ce0c..376415e3d32 100644 --- a/compiler/rustc_borrowck/src/diagnostics/var_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/var_name.rs @@ -1,8 +1,8 @@ #![deny(rustc::untranslatable_diagnostic)] #![deny(rustc::diagnostic_outside_of_impl)] +use crate::region_infer::RegionInferenceContext; use crate::Upvar; -use crate::{nll::ToRegionVid, region_infer::RegionInferenceContext}; use rustc_index::vec::{Idx, IndexSlice}; use rustc_middle::mir::{Body, Local}; use rustc_middle::ty::{RegionVid, TyCtxt}; @@ -46,7 +46,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { self.universal_regions().defining_ty.upvar_tys().position(|upvar_ty| { debug!("get_upvar_index_for_region: upvar_ty={upvar_ty:?}"); tcx.any_free_region_meets(&upvar_ty, |r| { - let r = r.to_region_vid(); + let r = r.as_var(); debug!("get_upvar_index_for_region: r={r:?} fr={fr:?}"); r == fr }) @@ -96,7 +96,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { self.universal_regions().unnormalized_input_tys.iter().skip(implicit_inputs).position( |arg_ty| { debug!("get_argument_index_for_region: arg_ty = {arg_ty:?}"); - tcx.any_free_region_meets(arg_ty, |r| r.to_region_vid() == fr) + tcx.any_free_region_meets(arg_ty, |r| r.as_var() == fr) }, )?; diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 3d876155fc9..a4b285a34fa 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -94,7 +94,7 @@ pub mod consumers; use borrow_set::{BorrowData, BorrowSet}; use dataflow::{BorrowIndex, BorrowckFlowState as Flows, BorrowckResults, Borrows}; -use nll::{PoloniusOutput, ToRegionVid}; +use nll::PoloniusOutput; use place_ext::PlaceExt; use places_conflict::{places_conflict, PlaceConflictBias}; use region_infer::RegionInferenceContext; @@ -507,9 +507,7 @@ impl<'cx, 'tcx> BorrowckInferCtxt<'cx, 'tcx> { F: Fn() -> RegionCtxt, { let next_region = self.infcx.next_region_var(origin); - let vid = next_region - .as_var() - .unwrap_or_else(|| bug!("expected RegionKind::RegionVar on {:?}", next_region)); + let vid = next_region.as_var(); if cfg!(debug_assertions) && !self.inside_canonicalization_ctxt() { debug!("inserting vid {:?} with origin {:?} into var_to_origin", vid, origin); @@ -531,9 +529,7 @@ impl<'cx, 'tcx> BorrowckInferCtxt<'cx, 'tcx> { F: Fn() -> RegionCtxt, { let next_region = self.infcx.next_nll_region_var(origin.clone()); - let vid = next_region - .as_var() - .unwrap_or_else(|| bug!("expected RegionKind::RegionVar on {:?}", next_region)); + let vid = next_region.as_var(); if cfg!(debug_assertions) && !self.inside_canonicalization_ctxt() { debug!("inserting vid {:?} with origin {:?} into var_to_origin", vid, origin); diff --git a/compiler/rustc_borrowck/src/nll.rs b/compiler/rustc_borrowck/src/nll.rs index 06ecbdb1707..59a3ab3189d 100644 --- a/compiler/rustc_borrowck/src/nll.rs +++ b/compiler/rustc_borrowck/src/nll.rs @@ -10,7 +10,7 @@ use rustc_middle::mir::{ BasicBlock, Body, ClosureOutlivesSubject, ClosureRegionRequirements, LocalKind, Location, Promoted, }; -use rustc_middle::ty::{self, OpaqueHiddenType, Region, RegionVid, TyCtxt}; +use rustc_middle::ty::{self, OpaqueHiddenType, TyCtxt}; use rustc_span::symbol::sym; use std::env; use std::io; @@ -444,27 +444,6 @@ fn for_each_region_constraint<'tcx>( Ok(()) } -/// Right now, we piggy back on the `ReVar` to store our NLL inference -/// regions. These are indexed with `RegionVid`. This method will -/// assert that the region is a `ReVar` and extract its internal index. -/// This is reasonable because in our MIR we replace all universal regions -/// with inference variables. -pub trait ToRegionVid { - fn to_region_vid(self) -> RegionVid; -} - -impl<'tcx> ToRegionVid for Region<'tcx> { - fn to_region_vid(self) -> RegionVid { - if let ty::ReVar(vid) = *self { vid } else { bug!("region is not an ReVar: {:?}", self) } - } -} - -impl ToRegionVid for RegionVid { - fn to_region_vid(self) -> RegionVid { - self - } -} - pub(crate) trait ConstraintDescription { fn description(&self) -> &'static str; } diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index f67af4584a4..729f3dbff3b 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -27,7 +27,7 @@ use crate::{ }, diagnostics::{RegionErrorKind, RegionErrors, UniverseInfo}, member_constraints::{MemberConstraintSet, NllMemberConstraintIndex}, - nll::{PoloniusOutput, ToRegionVid}, + nll::PoloniusOutput, region_infer::reverse_sccs::ReverseSccGraph, region_infer::values::{ LivenessValues, PlaceholderIndices, RegionElement, RegionValueElements, RegionValues, @@ -593,14 +593,14 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// Returns `true` if the region `r` contains the point `p`. /// /// Panics if called before `solve()` executes, - pub(crate) fn region_contains(&self, r: impl ToRegionVid, p: impl ToElementIndex) -> bool { - let scc = self.constraint_sccs.scc(r.to_region_vid()); + pub(crate) fn region_contains(&self, r: RegionVid, p: impl ToElementIndex) -> bool { + let scc = self.constraint_sccs.scc(r); self.scc_values.contains(scc, p) } /// Returns access to the value of `r` for debugging purposes. pub(crate) fn region_value_str(&self, r: RegionVid) -> String { - let scc = self.constraint_sccs.scc(r.to_region_vid()); + let scc = self.constraint_sccs.scc(r); self.scc_values.region_value_str(scc) } @@ -608,24 +608,21 @@ impl<'tcx> RegionInferenceContext<'tcx> { &'a self, r: RegionVid, ) -> impl Iterator<Item = ty::PlaceholderRegion> + 'a { - let scc = self.constraint_sccs.scc(r.to_region_vid()); + let scc = self.constraint_sccs.scc(r); self.scc_values.placeholders_contained_in(scc) } /// Returns access to the value of `r` for debugging purposes. pub(crate) fn region_universe(&self, r: RegionVid) -> ty::UniverseIndex { - let scc = self.constraint_sccs.scc(r.to_region_vid()); + let scc = self.constraint_sccs.scc(r); self.scc_universes[scc] } /// Once region solving has completed, this function will return /// the member constraints that were applied to the value of a given /// region `r`. See `AppliedMemberConstraint`. - pub(crate) fn applied_member_constraints( - &self, - r: impl ToRegionVid, - ) -> &[AppliedMemberConstraint] { - let scc = self.constraint_sccs.scc(r.to_region_vid()); + pub(crate) fn applied_member_constraints(&self, r: RegionVid) -> &[AppliedMemberConstraint] { + let scc = self.constraint_sccs.scc(r); binary_search_util::binary_search_slice( &self.member_constraints_applied, |applied| applied.member_region_scc, @@ -1133,7 +1130,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { let r_vid = self.to_region_vid(r); let r_scc = self.constraint_sccs.scc(r_vid); - // The challenge if this. We have some region variable `r` + // The challenge is this. We have some region variable `r` // whose value is a set of CFG points and universal // regions. We want to find if that set is *equivalent* to // any of the named regions found in the closure. @@ -2234,7 +2231,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { r: RegionVid, body: &Body<'_>, ) -> Option<Location> { - let scc = self.constraint_sccs.scc(r.to_region_vid()); + let scc = self.constraint_sccs.scc(r); let locations = self.scc_values.locations_outlived_by(scc); for location in locations { let bb = &body[location.block]; diff --git a/compiler/rustc_borrowck/src/renumber.rs b/compiler/rustc_borrowck/src/renumber.rs index 0fbf01dbe44..94ce29dfe51 100644 --- a/compiler/rustc_borrowck/src/renumber.rs +++ b/compiler/rustc_borrowck/src/renumber.rs @@ -20,31 +20,13 @@ pub fn renumber_mir<'tcx>( ) { debug!(?body.arg_count); - let mut visitor = NllVisitor { infcx }; + let mut renumberer = RegionRenumberer { infcx }; for body in promoted.iter_mut() { - visitor.visit_body(body); + renumberer.visit_body(body); } - visitor.visit_body(body); -} - -/// Replaces all regions appearing in `value` with fresh inference -/// variables. -#[instrument(skip(infcx, get_ctxt_fn), level = "debug")] -pub(crate) fn renumber_regions<'tcx, T, F>( - infcx: &BorrowckInferCtxt<'_, 'tcx>, - value: T, - get_ctxt_fn: F, -) -> T -where - T: TypeFoldable<TyCtxt<'tcx>>, - F: Fn() -> RegionCtxt, -{ - infcx.tcx.fold_regions(value, |_region, _depth| { - let origin = NllRegionVariableOrigin::Existential { from_forall: false }; - infcx.next_nll_region_var(origin, || get_ctxt_fn()) - }) + renumberer.visit_body(body); } #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] @@ -69,12 +51,10 @@ impl RegionCtxt { /// Used to determine the representative of a component in the strongly connected /// constraint graph pub(crate) fn preference_value(self) -> usize { - let _anon = Symbol::intern("anon"); - match self { RegionCtxt::Unknown => 1, RegionCtxt::Existential(None) => 2, - RegionCtxt::Existential(Some(_anon)) | RegionCtxt::Free(_anon) => 2, + RegionCtxt::Existential(Some(_)) | RegionCtxt::Free(_) => 2, RegionCtxt::Location(_) => 3, RegionCtxt::TyContext(_) => 4, _ => 5, @@ -82,21 +62,26 @@ impl RegionCtxt { } } -struct NllVisitor<'a, 'tcx> { +struct RegionRenumberer<'a, 'tcx> { infcx: &'a BorrowckInferCtxt<'a, 'tcx>, } -impl<'a, 'tcx> NllVisitor<'a, 'tcx> { +impl<'a, 'tcx> RegionRenumberer<'a, 'tcx> { + /// Replaces all regions appearing in `value` with fresh inference + /// variables. fn renumber_regions<T, F>(&mut self, value: T, region_ctxt_fn: F) -> T where T: TypeFoldable<TyCtxt<'tcx>>, F: Fn() -> RegionCtxt, { - renumber_regions(self.infcx, value, region_ctxt_fn) + let origin = NllRegionVariableOrigin::Existential { from_forall: false }; + self.infcx.tcx.fold_regions(value, |_region, _depth| { + self.infcx.next_nll_region_var(origin, || region_ctxt_fn()) + }) } } -impl<'a, 'tcx> MutVisitor<'tcx> for NllVisitor<'a, 'tcx> { +impl<'a, 'tcx> MutVisitor<'tcx> for RegionRenumberer<'a, 'tcx> { fn tcx(&self) -> TyCtxt<'tcx> { self.infcx.tcx } @@ -124,9 +109,9 @@ impl<'a, 'tcx> MutVisitor<'tcx> for NllVisitor<'a, 'tcx> { } #[instrument(skip(self), level = "debug")] - fn visit_constant(&mut self, constant: &mut Constant<'tcx>, _location: Location) { + fn visit_constant(&mut self, constant: &mut Constant<'tcx>, location: Location) { let literal = constant.literal; - constant.literal = self.renumber_regions(literal, || RegionCtxt::Location(_location)); + constant.literal = self.renumber_regions(literal, || RegionCtxt::Location(location)); debug!("constant: {:#?}", constant); } } diff --git a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs index a9356135006..71eae7b27d1 100644 --- a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs +++ b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs @@ -12,7 +12,6 @@ use rustc_span::{Span, DUMMY_SP}; use crate::{ constraints::OutlivesConstraint, - nll::ToRegionVid, region_infer::TypeTest, type_check::{Locations, MirTypeckRegionConstraints}, universal_regions::UniversalRegions, @@ -198,7 +197,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> { fn to_region_vid(&mut self, r: ty::Region<'tcx>) -> ty::RegionVid { if let ty::RePlaceholder(placeholder) = *r { - self.constraints.placeholder_region(self.infcx, placeholder).to_region_vid() + self.constraints.placeholder_region(self.infcx, placeholder).as_var() } else { self.universal_regions.to_region_vid(r) } diff --git a/compiler/rustc_borrowck/src/type_check/liveness/mod.rs b/compiler/rustc_borrowck/src/type_check/liveness/mod.rs index a411aec518e..f1ad0ca55cc 100644 --- a/compiler/rustc_borrowck/src/type_check/liveness/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/liveness/mod.rs @@ -11,7 +11,6 @@ use crate::{ constraints::OutlivesConstraintSet, facts::{AllFacts, AllFactsExt}, location::LocationTable, - nll::ToRegionVid, region_infer::values::RegionValueElements, universal_regions::UniversalRegions, }; @@ -80,9 +79,7 @@ fn compute_relevant_live_locals<'tcx>( ) -> (Vec<Local>, Vec<Local>) { let (boring_locals, relevant_live_locals): (Vec<_>, Vec<_>) = body.local_decls.iter_enumerated().partition_map(|(local, local_decl)| { - if tcx.all_free_regions_meet(&local_decl.ty, |r| { - free_regions.contains(&r.to_region_vid()) - }) { + if tcx.all_free_regions_meet(&local_decl.ty, |r| free_regions.contains(&r.as_var())) { Either::Left(local) } else { Either::Right(local) diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 624a4a00c31..375eca1b29d 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -35,6 +35,7 @@ use rustc_middle::ty::{ OpaqueHiddenType, OpaqueTypeKey, RegionVid, Ty, TyCtxt, UserType, UserTypeAnnotationIndex, }; use rustc_span::def_id::CRATE_DEF_ID; +use rustc_span::symbol::sym; use rustc_span::{Span, DUMMY_SP}; use rustc_target::abi::{FieldIdx, FIRST_VARIANT}; use rustc_trait_selection::traits::query::type_op::custom::scrape_region_constraints; @@ -55,7 +56,6 @@ use crate::{ facts::AllFacts, location::LocationTable, member_constraints::MemberConstraintSet, - nll::ToRegionVid, path_utils, region_infer::values::{ LivenessValues, PlaceholderIndex, PlaceholderIndices, RegionValueElements, @@ -1338,18 +1338,13 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { }; let (sig, map) = tcx.replace_late_bound_regions(sig, |br| { use crate::renumber::{BoundRegionInfo, RegionCtxt}; - use rustc_span::Symbol; let region_ctxt_fn = || { let reg_info = match br.kind { ty::BoundRegionKind::BrAnon(Some(span)) => BoundRegionInfo::Span(span), - ty::BoundRegionKind::BrAnon(..) => { - BoundRegionInfo::Name(Symbol::intern("anon")) - } + ty::BoundRegionKind::BrAnon(..) => BoundRegionInfo::Name(sym::anon), ty::BoundRegionKind::BrNamed(_, name) => BoundRegionInfo::Name(name), - ty::BoundRegionKind::BrEnv => { - BoundRegionInfo::Name(Symbol::intern("env")) - } + ty::BoundRegionKind::BrEnv => BoundRegionInfo::Name(sym::env), }; RegionCtxt::LateBound(reg_info) @@ -2423,7 +2418,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { if let Some(all_facts) = all_facts { let _prof_timer = self.infcx.tcx.prof.generic_activity("polonius_fact_generation"); if let Some(borrow_index) = borrow_set.get_index_of(&location) { - let region_vid = borrow_region.to_region_vid(); + let region_vid = borrow_region.as_var(); all_facts.loan_issued_at.push(( region_vid, borrow_index, @@ -2469,8 +2464,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { match base_ty.kind() { ty::Ref(ref_region, _, mutbl) => { constraints.outlives_constraints.push(OutlivesConstraint { - sup: ref_region.to_region_vid(), - sub: borrow_region.to_region_vid(), + sup: ref_region.as_var(), + sub: borrow_region.as_var(), locations: location.to_locations(), span: location.to_locations().span(body), category, @@ -2600,7 +2595,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { self.implicit_region_bound, self.param_env, location.to_locations(), - DUMMY_SP, // irrelevant; will be overrided. + DUMMY_SP, // irrelevant; will be overridden. ConstraintCategory::Boring, // same as above. &mut self.borrowck_context.constraints, ) diff --git a/compiler/rustc_borrowck/src/type_check/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs index 83429f2ddef..7e6d17ec343 100644 --- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs +++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs @@ -4,6 +4,7 @@ use rustc_infer::traits::PredicateObligations; use rustc_middle::mir::ConstraintCategory; use rustc_middle::ty::relate::TypeRelation; use rustc_middle::ty::{self, Ty}; +use rustc_span::symbol::sym; use rustc_span::{Span, Symbol}; use rustc_trait_selection::traits::query::Fallible; @@ -125,18 +126,14 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx> let reg_info = match placeholder.bound.kind { ty::BoundRegionKind::BrAnon(Some(span)) => BoundRegionInfo::Span(span), - ty::BoundRegionKind::BrAnon(..) => BoundRegionInfo::Name(Symbol::intern("anon")), + ty::BoundRegionKind::BrAnon(..) => BoundRegionInfo::Name(sym::anon), ty::BoundRegionKind::BrNamed(_, name) => BoundRegionInfo::Name(name), - ty::BoundRegionKind::BrEnv => BoundRegionInfo::Name(Symbol::intern("env")), + ty::BoundRegionKind::BrEnv => BoundRegionInfo::Name(sym::env), }; - let reg_var = - reg.as_var().unwrap_or_else(|| bug!("expected region {:?} to be of kind ReVar", reg)); - if cfg!(debug_assertions) && !self.type_checker.infcx.inside_canonicalization_ctxt() { let mut var_to_origin = self.type_checker.infcx.reg_var_to_origin.borrow_mut(); - debug!(?reg_var); - var_to_origin.insert(reg_var, RegionCtxt::Placeholder(reg_info)); + var_to_origin.insert(reg.as_var(), RegionCtxt::Placeholder(reg_info)); } reg @@ -149,12 +146,9 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx> universe, ); - let reg_var = - reg.as_var().unwrap_or_else(|| bug!("expected region {:?} to be of kind ReVar", reg)); - if cfg!(debug_assertions) && !self.type_checker.infcx.inside_canonicalization_ctxt() { let mut var_to_origin = self.type_checker.infcx.reg_var_to_origin.borrow_mut(); - var_to_origin.insert(reg_var, RegionCtxt::Existential(None)); + var_to_origin.insert(reg.as_var(), RegionCtxt::Existential(None)); } reg diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs index 68c86051364..70fddb1057c 100644 --- a/compiler/rustc_borrowck/src/universal_regions.rs +++ b/compiler/rustc_borrowck/src/universal_regions.rs @@ -24,10 +24,10 @@ use rustc_infer::infer::NllRegionVariableOrigin; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::{self, InlineConstSubsts, InlineConstSubstsParts, RegionVid, Ty, TyCtxt}; use rustc_middle::ty::{InternalSubsts, SubstsRef}; +use rustc_span::symbol::{kw, sym}; use rustc_span::Symbol; use std::iter; -use crate::nll::ToRegionVid; use crate::renumber::{BoundRegionInfo, RegionCtxt}; use crate::BorrowckInferCtxt; @@ -404,10 +404,8 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { assert_eq!(FIRST_GLOBAL_INDEX, self.infcx.num_region_vars()); // Create the "global" region that is always free in all contexts: 'static. - let fr_static = self - .infcx - .next_nll_region_var(FR, || RegionCtxt::Free(Symbol::intern("static"))) - .to_region_vid(); + let fr_static = + self.infcx.next_nll_region_var(FR, || RegionCtxt::Free(kw::Static)).as_var(); // We've now added all the global regions. The next ones we // add will be external. @@ -440,18 +438,14 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { debug!(?r); if !indices.indices.contains_key(&r) { let region_vid = { - let name = match r.get_name() { - Some(name) => name, - _ => Symbol::intern("anon"), - }; - + let name = r.get_name_or_anon(); self.infcx.next_nll_region_var(FR, || { RegionCtxt::LateBound(BoundRegionInfo::Name(name)) }) }; debug!(?region_vid); - indices.insert_late_bound_region(r, region_vid.to_region_vid()); + indices.insert_late_bound_region(r, region_vid.as_var()); } }, ); @@ -478,18 +472,14 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { debug!(?r); if !indices.indices.contains_key(&r) { let region_vid = { - let name = match r.get_name() { - Some(name) => name, - _ => Symbol::intern("anon"), - }; - + let name = r.get_name_or_anon(); self.infcx.next_nll_region_var(FR, || { RegionCtxt::LateBound(BoundRegionInfo::Name(name)) }) }; debug!(?region_vid); - indices.insert_late_bound_region(r, region_vid.to_region_vid()); + indices.insert_late_bound_region(r, region_vid.as_var()); } }); @@ -508,7 +498,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { let reg_vid = self .infcx .next_nll_region_var(FR, || RegionCtxt::Free(Symbol::intern("c-variadic"))) - .to_region_vid(); + .as_var(); let region = self.infcx.tcx.mk_re_var(reg_vid); let va_list_ty = @@ -523,7 +513,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { let fr_fn_body = self .infcx .next_nll_region_var(FR, || RegionCtxt::Free(Symbol::intern("fn_body"))) - .to_region_vid(); + .as_var(); let num_universals = self.infcx.num_region_vars(); @@ -644,7 +634,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { let global_mapping = iter::once((tcx.lifetimes.re_static, fr_static)); let subst_mapping = - iter::zip(identity_substs.regions(), fr_substs.regions().map(|r| r.to_region_vid())); + iter::zip(identity_substs.regions(), fr_substs.regions().map(|r| r.as_var())); UniversalRegionIndices { indices: global_mapping.chain(subst_mapping).collect(), fr_static } } @@ -768,15 +758,10 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for BorrowckInferCtxt<'cx, 'tcx> { T: TypeFoldable<TyCtxt<'tcx>>, { self.infcx.tcx.fold_regions(value, |region, _depth| { - let name = match region.get_name() { - Some(name) => name, - _ => Symbol::intern("anon"), - }; + let name = region.get_name_or_anon(); debug!(?region, ?name); - let reg_var = self.next_nll_region_var(origin, || RegionCtxt::Free(name)); - - reg_var + self.next_nll_region_var(origin, || RegionCtxt::Free(name)) }) } @@ -797,13 +782,13 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for BorrowckInferCtxt<'cx, 'tcx> { let region_vid = { let name = match br.kind.get_name() { Some(name) => name, - _ => Symbol::intern("anon"), + _ => sym::anon, }; self.next_nll_region_var(origin, || RegionCtxt::Bound(BoundRegionInfo::Name(name))) }; - indices.insert_late_bound_region(liberated_region, region_vid.to_region_vid()); + indices.insert_late_bound_region(liberated_region, region_vid.as_var()); debug!(?liberated_region, ?region_vid); region_vid }); @@ -829,18 +814,14 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for BorrowckInferCtxt<'cx, 'tcx> { debug!(?r); if !indices.indices.contains_key(&r) { let region_vid = { - let name = match r.get_name() { - Some(name) => name, - _ => Symbol::intern("anon"), - }; - + let name = r.get_name_or_anon(); self.next_nll_region_var(FR, || { RegionCtxt::LateBound(BoundRegionInfo::Name(name)) }) }; debug!(?region_vid); - indices.insert_late_bound_region(r, region_vid.to_region_vid()); + indices.insert_late_bound_region(r, region_vid.as_var()); } }); } @@ -855,17 +836,13 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for BorrowckInferCtxt<'cx, 'tcx> { debug!(?r); if !indices.indices.contains_key(&r) { let region_vid = { - let name = match r.get_name() { - Some(name) => name, - _ => Symbol::intern("anon"), - }; - + let name = r.get_name_or_anon(); self.next_nll_region_var(FR, || { RegionCtxt::LateBound(BoundRegionInfo::Name(name)) }) }; - indices.insert_late_bound_region(r, region_vid.to_region_vid()); + indices.insert_late_bound_region(r, region_vid.as_var()); } }); } @@ -883,7 +860,7 @@ impl<'tcx> UniversalRegionIndices<'tcx> { } /// Converts `r` into a local inference variable: `r` can either - /// by a `ReVar` (i.e., already a reference to an inference + /// be a `ReVar` (i.e., already a reference to an inference /// variable) or it can be `'static` or some early-bound /// region. This is useful when taking the results from /// type-checking and trait-matching, which may sometimes @@ -892,7 +869,7 @@ impl<'tcx> UniversalRegionIndices<'tcx> { /// fully initialized. pub fn to_region_vid(&self, r: ty::Region<'tcx>) -> RegionVid { if let ty::ReVar(..) = *r { - r.to_region_vid() + r.as_var() } else if r.is_error() { // We use the `'static` `RegionVid` because `ReError` doesn't actually exist in the // `UniversalRegionIndices`. This is fine because 1) it is a fallback only used if diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs index 435a07d8ce7..f0fc61d7c4f 100644 --- a/compiler/rustc_builtin_macros/src/format.rs +++ b/compiler/rustc_builtin_macros/src/format.rs @@ -42,7 +42,7 @@ struct MacroInput { fmtstr: P<Expr>, args: FormatArguments, /// Whether the first argument was a string literal or a result from eager macro expansion. - /// If it's not a string literal, we disallow implicit arugment capturing. + /// If it's not a string literal, we disallow implicit argument capturing. /// /// This does not correspond to whether we can treat spans to the literal normally, as the whole /// invocation might be the result of another macro expansion, in which case this flag may still be true. diff --git a/compiler/rustc_builtin_macros/src/test.rs b/compiler/rustc_builtin_macros/src/test.rs index a76ed4ee6ce..79d8be2484b 100644 --- a/compiler/rustc_builtin_macros/src/test.rs +++ b/compiler/rustc_builtin_macros/src/test.rs @@ -118,34 +118,22 @@ pub fn expand_test_or_bench( } } other => { - cx.struct_span_err( - other.span(), - "`#[test]` attribute is only allowed on non associated functions", - ) - .emit(); + not_testable_error(cx, attr_sp, None); return vec![other]; } }; - // Note: non-associated fn items are already handled by `expand_test_or_bench` let ast::ItemKind::Fn(fn_) = &item.kind else { - let diag = &cx.sess.parse_sess.span_diagnostic; - let msg = "the `#[test]` attribute may only be used on a non-associated function"; - let mut err = match item.kind { - // These were a warning before #92959 and need to continue being that to avoid breaking - // stable user code (#94508). - ast::ItemKind::MacCall(_) => diag.struct_span_warn(attr_sp, msg), - // `.forget_guarantee()` needed to get these two arms to match types. Because of how - // locally close the `.emit()` call is I'm comfortable with it, but if it can be - // reworked in the future to not need it, it'd be nice. - _ => diag.struct_span_err(attr_sp, msg).forget_guarantee(), + not_testable_error(cx, attr_sp, Some(&item)); + return if is_stmt { + vec![Annotatable::Stmt(P(ast::Stmt { + id: ast::DUMMY_NODE_ID, + span: item.span, + kind: ast::StmtKind::Item(item), + }))] + } else { + vec![Annotatable::Item(item)] }; - err.span_label(attr_sp, "the `#[test]` macro causes a function to be run on a test and has no effect on non-functions") - .span_label(item.span, format!("expected a non-associated function, found {} {}", item.kind.article(), item.kind.descr())) - .span_suggestion(attr_sp, "replace with conditional compilation to make the item only exist when tests are being run", "#[cfg(test)]", Applicability::MaybeIncorrect) - .emit(); - - return vec![Annotatable::Item(item)]; }; // has_*_signature will report any errors in the type so compilation @@ -398,6 +386,36 @@ pub fn expand_test_or_bench( } } +fn not_testable_error(cx: &ExtCtxt<'_>, attr_sp: Span, item: Option<&ast::Item>) { + let diag = &cx.sess.parse_sess.span_diagnostic; + let msg = "the `#[test]` attribute may only be used on a non-associated function"; + let mut err = match item.map(|i| &i.kind) { + // These were a warning before #92959 and need to continue being that to avoid breaking + // stable user code (#94508). + Some(ast::ItemKind::MacCall(_)) => diag.struct_span_warn(attr_sp, msg), + // `.forget_guarantee()` needed to get these two arms to match types. Because of how + // locally close the `.emit()` call is I'm comfortable with it, but if it can be + // reworked in the future to not need it, it'd be nice. + _ => diag.struct_span_err(attr_sp, msg).forget_guarantee(), + }; + if let Some(item) = item { + err.span_label( + item.span, + format!( + "expected a non-associated function, found {} {}", + item.kind.article(), + item.kind.descr() + ), + ); + } + err.span_label(attr_sp, "the `#[test]` macro causes a function to be run as a test and has no effect on non-functions") + .span_suggestion(attr_sp, + "replace with conditional compilation to make the item only exist when tests are being run", + "#[cfg(test)]", + Applicability::MaybeIncorrect) + .emit(); +} + fn get_location_info(cx: &ExtCtxt<'_>, item: &ast::Item) -> (Symbol, usize, usize, usize, usize) { let span = item.ident.span; let (source_file, lo_line, lo_col, hi_line, hi_col) = diff --git a/compiler/rustc_codegen_gcc/src/asm.rs b/compiler/rustc_codegen_gcc/src/asm.rs index 41e9d61a10e..65de02b3567 100644 --- a/compiler/rustc_codegen_gcc/src/asm.rs +++ b/compiler/rustc_codegen_gcc/src/asm.rs @@ -593,6 +593,9 @@ fn reg_to_gcc(reg: InlineAsmRegOrRegClass) -> ConstraintOrRegister { InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::reg) => "r", InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::wreg) => "w", InlineAsmRegClass::Hexagon(HexagonInlineAsmRegClass::reg) => "r", + InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg) => "r", + InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg_addr) => "a", + InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg_data) => "d", InlineAsmRegClass::Mips(MipsInlineAsmRegClass::reg) => "d", // more specific than "r" InlineAsmRegClass::Mips(MipsInlineAsmRegClass::freg) => "f", InlineAsmRegClass::Msp430(Msp430InlineAsmRegClass::reg) => "r", @@ -664,6 +667,9 @@ fn dummy_output_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, reg: InlineAsmRegCl InlineAsmRegClass::Avr(_) => unimplemented!(), InlineAsmRegClass::Bpf(_) => unimplemented!(), InlineAsmRegClass::Hexagon(HexagonInlineAsmRegClass::reg) => cx.type_i32(), + InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg) => cx.type_i32(), + InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg_addr) => cx.type_i32(), + InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg_data) => cx.type_i32(), InlineAsmRegClass::Mips(MipsInlineAsmRegClass::reg) => cx.type_i32(), InlineAsmRegClass::Mips(MipsInlineAsmRegClass::freg) => cx.type_f32(), InlineAsmRegClass::Msp430(_) => unimplemented!(), @@ -849,6 +855,7 @@ fn modifier_to_gcc(arch: InlineAsmArch, reg: InlineAsmRegClass, modifier: Option InlineAsmRegClass::Avr(_) => None, InlineAsmRegClass::S390x(_) => None, InlineAsmRegClass::Msp430(_) => None, + InlineAsmRegClass::M68k(_) => None, InlineAsmRegClass::SpirV(SpirVInlineAsmRegClass::reg) => { bug!("LLVM backend does not support SPIR-V") } diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs index e7668341eb6..1a3865360a3 100644 --- a/compiler/rustc_codegen_llvm/src/asm.rs +++ b/compiler/rustc_codegen_llvm/src/asm.rs @@ -244,6 +244,9 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { InlineAsmArch::Msp430 => { constraints.push("~{sr}".to_string()); } + InlineAsmArch::M68k => { + constraints.push("~{ccr}".to_string()); + } } } if !options.contains(InlineAsmOptions::NOMEM) { @@ -671,6 +674,9 @@ fn reg_to_llvm(reg: InlineAsmRegOrRegClass, layout: Option<&TyAndLayout<'_>>) -> InlineAsmRegClass::S390x(S390xInlineAsmRegClass::reg) => "r", InlineAsmRegClass::S390x(S390xInlineAsmRegClass::freg) => "f", InlineAsmRegClass::Msp430(Msp430InlineAsmRegClass::reg) => "r", + InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg) => "r", + InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg_addr) => "a", + InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg_data) => "d", InlineAsmRegClass::SpirV(SpirVInlineAsmRegClass::reg) => { bug!("LLVM backend does not support SPIR-V") } @@ -768,6 +774,7 @@ fn modifier_to_llvm( InlineAsmRegClass::SpirV(SpirVInlineAsmRegClass::reg) => { bug!("LLVM backend does not support SPIR-V") } + InlineAsmRegClass::M68k(_) => None, InlineAsmRegClass::Err => unreachable!(), } } @@ -839,6 +846,9 @@ fn dummy_output_type<'ll>(cx: &CodegenCx<'ll, '_>, reg: InlineAsmRegClass) -> &' InlineAsmRegClass::S390x(S390xInlineAsmRegClass::reg) => cx.type_i32(), InlineAsmRegClass::S390x(S390xInlineAsmRegClass::freg) => cx.type_f64(), InlineAsmRegClass::Msp430(Msp430InlineAsmRegClass::reg) => cx.type_i16(), + InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg) => cx.type_i32(), + InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg_addr) => cx.type_i32(), + InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg_data) => cx.type_i32(), InlineAsmRegClass::SpirV(SpirVInlineAsmRegClass::reg) => { bug!("LLVM backend does not support SPIR-V") } diff --git a/compiler/rustc_codegen_ssa/messages.ftl b/compiler/rustc_codegen_ssa/messages.ftl index 8fe5f8d50ab..243be0e1f70 100644 --- a/compiler/rustc_codegen_ssa/messages.ftl +++ b/compiler/rustc_codegen_ssa/messages.ftl @@ -141,7 +141,7 @@ codegen_ssa_msvc_missing_linker = the msvc targets depend on the msvc linker but codegen_ssa_check_installed_visual_studio = please ensure that Visual Studio 2017 or later, or Build Tools for Visual Studio were installed with the Visual C++ option. -codegen_ssa_unsufficient_vs_code_product = VS Code is a different product, and is not sufficient. +codegen_ssa_insufficient_vs_code_product = VS Code is a different product, and is not sufficient. codegen_ssa_processing_dymutil_failed = processing debug info with `dsymutil` failed: {$status} .note = {$output} diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 7a5fa5a370c..02e21e74fad 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -923,7 +923,7 @@ fn link_natively<'a>( if sess.target.is_like_msvc && linker_not_found { sess.emit_note(errors::MsvcMissingLinker); sess.emit_note(errors::CheckInstalledVisualStudio); - sess.emit_note(errors::UnsufficientVSCodeProduct); + sess.emit_note(errors::InsufficientVSCodeProduct); } sess.abort_if_errors(); } diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index 6dea7496fc3..66e7e314f79 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -405,8 +405,8 @@ pub struct MsvcMissingLinker; pub struct CheckInstalledVisualStudio; #[derive(Diagnostic)] -#[diag(codegen_ssa_unsufficient_vs_code_product)] -pub struct UnsufficientVSCodeProduct; +#[diag(codegen_ssa_insufficient_vs_code_product)] +pub struct InsufficientVSCodeProduct; #[derive(Diagnostic)] #[diag(codegen_ssa_processing_dymutil_failed)] diff --git a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs index 280f0207116..d049bafb821 100644 --- a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs +++ b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs @@ -442,11 +442,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let (var_ty, var_kind) = match var.value { mir::VarDebugInfoContents::Place(place) => { let var_ty = self.monomorphized_place_ty(place.as_ref()); - let var_kind = if self.mir.local_kind(place.local) == mir::LocalKind::Arg + let var_kind = if let Some(arg_index) = var.argument_index && place.projection.is_empty() - && var.source_info.scope == mir::OUTERMOST_SOURCE_SCOPE { - let arg_index = place.local.index() - 1; + let arg_index = arg_index as usize; if target_is_msvc { // ScalarPair parameters are spilled to the stack so they need to // be marked as a `LocalVariable` for MSVC debuggers to visualize @@ -455,13 +454,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { if let Abi::ScalarPair(_, _) = var_ty_layout.abi { VariableKind::LocalVariable } else { - VariableKind::ArgumentVariable(arg_index + 1) + VariableKind::ArgumentVariable(arg_index) } } else { // FIXME(eddyb) shouldn't `ArgumentVariable` indices be // offset in closures to account for the hidden environment? - // Also, is this `+ 1` needed at all? - VariableKind::ArgumentVariable(arg_index + 1) + VariableKind::ArgumentVariable(arg_index) } } else { VariableKind::LocalVariable diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs index 7564ba17b40..4bd6fe19931 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -205,7 +205,7 @@ pub(crate) fn turn_into_const_value<'tcx>( let cid = key.value; let def_id = cid.instance.def.def_id(); let is_static = tcx.is_static(def_id); - // This is just accessing an already computed constant, so no need to check alginment here. + // This is just accessing an already computed constant, so no need to check alignment here. let ecx = mk_eval_cx( tcx, tcx.def_span(key.value.instance.def_id()), diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index 0f56fda18f5..d4bed97380b 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -679,13 +679,21 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { // Unlike `mem::transmute`, a MIR `Transmute` is well-formed // for any two `Sized` types, just potentially UB to run. - if !op_ty.is_sized(self.tcx, self.param_env) { + if !self + .tcx + .normalize_erasing_regions(self.param_env, op_ty) + .is_sized(self.tcx, self.param_env) + { self.fail( location, format!("Cannot transmute from non-`Sized` type {op_ty:?}"), ); } - if !target_type.is_sized(self.tcx, self.param_env) { + if !self + .tcx + .normalize_erasing_regions(self.param_env, *target_type) + .is_sized(self.tcx, self.param_env) + { self.fail( location, format!("Cannot transmute to non-`Sized` type {target_type:?}"), diff --git a/compiler/rustc_data_structures/Cargo.toml b/compiler/rustc_data_structures/Cargo.toml index 24b6b5cfb1f..2102f09c56a 100644 --- a/compiler/rustc_data_structures/Cargo.toml +++ b/compiler/rustc_data_structures/Cargo.toml @@ -33,6 +33,7 @@ tempfile = "3.2" thin-vec = "0.2.12" tracing = "0.1" elsa = "=1.7.1" +itertools = "0.10.1" [dependencies.parking_lot] version = "0.11" diff --git a/compiler/rustc_data_structures/src/sso/either_iter.rs b/compiler/rustc_data_structures/src/sso/either_iter.rs deleted file mode 100644 index bca6c0955b9..00000000000 --- a/compiler/rustc_data_structures/src/sso/either_iter.rs +++ /dev/null @@ -1,73 +0,0 @@ -use std::fmt; -use std::iter::FusedIterator; - -/// Iterator which may contain instance of -/// one of two specific implementations. -/// -/// Note: For most methods providing custom -/// implementation may marginally -/// improve performance by avoiding -/// doing Left/Right match on every step -/// and doing it only once instead. -#[derive(Clone)] -pub enum EitherIter<L, R> { - Left(L), - Right(R), -} - -impl<L, R> Iterator for EitherIter<L, R> -where - L: Iterator, - R: Iterator<Item = L::Item>, -{ - type Item = L::Item; - - fn next(&mut self) -> Option<Self::Item> { - match self { - EitherIter::Left(l) => l.next(), - EitherIter::Right(r) => r.next(), - } - } - - fn size_hint(&self) -> (usize, Option<usize>) { - match self { - EitherIter::Left(l) => l.size_hint(), - EitherIter::Right(r) => r.size_hint(), - } - } -} - -impl<L, R> ExactSizeIterator for EitherIter<L, R> -where - L: ExactSizeIterator, - R: ExactSizeIterator, - EitherIter<L, R>: Iterator, -{ - fn len(&self) -> usize { - match self { - EitherIter::Left(l) => l.len(), - EitherIter::Right(r) => r.len(), - } - } -} - -impl<L, R> FusedIterator for EitherIter<L, R> -where - L: FusedIterator, - R: FusedIterator, - EitherIter<L, R>: Iterator, -{ -} - -impl<L, R> fmt::Debug for EitherIter<L, R> -where - L: fmt::Debug, - R: fmt::Debug, -{ - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - EitherIter::Left(l) => l.fmt(f), - EitherIter::Right(r) => r.fmt(f), - } - } -} diff --git a/compiler/rustc_data_structures/src/sso/map.rs b/compiler/rustc_data_structures/src/sso/map.rs index 7cdac581977..89b8c852649 100644 --- a/compiler/rustc_data_structures/src/sso/map.rs +++ b/compiler/rustc_data_structures/src/sso/map.rs @@ -1,24 +1,24 @@ -use super::either_iter::EitherIter; use crate::fx::FxHashMap; use arrayvec::ArrayVec; +use itertools::Either; use std::fmt; use std::hash::Hash; use std::ops::Index; -// For pointer-sized arguments arrays -// are faster than set/map for up to 64 -// arguments. -// -// On the other hand such a big array -// hurts cache performance, makes passing -// sso structures around very expensive. -// -// Biggest performance benefit is gained -// for reasonably small arrays that stay -// small in vast majority of cases. -// -// '8' is chosen as a sane default, to be -// reevaluated later. +/// For pointer-sized arguments arrays +/// are faster than set/map for up to 64 +/// arguments. +/// +/// On the other hand such a big array +/// hurts cache performance, makes passing +/// sso structures around very expensive. +/// +/// Biggest performance benefit is gained +/// for reasonably small arrays that stay +/// small in vast majority of cases. +/// +/// '8' is chosen as a sane default, to be +/// reevaluated later. const SSO_ARRAY_SIZE: usize = 8; /// Small-storage-optimized implementation of a map. @@ -138,8 +138,8 @@ impl<K, V> SsoHashMap<K, V> { /// The iterator element type is `&'a K`. pub fn keys(&self) -> impl Iterator<Item = &'_ K> { match self { - SsoHashMap::Array(array) => EitherIter::Left(array.iter().map(|(k, _v)| k)), - SsoHashMap::Map(map) => EitherIter::Right(map.keys()), + SsoHashMap::Array(array) => Either::Left(array.iter().map(|(k, _v)| k)), + SsoHashMap::Map(map) => Either::Right(map.keys()), } } @@ -147,8 +147,8 @@ impl<K, V> SsoHashMap<K, V> { /// The iterator element type is `&'a V`. pub fn values(&self) -> impl Iterator<Item = &'_ V> { match self { - SsoHashMap::Array(array) => EitherIter::Left(array.iter().map(|(_k, v)| v)), - SsoHashMap::Map(map) => EitherIter::Right(map.values()), + SsoHashMap::Array(array) => Either::Left(array.iter().map(|(_k, v)| v)), + SsoHashMap::Map(map) => Either::Right(map.values()), } } @@ -156,8 +156,8 @@ impl<K, V> SsoHashMap<K, V> { /// The iterator element type is `&'a mut V`. pub fn values_mut(&mut self) -> impl Iterator<Item = &'_ mut V> { match self { - SsoHashMap::Array(array) => EitherIter::Left(array.iter_mut().map(|(_k, v)| v)), - SsoHashMap::Map(map) => EitherIter::Right(map.values_mut()), + SsoHashMap::Array(array) => Either::Left(array.iter_mut().map(|(_k, v)| v)), + SsoHashMap::Map(map) => Either::Right(map.values_mut()), } } @@ -165,8 +165,8 @@ impl<K, V> SsoHashMap<K, V> { /// allocated memory for reuse. pub fn drain(&mut self) -> impl Iterator<Item = (K, V)> + '_ { match self { - SsoHashMap::Array(array) => EitherIter::Left(array.drain(..)), - SsoHashMap::Map(map) => EitherIter::Right(map.drain()), + SsoHashMap::Array(array) => Either::Left(array.drain(..)), + SsoHashMap::Map(map) => Either::Right(map.drain()), } } } @@ -406,16 +406,16 @@ where } impl<K, V> IntoIterator for SsoHashMap<K, V> { - type IntoIter = EitherIter< - <ArrayVec<(K, V), 8> as IntoIterator>::IntoIter, + type IntoIter = Either< + <ArrayVec<(K, V), SSO_ARRAY_SIZE> as IntoIterator>::IntoIter, <FxHashMap<K, V> as IntoIterator>::IntoIter, >; type Item = <Self::IntoIter as Iterator>::Item; fn into_iter(self) -> Self::IntoIter { match self { - SsoHashMap::Array(array) => EitherIter::Left(array.into_iter()), - SsoHashMap::Map(map) => EitherIter::Right(map.into_iter()), + SsoHashMap::Array(array) => Either::Left(array.into_iter()), + SsoHashMap::Map(map) => Either::Right(map.into_iter()), } } } @@ -435,9 +435,9 @@ fn adapt_array_mut_it<K, V>(pair: &mut (K, V)) -> (&K, &mut V) { } impl<'a, K, V> IntoIterator for &'a SsoHashMap<K, V> { - type IntoIter = EitherIter< + type IntoIter = Either< std::iter::Map< - <&'a ArrayVec<(K, V), 8> as IntoIterator>::IntoIter, + <&'a ArrayVec<(K, V), SSO_ARRAY_SIZE> as IntoIterator>::IntoIter, fn(&'a (K, V)) -> (&'a K, &'a V), >, <&'a FxHashMap<K, V> as IntoIterator>::IntoIter, @@ -446,16 +446,16 @@ impl<'a, K, V> IntoIterator for &'a SsoHashMap<K, V> { fn into_iter(self) -> Self::IntoIter { match self { - SsoHashMap::Array(array) => EitherIter::Left(array.into_iter().map(adapt_array_ref_it)), - SsoHashMap::Map(map) => EitherIter::Right(map.iter()), + SsoHashMap::Array(array) => Either::Left(array.into_iter().map(adapt_array_ref_it)), + SsoHashMap::Map(map) => Either::Right(map.iter()), } } } impl<'a, K, V> IntoIterator for &'a mut SsoHashMap<K, V> { - type IntoIter = EitherIter< + type IntoIter = Either< std::iter::Map< - <&'a mut ArrayVec<(K, V), 8> as IntoIterator>::IntoIter, + <&'a mut ArrayVec<(K, V), SSO_ARRAY_SIZE> as IntoIterator>::IntoIter, fn(&'a mut (K, V)) -> (&'a K, &'a mut V), >, <&'a mut FxHashMap<K, V> as IntoIterator>::IntoIter, @@ -464,8 +464,8 @@ impl<'a, K, V> IntoIterator for &'a mut SsoHashMap<K, V> { fn into_iter(self) -> Self::IntoIter { match self { - SsoHashMap::Array(array) => EitherIter::Left(array.into_iter().map(adapt_array_mut_it)), - SsoHashMap::Map(map) => EitherIter::Right(map.iter_mut()), + SsoHashMap::Array(array) => Either::Left(array.into_iter().map(adapt_array_mut_it)), + SsoHashMap::Map(map) => Either::Right(map.iter_mut()), } } } diff --git a/compiler/rustc_data_structures/src/sso/mod.rs b/compiler/rustc_data_structures/src/sso/mod.rs index dd21bc8e696..ef634b9adce 100644 --- a/compiler/rustc_data_structures/src/sso/mod.rs +++ b/compiler/rustc_data_structures/src/sso/mod.rs @@ -1,4 +1,3 @@ -mod either_iter; mod map; mod set; diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 730d41ab962..b9f0e756e65 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -5,7 +5,6 @@ //! This API is completely unstable and subject to change. #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![feature(is_terminal)] #![feature(lazy_cell)] #![feature(decl_macro)] #![recursion_limit = "256"] @@ -37,7 +36,7 @@ use rustc_metadata::locator; use rustc_session::config::{nightly_options, CG_OPTIONS, Z_OPTIONS}; use rustc_session::config::{ErrorOutputType, Input, OutputType, PrintRequest, TrimmedDefPaths}; use rustc_session::cstore::MetadataLoader; -use rustc_session::getopts; +use rustc_session::getopts::{self, Matches}; use rustc_session::lint::{Lint, LintId}; use rustc_session::{config, Session}; use rustc_session::{early_error, early_error_no_abort, early_warn}; @@ -956,6 +955,46 @@ Available lint options: } } +/// Show help for flag categories shared between rustdoc and rustc. +/// +/// Returns whether a help option was printed. +pub fn describe_flag_categories(matches: &Matches) -> bool { + // Handle the special case of -Wall. + let wall = matches.opt_strs("W"); + if wall.iter().any(|x| *x == "all") { + print_wall_help(); + rustc_errors::FatalError.raise(); + } + + // Don't handle -W help here, because we might first load plugins. + let debug_flags = matches.opt_strs("Z"); + if debug_flags.iter().any(|x| *x == "help") { + describe_debug_flags(); + return true; + } + + let cg_flags = matches.opt_strs("C"); + if cg_flags.iter().any(|x| *x == "help") { + describe_codegen_flags(); + return true; + } + + if cg_flags.iter().any(|x| *x == "no-stack-check") { + early_warn( + ErrorOutputType::default(), + "the --no-stack-check flag is deprecated and does nothing", + ); + } + + if cg_flags.iter().any(|x| *x == "passes=list") { + let backend_name = debug_flags.iter().find_map(|x| x.strip_prefix("codegen-backend=")); + get_codegen_backend(&None, backend_name).print_passes(); + return true; + } + + false +} + fn describe_debug_flags() { println!("\nAvailable options:\n"); print_flag_list("-Z", config::Z_OPTIONS); @@ -966,7 +1005,7 @@ fn describe_codegen_flags() { print_flag_list("-C", config::CG_OPTIONS); } -pub fn print_flag_list<T>( +fn print_flag_list<T>( cmdline_opt: &str, flag_list: &[(&'static str, T, &'static str, &'static str)], ) { @@ -1059,37 +1098,7 @@ pub fn handle_options(args: &[String]) -> Option<getopts::Matches> { return None; } - // Handle the special case of -Wall. - let wall = matches.opt_strs("W"); - if wall.iter().any(|x| *x == "all") { - print_wall_help(); - rustc_errors::FatalError.raise(); - } - - // Don't handle -W help here, because we might first load plugins. - let debug_flags = matches.opt_strs("Z"); - if debug_flags.iter().any(|x| *x == "help") { - describe_debug_flags(); - return None; - } - - let cg_flags = matches.opt_strs("C"); - - if cg_flags.iter().any(|x| *x == "help") { - describe_codegen_flags(); - return None; - } - - if cg_flags.iter().any(|x| *x == "no-stack-check") { - early_warn( - ErrorOutputType::default(), - "the --no-stack-check flag is deprecated and does nothing", - ); - } - - if cg_flags.iter().any(|x| *x == "passes=list") { - let backend_name = debug_flags.iter().find_map(|x| x.strip_prefix("codegen-backend=")); - get_codegen_backend(&None, backend_name).print_passes(); + if describe_flag_categories(&matches) { return None; } diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 81e8bcbf7cd..fe44799efdb 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -1832,6 +1832,12 @@ impl EmitterWriter { } let show_code_change = if has_deletion && !is_multiline { DisplaySuggestion::Diff + } else if let [part] = &parts[..] + && part.snippet.ends_with('\n') + && part.snippet.trim() == complete.trim() + { + // We are adding a line(s) of code before code that was already there. + DisplaySuggestion::Add } else if (parts.len() != 1 || parts[0].snippet.trim() != complete.trim()) && !is_multiline { @@ -1879,7 +1885,10 @@ impl EmitterWriter { row_num += line_end - line_start; } let mut unhighlighted_lines = Vec::new(); + let mut last_pos = 0; + let mut is_item_attribute = false; for (line_pos, (line, highlight_parts)) in lines.by_ref().zip(highlights).enumerate() { + last_pos = line_pos; debug!(%line_pos, %line, ?highlight_parts); // Remember lines that are not highlighted to hide them if needed @@ -1887,6 +1896,12 @@ impl EmitterWriter { unhighlighted_lines.push((line_pos, line)); continue; } + if highlight_parts.len() == 1 + && line.trim().starts_with("#[") + && line.trim().ends_with(']') + { + is_item_attribute = true; + } match unhighlighted_lines.len() { 0 => (), @@ -1963,13 +1978,41 @@ impl EmitterWriter { is_multiline, ) } + if let DisplaySuggestion::Add = show_code_change && is_item_attribute { + // The suggestion adds an entire line of code, ending on a newline, so we'll also + // print the *following* line, to provide context of what we're advicing people to + // do. Otherwise you would only see contextless code that can be confused for + // already existing code, despite the colors and UI elements. + // We special case `#[derive(_)]\n` and other attribute suggestions, because those + // are the ones where context is most useful. + let file_lines = sm + .span_to_lines(span.primary_span().unwrap().shrink_to_hi()) + .expect("span_to_lines failed when emitting suggestion"); + let line_num = sm.lookup_char_pos(parts[0].span.lo()).line; + if let Some(line) = file_lines.file.get_line(line_num - 1) { + let line = normalize_whitespace(&line); + self.draw_code_line( + &mut buffer, + &mut row_num, + &[], + line_num + last_pos + 1, + &line, + DisplaySuggestion::None, + max_line_num_len, + &file_lines, + is_multiline, + ) + } + } // This offset and the ones below need to be signed to account for replacement code // that is shorter than the original code. let mut offsets: Vec<(usize, isize)> = Vec::new(); // Only show an underline in the suggestions if the suggestion is not the // entirety of the code being shown and the displayed code is not multiline. - if let DisplaySuggestion::Diff | DisplaySuggestion::Underline = show_code_change { + if let DisplaySuggestion::Diff | DisplaySuggestion::Underline | DisplaySuggestion::Add = + show_code_change + { draw_col_separator_no_space(&mut buffer, row_num, max_line_num_len + 1); for part in parts { let span_start_pos = sm.lookup_char_pos(part.span.lo()).col_display; @@ -2247,6 +2290,10 @@ impl EmitterWriter { } } buffer.append(*row_num, &normalize_whitespace(line_to_add), Style::NoStyle); + } else if let DisplaySuggestion::Add = show_code_change { + buffer.puts(*row_num, 0, &self.maybe_anonymized(line_num), Style::LineNumber); + buffer.puts(*row_num, max_line_num_len + 1, "+ ", Style::Addition); + buffer.append(*row_num, &normalize_whitespace(line_to_add), Style::NoStyle); } else { buffer.puts(*row_num, 0, &self.maybe_anonymized(line_num), Style::LineNumber); draw_col_separator(buffer, *row_num, max_line_num_len + 1); @@ -2281,6 +2328,7 @@ enum DisplaySuggestion { Underline, Diff, None, + Add, } impl FileWithAnnotatedLines { diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 5b0d8096207..d20b168904d 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -6,7 +6,6 @@ #![feature(array_windows)] #![feature(drain_filter)] #![feature(if_let_guard)] -#![feature(is_terminal)] #![feature(adt_const_params)] #![feature(let_chains)] #![feature(never_type)] @@ -475,8 +474,6 @@ pub enum StashKey { /// When an invalid lifetime e.g. `'2` should be reinterpreted /// as a char literal in the parser LifetimeIsChar, - /// When an invalid lifetime e.g. `'🐱` contains emoji. - LifetimeContainsEmoji, /// Maybe there was a typo where a comma was forgotten before /// FRU syntax MaybeFruTypo, diff --git a/compiler/rustc_expand/messages.ftl b/compiler/rustc_expand/messages.ftl index cfae781bdee..5d999d0db5d 100644 --- a/compiler/rustc_expand/messages.ftl +++ b/compiler/rustc_expand/messages.ftl @@ -135,4 +135,4 @@ expand_proc_macro_panicked = .help = message: {$message} expand_proc_macro_derive_tokens = - proc-macro derive produced unparseable tokens + proc-macro derive produced unparsable tokens diff --git a/compiler/rustc_expand/src/mbe/diagnostics.rs b/compiler/rustc_expand/src/mbe/diagnostics.rs index 6bc393c6534..35572292271 100644 --- a/compiler/rustc_expand/src/mbe/diagnostics.rs +++ b/compiler/rustc_expand/src/mbe/diagnostics.rs @@ -66,7 +66,12 @@ pub(super) fn failed_to_match_macro<'cx>( && (matches!(expected_token.kind, TokenKind::Interpolated(_)) || matches!(token.kind, TokenKind::Interpolated(_))) { - err.note("captured metavariables except for `$tt`, `$ident` and `$lifetime` cannot be compared to other tokens"); + err.note("captured metavariables except for `:tt`, `:ident` and `:lifetime` cannot be compared to other tokens"); + err.note("see <https://doc.rust-lang.org/nightly/reference/macros-by-example.html#forwarding-a-matched-fragment> for more information"); + + if !def_span.is_dummy() && !cx.source_map().is_imported(def_span) { + err.help("try using `:tt` instead in the macro definition"); + } } // Check whether there's a missing comma in this macro call, like `println!("{}" a);` diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index 426c6727adc..48f5bd1cb50 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -309,7 +309,7 @@ declare_features! ( (active, associated_type_defaults, "1.2.0", Some(29661), None), /// Allows `async || body` closures. (active, async_closure, "1.37.0", Some(62290), None), - /// Alows async functions to be declared, implemented, and used in traits. + /// Allows async functions to be declared, implemented, and used in traits. (incomplete, async_fn_in_trait, "1.66.0", Some(91611), None), /// Allows `extern "C-unwind" fn` to enable unwinding across ABI boundaries. (active, c_unwind, "1.52.0", Some(74990), None), @@ -416,6 +416,8 @@ declare_features! ( (active, half_open_range_patterns_in_slices, "1.66.0", Some(67264), None), /// Allows `if let` guard in match arms. (active, if_let_guard, "1.47.0", Some(51114), None), + /// Allows `impl Trait` to be used inside associated types (RFC 2515). + (active, impl_trait_in_assoc_type, "CURRENT_RUSTC_VERSION", Some(63063), None), /// Allows `impl Trait` as output type in `Fn` traits in return position of functions. (active, impl_trait_in_fn_trait_return, "1.64.0", Some(99697), None), /// Allows referencing `Self` and projections in impl-trait. diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 8cb95610da0..8d1156c1771 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -2520,24 +2520,16 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { tcx, infcx.fresh_substs_for_item(DUMMY_SP, impl_def_id), ); - // I guess we don't need to make a universe unless we need it, - // but also we're on the error path, so it doesn't matter here. - let universe = infcx.create_next_universe(); + let value = tcx.fold_regions(qself_ty, |_, _| tcx.lifetimes.re_erased); + // FIXME: Don't bother dealing with non-lifetime binders here... + if value.has_escaping_bound_vars() { + return false; + } infcx .can_eq( ty::ParamEnv::empty(), impl_.self_ty(), - tcx.replace_escaping_bound_vars_uncached(qself_ty, ty::fold::FnMutDelegate { - regions: &mut |_| tcx.lifetimes.re_erased, - types: &mut |bv| tcx.mk_placeholder(ty::PlaceholderType { - universe, - bound: bv, - }), - consts: &mut |bv, ty| tcx.mk_const(ty::PlaceholderConst { - universe, - bound: bv, - }, ty), - }) + value, ) }) && tcx.impl_polarity(impl_def_id) != ty::ImplPolarity::Negative diff --git a/compiler/rustc_hir_analysis/src/bounds.rs b/compiler/rustc_hir_analysis/src/bounds.rs index 0880c8c15f2..284b099e7bc 100644 --- a/compiler/rustc_hir_analysis/src/bounds.rs +++ b/compiler/rustc_hir_analysis/src/bounds.rs @@ -58,7 +58,7 @@ impl<'tcx> Bounds<'tcx> { pub fn push_sized(&mut self, tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, span: Span) { let sized_def_id = tcx.require_lang_item(LangItem::Sized, Some(span)); let trait_ref = ty::Binder::dummy(tcx.mk_trait_ref(sized_def_id, [ty])); - // Preferrable to put this obligation first, since we report better errors for sized ambiguity. + // Preferable to put this obligation first, since we report better errors for sized ambiguity. self.predicates.insert(0, (trait_ref.without_const().to_predicate(tcx), span)); } diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 8617bca0825..0bb98fdf2a2 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -452,11 +452,8 @@ fn check_opaque_meets_bounds<'tcx>( hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..) => {} // Can have different predicates to their defining use hir::OpaqueTyOrigin::TyAlias => { - let outlives_environment = OutlivesEnvironment::new(param_env); - let _ = infcx.err_ctxt().check_region_obligations_and_report_errors( - defining_use_anchor, - &outlives_environment, - ); + let outlives_env = OutlivesEnvironment::new(param_env); + let _ = ocx.resolve_regions_and_report_errors(defining_use_anchor, &outlives_env); } } // Clean up after ourselves diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index f6c2004c4a6..5d119a7737a 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -332,10 +332,6 @@ fn compare_method_predicate_entailment<'tcx>( param_env, infcx.implied_bounds_tys(param_env, impl_m_def_id, wf_tys.clone()), ); - infcx.process_registered_region_obligations( - outlives_env.region_bound_pairs(), - outlives_env.param_env, - ); let errors = infcx.resolve_regions(&outlives_env); if !errors.is_empty() { // FIXME(compiler-errors): This can be simplified when IMPLIED_BOUNDS_ENTAILMENT @@ -722,18 +718,18 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>( return Err(reported); } + let collected_types = collector.types; + // Finally, resolve all regions. This catches wily misuses of // lifetime parameters. - let outlives_environment = OutlivesEnvironment::with_bounds( + let outlives_env = OutlivesEnvironment::with_bounds( param_env, infcx.implied_bounds_tys(param_env, impl_m_def_id, wf_tys), ); - infcx - .err_ctxt() - .check_region_obligations_and_report_errors(impl_m_def_id, &outlives_environment)?; + ocx.resolve_regions_and_report_errors(impl_m_def_id, &outlives_env)?; let mut collected_tys = FxHashMap::default(); - for (def_id, (ty, substs)) in collector.types { + for (def_id, (ty, substs)) in collected_types { match infcx.fully_resolve(ty) { Ok(ty) => { // `ty` contains free regions that we created earlier while liberating the @@ -1742,11 +1738,8 @@ pub(super) fn compare_impl_const_raw( return Err(infcx.err_ctxt().report_fulfillment_errors(&errors)); } - let outlives_environment = OutlivesEnvironment::new(param_env); - infcx - .err_ctxt() - .check_region_obligations_and_report_errors(impl_const_item_def, &outlives_environment)?; - Ok(()) + let outlives_env = OutlivesEnvironment::new(param_env); + ocx.resolve_regions_and_report_errors(impl_const_item_def, &outlives_env) } pub(super) fn compare_impl_ty<'tcx>( @@ -1845,13 +1838,8 @@ fn compare_type_predicate_entailment<'tcx>( // Finally, resolve all regions. This catches wily misuses of // lifetime parameters. - let outlives_environment = OutlivesEnvironment::new(param_env); - infcx.err_ctxt().check_region_obligations_and_report_errors( - impl_ty.def_id.expect_local(), - &outlives_environment, - )?; - - Ok(()) + let outlives_env = OutlivesEnvironment::new(param_env); + ocx.resolve_regions_and_report_errors(impl_ty_def_id, &outlives_env) } /// Validate that `ProjectionCandidate`s created for this associated type will @@ -2063,14 +2051,8 @@ pub(super) fn check_type_bounds<'tcx>( // Finally, resolve all regions. This catches wily misuses of // lifetime parameters. let implied_bounds = infcx.implied_bounds_tys(param_env, impl_ty_def_id, assumed_wf_types); - let outlives_environment = OutlivesEnvironment::with_bounds(param_env, implied_bounds); - - infcx.err_ctxt().check_region_obligations_and_report_errors( - impl_ty.def_id.expect_local(), - &outlives_environment, - )?; - - Ok(()) + let outlives_env = OutlivesEnvironment::with_bounds(param_env, implied_bounds); + ocx.resolve_regions_and_report_errors(impl_ty_def_id, &outlives_env) } fn assoc_item_kind_str(impl_item: &ty::AssocItem) -> &'static str { diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index c03621fcfb2..53197bc8491 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -114,11 +114,9 @@ pub(super) fn enter_wf_checking_ctxt<'tcx, F>( return; } - let outlives_environment = OutlivesEnvironment::with_bounds(param_env, implied_bounds); + let outlives_env = OutlivesEnvironment::with_bounds(param_env, implied_bounds); - let _ = infcx - .err_ctxt() - .check_region_obligations_and_report_errors(body_def_id, &outlives_environment); + let _ = wfcx.ocx.resolve_regions_and_report_errors(body_def_id, &outlives_env); } fn check_well_formed(tcx: TyCtxt<'_>, def_id: hir::OwnerId) { @@ -680,12 +678,7 @@ fn resolve_regions_with_wf_tys<'tcx>( add_constraints(&infcx, region_bound_pairs); - infcx.process_registered_region_obligations( - outlives_environment.region_bound_pairs(), - param_env, - ); let errors = infcx.resolve_regions(&outlives_environment); - debug!(?errors, "errors"); // If we were able to prove that the type outlives the region without diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index ac7c68d9c4b..0f40cca9427 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -354,9 +354,7 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef // Finally, resolve all regions. let outlives_env = OutlivesEnvironment::new(param_env); - let _ = infcx - .err_ctxt() - .check_region_obligations_and_report_errors(impl_did, &outlives_env); + let _ = ocx.resolve_regions_and_report_errors(impl_did, &outlives_env); } } _ => { @@ -592,7 +590,7 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: LocalDefId) -> Coe // Finally, resolve all regions. let outlives_env = OutlivesEnvironment::new(param_env); - let _ = infcx.err_ctxt().check_region_obligations_and_report_errors(impl_did, &outlives_env); + let _ = ocx.resolve_regions_and_report_errors(impl_did, &outlives_env); CoerceUnsizedInfo { custom_kind: kind } } diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index 225b1550580..c173bd913a8 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -8,10 +8,7 @@ use rustc_middle::hir::nested_filter; use rustc_middle::ty::print::with_forced_trimmed_paths; use rustc_middle::ty::subst::InternalSubsts; use rustc_middle::ty::util::IntTypeExt; -use rustc_middle::ty::{ - self, ImplTraitInTraitData, IsSuggestable, Ty, TyCtxt, TypeFolder, TypeSuperFoldable, - TypeVisitableExt, -}; +use rustc_middle::ty::{self, ImplTraitInTraitData, IsSuggestable, Ty, TyCtxt, TypeVisitableExt}; use rustc_span::symbol::Ident; use rustc_span::{Span, DUMMY_SP}; @@ -874,28 +871,6 @@ fn infer_placeholder_type<'a>( item_ident: Ident, kind: &'static str, ) -> Ty<'a> { - // Attempts to make the type nameable by turning FnDefs into FnPtrs. - struct MakeNameable<'tcx> { - tcx: TyCtxt<'tcx>, - } - - impl<'tcx> TypeFolder<TyCtxt<'tcx>> for MakeNameable<'tcx> { - fn interner(&self) -> TyCtxt<'tcx> { - self.tcx - } - - fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { - let ty = match *ty.kind() { - ty::FnDef(def_id, substs) => { - self.tcx.mk_fn_ptr(self.tcx.fn_sig(def_id).subst(self.tcx, substs)) - } - _ => ty, - }; - - ty.super_fold_with(self) - } - } - let ty = tcx.diagnostic_only_typeck(def_id).node_type(body_id.hir_id); // If this came from a free `const` or `static mut?` item, diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs index 35785e81ff4..eb2fc395223 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs @@ -180,8 +180,7 @@ fn get_impl_substs( let implied_bounds = infcx.implied_bounds_tys(param_env, impl1_def_id, assumed_wf_types); let outlives_env = OutlivesEnvironment::with_bounds(param_env, implied_bounds); - let _ = - infcx.err_ctxt().check_region_obligations_and_report_errors(impl1_def_id, &outlives_env); + let _ = ocx.resolve_regions_and_report_errors(impl1_def_id, &outlives_env); let Ok(impl2_substs) = infcx.fully_resolve(impl2_substs) else { let span = tcx.def_span(impl1_def_id); tcx.sess.emit_err(SubstsOnOverriddenImpl { span }); diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 30d307948a6..a4c3be1d177 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -308,7 +308,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let rcvr_ty = self.node_ty(rcvr.hir_id); // Get the evaluated type *after* calling the method call, so that the influence // of the arguments can be reflected in the receiver type. The receiver - // expression has the type *before* theis analysis is done. + // expression has the type *before* this analysis is done. let ty = match self.lookup_probe_for_diagnostic( segment.ident, rcvr_ty, diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 68e096e3bd0..6ffa0134f3d 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -120,7 +120,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty } - pub(super) fn check_expr_coercable_to_type( + pub(super) fn check_expr_coercible_to_type( &self, expr: &'tcx hir::Expr<'tcx>, expected: Ty<'tcx>, @@ -1128,7 +1128,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } }; - // This is (basically) inlined `check_expr_coercable_to_type`, but we want + // This is (basically) inlined `check_expr_coercible_to_type`, but we want // to suggest an additional fixup here in `suggest_deref_binop`. let rhs_ty = self.check_expr_with_hint(&rhs, lhs_ty); if let (_, Some(mut diag)) = @@ -1401,7 +1401,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let (element_ty, t) = match uty { Some(uty) => { - self.check_expr_coercable_to_type(&element, uty, None); + self.check_expr_coercible_to_type(&element, uty, None); (uty, uty) } None => { @@ -1478,7 +1478,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let elt_ts_iter = elts.iter().enumerate().map(|(i, e)| match flds { Some(fs) if i < fs.len() => { let ety = fs[i]; - self.check_expr_coercable_to_type(&e, ety, None); + self.check_expr_coercible_to_type(&e, ety, None); ety } _ => self.check_expr_with_expectation(&e, NoExpectation), @@ -2869,7 +2869,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) -> Ty<'tcx> { match self.resume_yield_tys { Some((resume_ty, yield_ty)) => { - self.check_expr_coercable_to_type(&value, yield_ty, None); + self.check_expr_coercible_to_type(&value, yield_ty, None); resume_ty } @@ -2878,7 +2878,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // information. Hence, we check the source of the yield expression here and check its // value's type against `()` (this check should always hold). None if src.is_await() => { - self.check_expr_coercable_to_type(&value, self.tcx.mk_unit(), None); + self.check_expr_coercible_to_type(&value, self.tcx.mk_unit(), None); self.tcx.mk_unit() } _ => { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index fdf178c3ea7..f736f7a9620 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -578,7 +578,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { #[instrument(skip(self), level = "debug")] pub(in super::super) fn report_ambiguity_errors(&self) { - let mut errors = self.fulfillment_cx.borrow_mut().collect_remaining_errors(); + let mut errors = self.fulfillment_cx.borrow_mut().collect_remaining_errors(self); if !errors.is_empty() { self.adjust_fulfillment_errors_for_expr_obligation(&mut errors); diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs index 3e0c2bf2a55..f879ccbb3af 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs @@ -78,7 +78,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Finally, for ambiguity-related errors, we actually want to look // for a parameter that is the source of the inference type left // over in this predicate. - if let traits::FulfillmentErrorCode::CodeAmbiguity = error.code { + if let traits::FulfillmentErrorCode::CodeAmbiguity { .. } = error.code { fallback_param_to_point_at = None; self_param_to_point_at = None; param_to_point_at = @@ -466,7 +466,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// obligation. Hence we refine the `expr` "outwards-in" and bail at the first kind of expression/impl we don't recognize. /// /// This function returns a `Result<&Expr, &Expr>` - either way, it returns the `Expr` whose span should be - /// reported as an error. If it is `Ok`, then it means it refined successfull. If it is `Err`, then it may be + /// reported as an error. If it is `Ok`, then it means it refined successful. If it is `Err`, then it may be /// only a partial success - but it cannot be refined even further. fn blame_specific_expr_if_possible_for_derived_predicate_obligation( &self, @@ -534,7 +534,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// - in_ty: `(Option<Vec<T>, bool)` /// we would drill until we arrive at `vec![1, 2, 3]`. /// - /// If successful, we return `Ok(refined_expr)`. If unsuccesful, we return `Err(partially_refined_expr`), + /// If successful, we return `Ok(refined_expr)`. If unsuccessful, we return `Err(partially_refined_expr`), /// which will go as far as possible. For example, given `(foo(), false)` instead, we would drill to /// `foo()` and then return `Err("foo()")`. /// diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index cf93d1d2182..a009ae5d44e 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -1413,7 +1413,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.demand_eqtype(init.span, local_ty, init_ty); init_ty } else { - self.check_expr_coercable_to_type(init, local_ty, None) + self.check_expr_coercible_to_type(init, local_ty, None) } } diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 6af095cb4d4..45890abad92 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -280,7 +280,7 @@ fn typeck_with_fallback<'tcx>( // Gather locals in statics (because of block expressions). GatherLocalsVisitor::new(&fcx).visit_body(body); - fcx.check_expr_coercable_to_type(&body.value, expected_type, None); + fcx.check_expr_coercible_to_type(&body.value, expected_type, None); fcx.write_ty(id, expected_type); }; diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 08cd6085d7f..4fd778910ba 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -1531,23 +1531,18 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { // Convert the bounds into obligations. let impl_obligations = traits::predicates_for_generics( - |_idx, span| { - let misc = traits::ObligationCause::misc(span, self.body_id); - let parent_trait_pred = ty::Binder::dummy(ty::TraitPredicate { - trait_ref: ty::TraitRef::from_method(self.tcx, impl_def_id, substs), - constness: ty::BoundConstness::NotConst, - polarity: ty::ImplPolarity::Positive, - }); - misc.derived_cause(parent_trait_pred, |derived| { - traits::ImplDerivedObligation(Box::new( - traits::ImplDerivedObligationCause { - derived, - impl_or_alias_def_id: impl_def_id, - impl_def_predicate_index: None, - span, - }, - )) - }) + |idx, span| { + let code = if span.is_dummy() { + traits::ExprItemObligation(impl_def_id, self.scope_expr_id, idx) + } else { + traits::ExprBindingObligation( + impl_def_id, + span, + self.scope_expr_id, + idx, + ) + }; + ObligationCause::new(self.span, self.body_id, code) }, self.param_env, impl_bounds, diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 5c50619f4c3..900a6fa0d8d 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -300,7 +300,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; // We could pass the file for long types into these two, but it isn't strictly necessary - // given how targetted they are. + // given how targeted they are. if self.suggest_wrapping_range_with_parens( tcx, rcvr_ty, @@ -661,19 +661,26 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Find all the requirements that come from a local `impl` block. let mut skip_list: FxHashSet<_> = Default::default(); let mut spanned_predicates = FxHashMap::default(); - for (p, parent_p, impl_def_id, cause) in unsatisfied_predicates - .iter() - .filter_map(|(p, parent, c)| c.as_ref().map(|c| (p, parent, c))) - .filter_map(|(p, parent, c)| match c.code() { - ObligationCauseCode::ImplDerivedObligation(data) - if matches!(p.kind().skip_binder(), ty::PredicateKind::Clause(_)) => - { - Some((p, parent, data.impl_or_alias_def_id, data)) + for (p, parent_p, cause) in unsatisfied_predicates { + // Extract the predicate span and parent def id of the cause, + // if we have one. + let (item_def_id, cause_span) = match cause.as_ref().map(|cause| cause.code()) { + Some(ObligationCauseCode::ImplDerivedObligation(data)) => { + (data.impl_or_alias_def_id, data.span) } - _ => None, - }) - { - match self.tcx.hir().get_if_local(impl_def_id) { + Some( + ObligationCauseCode::ExprBindingObligation(def_id, span, _, _) + | ObligationCauseCode::BindingObligation(def_id, span), + ) => (*def_id, *span), + _ => continue, + }; + + // Don't point out the span of `WellFormed` predicates. + if !matches!(p.kind().skip_binder(), ty::PredicateKind::Clause(_)) { + continue; + }; + + match self.tcx.hir().get_if_local(item_def_id) { // Unmet obligation comes from a `derive` macro, point at it once to // avoid multiple span labels pointing at the same place. Some(Node::Item(hir::Item { @@ -718,7 +725,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } }); for param in generics.params { - if param.span == cause.span && sized_pred { + if param.span == cause_span && sized_pred { let (sp, sugg) = match param.colon_span { Some(sp) => (sp.shrink_to_hi(), " ?Sized +"), None => (param.span.shrink_to_hi(), ": ?Sized"), @@ -741,9 +748,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { (FxHashSet::default(), FxHashSet::default(), Vec::new()) }); entry.2.push(p); - if cause.span != *item_span { - entry.0.insert(cause.span); - entry.1.insert((cause.span, "unsatisfied trait bound introduced here")); + if cause_span != *item_span { + entry.0.insert(cause_span); + entry.1.insert((cause_span, "unsatisfied trait bound introduced here")); } else { if let Some(trait_ref) = of_trait { entry.0.insert(trait_ref.path.span); @@ -775,9 +782,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let entry = entry.or_insert_with(|| { (FxHashSet::default(), FxHashSet::default(), Vec::new()) }); - entry.0.insert(cause.span); + entry.0.insert(cause_span); entry.1.insert((ident.span, "")); - entry.1.insert((cause.span, "unsatisfied trait bound introduced here")); + entry.1.insert((cause_span, "unsatisfied trait bound introduced here")); entry.2.push(p); } Some(node) => unreachable!("encountered `{node:?}`"), diff --git a/compiler/rustc_hir_typeck/src/op.rs b/compiler/rustc_hir_typeck/src/op.rs index 8a83bb58573..a52c94cb00c 100644 --- a/compiler/rustc_hir_typeck/src/op.rs +++ b/compiler/rustc_hir_typeck/src/op.rs @@ -12,9 +12,7 @@ use rustc_middle::ty::adjustment::{ Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, }; use rustc_middle::ty::print::with_no_trimmed_paths; -use rustc_middle::ty::{ - self, IsSuggestable, Ty, TyCtxt, TypeFolder, TypeSuperFoldable, TypeVisitableExt, -}; +use rustc_middle::ty::{self, IsSuggestable, Ty, TyCtxt, TypeVisitableExt}; use rustc_session::errors::ExprParenthesesNeeded; use rustc_span::source_map::Spanned; use rustc_span::symbol::{sym, Ident}; @@ -103,9 +101,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { match BinOpCategory::from(op) { BinOpCategory::Shortcircuit => { // && and || are a simple case. - self.check_expr_coercable_to_type(lhs_expr, tcx.types.bool, None); + self.check_expr_coercible_to_type(lhs_expr, tcx.types.bool, None); let lhs_diverges = self.diverges.get(); - self.check_expr_coercable_to_type(rhs_expr, tcx.types.bool, None); + self.check_expr_coercible_to_type(rhs_expr, tcx.types.bool, None); // Depending on the LHS' value, the RHS can never execute. self.diverges.set(lhs_diverges); @@ -255,7 +253,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); // see `NB` above - let rhs_ty = self.check_expr_coercable_to_type(rhs_expr, rhs_ty_var, Some(lhs_expr)); + let rhs_ty = self.check_expr_coercible_to_type(rhs_expr, rhs_ty_var, Some(lhs_expr)); let rhs_ty = self.resolve_vars_with_obligations(rhs_ty); let return_ty = match result { @@ -965,21 +963,3 @@ fn is_builtin_binop<'tcx>(lhs: Ty<'tcx>, rhs: Ty<'tcx>, op: hir::BinOp) -> bool } } } - -struct TypeParamEraser<'a, 'tcx>(&'a FnCtxt<'a, 'tcx>, Span); - -impl<'tcx> TypeFolder<TyCtxt<'tcx>> for TypeParamEraser<'_, 'tcx> { - fn interner(&self) -> TyCtxt<'tcx> { - self.0.tcx - } - - fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { - match ty.kind() { - ty::Param(_) => self.0.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::MiscVariable, - span: self.1, - }), - _ => ty.super_fold_with(self), - } - } -} diff --git a/compiler/rustc_infer/messages.ftl b/compiler/rustc_infer/messages.ftl index 4d4a7880b00..c8998ea91bf 100644 --- a/compiler/rustc_infer/messages.ftl +++ b/compiler/rustc_infer/messages.ftl @@ -163,7 +163,6 @@ infer_region_explanation = {$pref_kind -> [as_defined] the lifetime `{$desc_arg}` as defined here [as_defined_anon] the anonymous lifetime as defined here [defined_here] the anonymous lifetime defined here - [anon_num_here] the anonymous lifetime #{$desc_num_arg} defined here [defined_here_reg] the lifetime `{$desc_arg}` as defined here }{$suff_kind -> *[should_not_happen] [{$suff_kind}] @@ -174,7 +173,7 @@ infer_region_explanation = {$pref_kind -> infer_outlives_content = lifetime of reference outlives lifetime of borrowed content... infer_outlives_bound = lifetime of the source pointer does not outlive lifetime bound of the object type -infer_fullfill_req_lifetime = the type `{$ty}` does not fulfill the required lifetime +infer_fulfill_req_lifetime = the type `{$ty}` does not fulfill the required lifetime infer_lf_bound_not_satisfied = lifetime bound not satisfied infer_borrowed_too_long = a value of type `{$ty}` is borrowed for too long infer_ref_longer_than_data = in type `{$ty}`, reference has a longer lifetime than the data it references diff --git a/compiler/rustc_infer/src/errors/mod.rs b/compiler/rustc_infer/src/errors/mod.rs index b129621130d..65b3dd1a892 100644 --- a/compiler/rustc_infer/src/errors/mod.rs +++ b/compiler/rustc_infer/src/errors/mod.rs @@ -53,7 +53,7 @@ pub struct AnnotationRequired<'a> { // Copy of `AnnotationRequired` for E0283 #[derive(Diagnostic)] #[diag(infer_type_annotations_needed, code = "E0283")] -pub struct AmbigousImpl<'a> { +pub struct AmbiguousImpl<'a> { #[primary_span] pub span: Span, pub source_kind: &'static str, @@ -942,8 +942,8 @@ pub struct OutlivesBound<'a> { } #[derive(Diagnostic)] -#[diag(infer_fullfill_req_lifetime, code = "E0477")] -pub struct FullfillReqLifetime<'a> { +#[diag(infer_fulfill_req_lifetime, code = "E0477")] +pub struct FulfillReqLifetime<'a> { #[primary_span] pub span: Span, pub ty: Ty<'a>, diff --git a/compiler/rustc_infer/src/errors/note_and_explain.rs b/compiler/rustc_infer/src/errors/note_and_explain.rs index 30f6af74b83..7328241dfbc 100644 --- a/compiler/rustc_infer/src/errors/note_and_explain.rs +++ b/compiler/rustc_infer/src/errors/note_and_explain.rs @@ -4,12 +4,10 @@ use rustc_errors::{self, AddToDiagnostic, Diagnostic, IntoDiagnosticArg, Subdiag use rustc_middle::ty::{self, TyCtxt}; use rustc_span::{symbol::kw, Span}; -#[derive(Default)] struct DescriptionCtx<'a> { span: Option<Span>, kind: &'a str, arg: String, - num_arg: u32, } impl<'a> DescriptionCtx<'a> { @@ -18,102 +16,74 @@ impl<'a> DescriptionCtx<'a> { region: ty::Region<'tcx>, alt_span: Option<Span>, ) -> Option<Self> { - let mut me = DescriptionCtx::default(); - me.span = alt_span; - match *region { - ty::ReEarlyBound(_) | ty::ReFree(_) => { - return Self::from_early_bound_and_free_regions(tcx, region); - } - ty::ReStatic => { - me.kind = "restatic"; - } - - ty::RePlaceholder(_) => return None, - - ty::ReError(_) => return None, - - // FIXME(#13998) RePlaceholder should probably print like - // ReFree rather than dumping Debug output on the user. - // - // We shouldn't really be having unification failures with ReVar - // and ReLateBound though. - ty::ReVar(_) | ty::ReLateBound(..) | ty::ReErased => { - me.kind = "revar"; - me.arg = format!("{:?}", region); - } - }; - Some(me) - } - - fn from_early_bound_and_free_regions<'tcx>( - tcx: TyCtxt<'tcx>, - region: ty::Region<'tcx>, - ) -> Option<Self> { - let mut me = DescriptionCtx::default(); - let scope = region.free_region_binding_scope(tcx).expect_local(); - match *region { + let (span, kind, arg) = match *region { ty::ReEarlyBound(ref br) => { - let mut sp = tcx.def_span(scope); - if let Some(param) = + let scope = region.free_region_binding_scope(tcx).expect_local(); + let span = if let Some(param) = tcx.hir().get_generics(scope).and_then(|generics| generics.get_named(br.name)) { - sp = param.span; - } - if br.has_name() { - me.kind = "as_defined"; - me.arg = br.name.to_string(); + param.span } else { - me.kind = "as_defined_anon"; + tcx.def_span(scope) }; - me.span = Some(sp) + if br.has_name() { + (Some(span), "as_defined", br.name.to_string()) + } else { + (Some(span), "as_defined_anon", String::new()) + } } ty::ReFree(ref fr) => { if !fr.bound_region.is_named() && let Some((ty, _)) = find_anon_type(tcx, region, &fr.bound_region) { - me.kind = "defined_here"; - me.span = Some(ty.span); + (Some(ty.span), "defined_here", String::new()) } else { + let scope = region.free_region_binding_scope(tcx).expect_local(); match fr.bound_region { ty::BoundRegionKind::BrNamed(_, name) => { - let mut sp = tcx.def_span(scope); - if let Some(param) = - tcx.hir().get_generics(scope).and_then(|generics| generics.get_named(name)) + let span = if let Some(param) = tcx + .hir() + .get_generics(scope) + .and_then(|generics| generics.get_named(name)) { - sp = param.span; - } - if name == kw::UnderscoreLifetime { - me.kind = "as_defined_anon"; + param.span } else { - me.kind = "as_defined"; - me.arg = name.to_string(); + tcx.def_span(scope) }; - me.span = Some(sp); + if name == kw::UnderscoreLifetime { + (Some(span), "as_defined_anon", String::new()) + } else { + (Some(span), "as_defined", name.to_string()) + } } ty::BrAnon(span) => { - me.kind = "defined_here"; - me.span = match span { + let span = match span { Some(_) => span, None => Some(tcx.def_span(scope)), - } - }, + }; + (span, "defined_here", String::new()) + } _ => { - me.kind = "defined_here_reg"; - me.arg = region.to_string(); - me.span = Some(tcx.def_span(scope)); - }, + (Some(tcx.def_span(scope)), "defined_here_reg", region.to_string()) + } } } } - _ => bug!(), - } - Some(me) - } - fn add_to(self, diag: &mut rustc_errors::Diagnostic) { - diag.set_arg("desc_kind", self.kind); - diag.set_arg("desc_arg", self.arg); - diag.set_arg("desc_num_arg", self.num_arg); + ty::ReStatic => (alt_span, "restatic", String::new()), + + ty::RePlaceholder(_) | ty::ReError(_) => return None, + + // FIXME(#13998) RePlaceholder should probably print like + // ReFree rather than dumping Debug output on the user. + // + // We shouldn't really be having unification failures with ReVar + // and ReLateBound though. + ty::ReVar(_) | ty::ReLateBound(..) | ty::ReErased => { + (alt_span, "revar", format!("{:?}", region)) + } + }; + Some(DescriptionCtx { span, kind, arg }) } } @@ -198,10 +168,11 @@ impl AddToDiagnostic for RegionExplanation<'_> { { diag.set_arg("pref_kind", self.prefix); diag.set_arg("suff_kind", self.suffix); - let desc_span = self.desc.span; - self.desc.add_to(diag); + diag.set_arg("desc_kind", self.desc.kind); + diag.set_arg("desc_arg", self.desc.arg); + let msg = f(diag, fluent::infer_region_explanation.into()); - if let Some(span) = desc_span { + if let Some(span) = self.desc.span { diag.span_note(span, msg); } else { diag.note(msg); diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 7901bc94021..9e5f6d107d1 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -74,6 +74,7 @@ use rustc_middle::ty::{ self, error::TypeError, List, Region, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, }; +use rustc_span::DUMMY_SP; use rustc_span::{sym, symbol::kw, BytePos, DesugaringKind, Pos, Span}; use rustc_target::spec::abi; use std::ops::{ControlFlow, Deref}; @@ -113,7 +114,11 @@ fn escape_literal(s: &str) -> String { /// A helper for building type related errors. The `typeck_results` /// field is only populated during an in-progress typeck. -/// Get an instance by calling `InferCtxt::err` or `FnCtxt::infer_err`. +/// Get an instance by calling `InferCtxt::err_ctxt` or `FnCtxt::err_ctxt`. +/// +/// You must only create this if you intend to actually emit an error. +/// This provides a lot of utility methods which should not be used +/// during the happy path. pub struct TypeErrCtxt<'a, 'tcx> { pub infcx: &'a InferCtxt<'tcx>, pub typeck_results: Option<std::cell::Ref<'a, ty::TypeckResults<'tcx>>>, @@ -125,6 +130,19 @@ pub struct TypeErrCtxt<'a, 'tcx> { Box<dyn Fn(Ty<'tcx>) -> Vec<(Ty<'tcx>, Vec<PredicateObligation<'tcx>>)> + 'a>, } +impl Drop for TypeErrCtxt<'_, '_> { + fn drop(&mut self) { + if let Some(_) = self.infcx.tcx.sess.has_errors_or_delayed_span_bugs() { + // ok, emitted an error. + } else { + self.infcx + .tcx + .sess + .delay_span_bug(DUMMY_SP, "used a `TypeErrCtxt` without failing compilation"); + } + } +} + impl TypeErrCtxt<'_, '_> { /// This is just to avoid a potential footgun of accidentally /// dropping `typeck_results` by calling `InferCtxt::err_ctxt` @@ -185,83 +203,73 @@ fn msg_span_from_named_region<'tcx>( alt_span: Option<Span>, ) -> (String, Option<Span>) { match *region { - ty::ReEarlyBound(_) | ty::ReFree(_) => { - let (msg, span) = msg_span_from_early_bound_and_free_regions(tcx, region); - (msg, Some(span)) - } - ty::ReStatic => ("the static lifetime".to_owned(), alt_span), - ty::RePlaceholder(ty::PlaceholderRegion { - bound: ty::BoundRegion { kind: ty::BoundRegionKind::BrNamed(def_id, name), .. }, - .. - }) => (format!("the lifetime `{name}` as defined here"), Some(tcx.def_span(def_id))), - ty::RePlaceholder(ty::PlaceholderRegion { - bound: ty::BoundRegion { kind: ty::BoundRegionKind::BrAnon(Some(span)), .. }, - .. - }) => (format!("the anonymous lifetime defined here"), Some(span)), - ty::RePlaceholder(ty::PlaceholderRegion { - bound: ty::BoundRegion { kind: ty::BoundRegionKind::BrAnon(None), .. }, - .. - }) => (format!("an anonymous lifetime"), None), - _ => bug!("{:?}", region), - } -} - -fn msg_span_from_early_bound_and_free_regions<'tcx>( - tcx: TyCtxt<'tcx>, - region: ty::Region<'tcx>, -) -> (String, Span) { - let scope = region.free_region_binding_scope(tcx).expect_local(); - match *region { ty::ReEarlyBound(ref br) => { - let mut sp = tcx.def_span(scope); - if let Some(param) = + let scope = region.free_region_binding_scope(tcx).expect_local(); + let span = if let Some(param) = tcx.hir().get_generics(scope).and_then(|generics| generics.get_named(br.name)) { - sp = param.span; - } + param.span + } else { + tcx.def_span(scope) + }; let text = if br.has_name() { format!("the lifetime `{}` as defined here", br.name) } else { "the anonymous lifetime as defined here".to_string() }; - (text, sp) + (text, Some(span)) } ty::ReFree(ref fr) => { if !fr.bound_region.is_named() && let Some((ty, _)) = find_anon_type(tcx, region, &fr.bound_region) { - ("the anonymous lifetime defined here".to_string(), ty.span) + ("the anonymous lifetime defined here".to_string(), Some(ty.span)) } else { + let scope = region.free_region_binding_scope(tcx).expect_local(); match fr.bound_region { ty::BoundRegionKind::BrNamed(_, name) => { - let mut sp = tcx.def_span(scope); - if let Some(param) = + let span = if let Some(param) = tcx.hir().get_generics(scope).and_then(|generics| generics.get_named(name)) { - sp = param.span; - } + param.span + } else { + tcx.def_span(scope) + }; let text = if name == kw::UnderscoreLifetime { "the anonymous lifetime as defined here".to_string() } else { format!("the lifetime `{}` as defined here", name) }; - (text, sp) + (text, Some(span)) } ty::BrAnon(span) => ( "the anonymous lifetime as defined here".to_string(), - match span { + Some(match span { Some(span) => span, None => tcx.def_span(scope) - } + }) ), _ => ( format!("the lifetime `{}` as defined here", region), - tcx.def_span(scope), + Some(tcx.def_span(scope)), ), } } } - _ => bug!(), + ty::ReStatic => ("the static lifetime".to_owned(), alt_span), + ty::RePlaceholder(ty::PlaceholderRegion { + bound: ty::BoundRegion { kind: ty::BoundRegionKind::BrNamed(def_id, name), .. }, + .. + }) => (format!("the lifetime `{name}` as defined here"), Some(tcx.def_span(def_id))), + ty::RePlaceholder(ty::PlaceholderRegion { + bound: ty::BoundRegion { kind: ty::BoundRegionKind::BrAnon(Some(span)), .. }, + .. + }) => (format!("the anonymous lifetime defined here"), Some(span)), + ty::RePlaceholder(ty::PlaceholderRegion { + bound: ty::BoundRegion { kind: ty::BoundRegionKind::BrAnon(None), .. }, + .. + }) => (format!("an anonymous lifetime"), None), + _ => bug!("{:?}", region), } } @@ -419,7 +427,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { &self, generic_param_scope: LocalDefId, errors: &[RegionResolutionError<'tcx>], - ) { + ) -> ErrorGuaranteed { + if let Some(guaranteed) = self.infcx.tainted_by_errors() { + return guaranteed; + } + debug!("report_region_errors(): {} errors to start", errors.len()); // try to pre-process the errors, which will group some of them @@ -499,6 +511,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } } } + + self.tcx + .sess + .delay_span_bug(self.tcx.def_span(generic_param_scope), "expected region errors") } // This method goes through all the errors and try to group certain types @@ -1829,7 +1845,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { // will try to hide in some case such as `async fn`, so // to make an error more use friendly we will // avoid to suggest a mismatch type with a - // type that the user usually are not usign + // type that the user usually are not using // directly such as `impl Future<Output = u8>`. if !self.tcx.ty_is_opaque_future(found_ty) { diag.note_expected_found_extra( diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs index d7b900ca02d..75cc4e257bd 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs @@ -1,5 +1,5 @@ use crate::errors::{ - AmbigousImpl, AmbigousReturn, AnnotationRequired, InferenceBadError, NeedTypeInfoInGenerator, + AmbigousReturn, AmbiguousImpl, AnnotationRequired, InferenceBadError, NeedTypeInfoInGenerator, SourceKindMultiSuggestion, SourceKindSubdiag, }; use crate::infer::error_reporting::TypeErrCtxt; @@ -358,7 +358,7 @@ impl<'tcx> InferCtxt<'tcx> { bad_label, } .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic), - TypeAnnotationNeeded::E0283 => AmbigousImpl { + TypeAnnotationNeeded::E0283 => AmbiguousImpl { span, source_kind, source_name, @@ -563,7 +563,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { bad_label: None, } .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic), - TypeAnnotationNeeded::E0283 => AmbigousImpl { + TypeAnnotationNeeded::E0283 => AmbiguousImpl { span, source_kind, source_name: &name, diff --git a/compiler/rustc_infer/src/infer/error_reporting/note.rs b/compiler/rustc_infer/src/infer/error_reporting/note.rs index e720af73c39..07a9eff2dbe 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note.rs @@ -1,5 +1,5 @@ use crate::errors::{ - note_and_explain, FullfillReqLifetime, LfBoundNotSatisfied, OutlivesBound, OutlivesContent, + note_and_explain, FulfillReqLifetime, LfBoundNotSatisfied, OutlivesBound, OutlivesContent, RefLongerThanData, RegionOriginNote, WhereClauseSuggestions, }; use crate::fluent_generated as fluent; @@ -176,7 +176,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { let note = note_and_explain::RegionExplanation::new( self.tcx, sub, opt_span, prefix, suffix, ); - FullfillReqLifetime { span, ty: self.resolve_vars_if_possible(ty), note } + FulfillReqLifetime { span, ty: self.resolve_vars_if_possible(ty), note } .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic) } infer::RelateRegionParamBound(span) => { diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index b4f2ad0bb34..66f51328bbe 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -45,8 +45,7 @@ use self::combine::CombineFields; use self::error_reporting::TypeErrCtxt; use self::free_regions::RegionRelations; use self::lexical_region_resolve::LexicalRegionResolutions; -use self::outlives::env::OutlivesEnvironment; -use self::region_constraints::{GenericKind, RegionConstraintData, VarInfos, VerifyBound}; +use self::region_constraints::{GenericKind, VarInfos, VerifyBound}; use self::region_constraints::{ RegionConstraintCollector, RegionConstraintStorage, RegionSnapshot, }; @@ -1213,95 +1212,6 @@ impl<'tcx> InferCtxt<'tcx> { self.tainted_by_errors.set(Some(e)); } - pub fn skip_region_resolution(&self) { - let (var_infos, _) = { - let mut inner = self.inner.borrow_mut(); - let inner = &mut *inner; - // Note: `inner.region_obligations` may not be empty, because we - // didn't necessarily call `process_registered_region_obligations`. - // This is okay, because that doesn't introduce new vars. - inner - .region_constraint_storage - .take() - .expect("regions already resolved") - .with_log(&mut inner.undo_log) - .into_infos_and_data() - }; - - let lexical_region_resolutions = LexicalRegionResolutions { - values: rustc_index::vec::IndexVec::from_elem_n( - crate::infer::lexical_region_resolve::VarValue::Value(self.tcx.lifetimes.re_erased), - var_infos.len(), - ), - }; - - let old_value = self.lexical_region_resolutions.replace(Some(lexical_region_resolutions)); - assert!(old_value.is_none()); - } - - /// Process the region constraints and return any errors that - /// result. After this, no more unification operations should be - /// done -- or the compiler will panic -- but it is legal to use - /// `resolve_vars_if_possible` as well as `fully_resolve`. - pub fn resolve_regions( - &self, - outlives_env: &OutlivesEnvironment<'tcx>, - ) -> Vec<RegionResolutionError<'tcx>> { - let (var_infos, data) = { - let mut inner = self.inner.borrow_mut(); - let inner = &mut *inner; - assert!( - self.tainted_by_errors().is_some() || inner.region_obligations.is_empty(), - "region_obligations not empty: {:#?}", - inner.region_obligations - ); - inner - .region_constraint_storage - .take() - .expect("regions already resolved") - .with_log(&mut inner.undo_log) - .into_infos_and_data() - }; - - let region_rels = &RegionRelations::new(self.tcx, outlives_env.free_region_map()); - - let (lexical_region_resolutions, errors) = - lexical_region_resolve::resolve(outlives_env.param_env, region_rels, var_infos, data); - - let old_value = self.lexical_region_resolutions.replace(Some(lexical_region_resolutions)); - assert!(old_value.is_none()); - - errors - } - /// Obtains (and clears) the current set of region - /// constraints. The inference context is still usable: further - /// unifications will simply add new constraints. - /// - /// This method is not meant to be used with normal lexical region - /// resolution. Rather, it is used in the NLL mode as a kind of - /// interim hack: basically we run normal type-check and generate - /// region constraints as normal, but then we take them and - /// translate them into the form that the NLL solver - /// understands. See the NLL module for mode details. - pub fn take_and_reset_region_constraints(&self) -> RegionConstraintData<'tcx> { - assert!( - self.inner.borrow().region_obligations.is_empty(), - "region_obligations not empty: {:#?}", - self.inner.borrow().region_obligations - ); - - self.inner.borrow_mut().unwrap_region_constraints().take_and_reset_data() - } - - /// Gives temporary access to the region constraint data. - pub fn with_region_constraints<R>( - &self, - op: impl FnOnce(&RegionConstraintData<'tcx>) -> R, - ) -> R { - let mut inner = self.inner.borrow_mut(); - op(inner.unwrap_region_constraints().data()) - } - pub fn region_var_origin(&self, vid: ty::RegionVid) -> RegionVariableOrigin { let mut inner = self.inner.borrow_mut(); let inner = &mut *inner; @@ -1754,56 +1664,6 @@ impl<'cx, 'tcx> Drop for CanonicalizationCtxtGuard<'cx, 'tcx> { } impl<'tcx> TypeErrCtxt<'_, 'tcx> { - /// Processes registered region obliations and resolves regions, reporting - /// any errors if any were raised. Prefer using this function over manually - /// calling `resolve_regions_and_report_errors`. - pub fn check_region_obligations_and_report_errors( - &self, - generic_param_scope: LocalDefId, - outlives_env: &OutlivesEnvironment<'tcx>, - ) -> Result<(), ErrorGuaranteed> { - self.process_registered_region_obligations( - outlives_env.region_bound_pairs(), - outlives_env.param_env, - ); - - self.resolve_regions_and_report_errors(generic_param_scope, outlives_env) - } - - /// Process the region constraints and report any errors that - /// result. After this, no more unification operations should be - /// done -- or the compiler will panic -- but it is legal to use - /// `resolve_vars_if_possible` as well as `fully_resolve`. - /// - /// Make sure to call [`InferCtxt::process_registered_region_obligations`] - /// first, or preferably use [`TypeErrCtxt::check_region_obligations_and_report_errors`] - /// to do both of these operations together. - pub fn resolve_regions_and_report_errors( - &self, - generic_param_scope: LocalDefId, - outlives_env: &OutlivesEnvironment<'tcx>, - ) -> Result<(), ErrorGuaranteed> { - let errors = self.resolve_regions(outlives_env); - - if let None = self.tainted_by_errors() { - // As a heuristic, just skip reporting region errors - // altogether if other errors have been reported while - // this infcx was in use. This is totally hokey but - // otherwise we have a hard time separating legit region - // errors from silly ones. - self.report_region_errors(generic_param_scope, &errors); - } - - if errors.is_empty() { - Ok(()) - } else { - Err(self - .tcx - .sess - .delay_span_bug(rustc_span::DUMMY_SP, "error should have been emitted")) - } - } - // [Note-Type-error-reporting] // An invariant is that anytime the expected or actual type is Error (the special // error type, meaning that an error occurred when typechecking this expression), diff --git a/compiler/rustc_infer/src/infer/outlives/mod.rs b/compiler/rustc_infer/src/infer/outlives/mod.rs index 048dad3a48b..9a9a1696b00 100644 --- a/compiler/rustc_infer/src/infer/outlives/mod.rs +++ b/compiler/rustc_infer/src/infer/outlives/mod.rs @@ -1,4 +1,11 @@ //! Various code related to computing outlives relations. +use self::env::OutlivesEnvironment; +use super::region_constraints::RegionConstraintData; +use super::{InferCtxt, RegionResolutionError}; +use crate::infer::free_regions::RegionRelations; +use crate::infer::lexical_region_resolve::{self, LexicalRegionResolutions}; +use rustc_middle::traits::query::OutlivesBound; +use rustc_middle::ty; pub mod components; pub mod env; @@ -6,9 +13,6 @@ pub mod obligations; pub mod test_type_match; pub mod verify; -use rustc_middle::traits::query::OutlivesBound; -use rustc_middle::ty; - #[instrument(level = "debug", skip(param_env), ret)] pub fn explicit_outlives_bounds<'tcx>( param_env: ty::ParamEnv<'tcx>, @@ -39,3 +43,98 @@ pub fn explicit_outlives_bounds<'tcx>( ))) => Some(OutlivesBound::RegionSubRegion(r_b, r_a)), }) } + +impl<'tcx> InferCtxt<'tcx> { + pub fn skip_region_resolution(&self) { + let (var_infos, _) = { + let mut inner = self.inner.borrow_mut(); + let inner = &mut *inner; + // Note: `inner.region_obligations` may not be empty, because we + // didn't necessarily call `process_registered_region_obligations`. + // This is okay, because that doesn't introduce new vars. + inner + .region_constraint_storage + .take() + .expect("regions already resolved") + .with_log(&mut inner.undo_log) + .into_infos_and_data() + }; + + let lexical_region_resolutions = LexicalRegionResolutions { + values: rustc_index::vec::IndexVec::from_elem_n( + crate::infer::lexical_region_resolve::VarValue::Value(self.tcx.lifetimes.re_erased), + var_infos.len(), + ), + }; + + let old_value = self.lexical_region_resolutions.replace(Some(lexical_region_resolutions)); + assert!(old_value.is_none()); + } + + /// Process the region constraints and return any errors that + /// result. After this, no more unification operations should be + /// done -- or the compiler will panic -- but it is legal to use + /// `resolve_vars_if_possible` as well as `fully_resolve`. + #[must_use] + pub fn resolve_regions( + &self, + outlives_env: &OutlivesEnvironment<'tcx>, + ) -> Vec<RegionResolutionError<'tcx>> { + self.process_registered_region_obligations(outlives_env); + + let (var_infos, data) = { + let mut inner = self.inner.borrow_mut(); + let inner = &mut *inner; + assert!( + self.tainted_by_errors().is_some() || inner.region_obligations.is_empty(), + "region_obligations not empty: {:#?}", + inner.region_obligations + ); + inner + .region_constraint_storage + .take() + .expect("regions already resolved") + .with_log(&mut inner.undo_log) + .into_infos_and_data() + }; + + let region_rels = &RegionRelations::new(self.tcx, outlives_env.free_region_map()); + + let (lexical_region_resolutions, errors) = + lexical_region_resolve::resolve(outlives_env.param_env, region_rels, var_infos, data); + + let old_value = self.lexical_region_resolutions.replace(Some(lexical_region_resolutions)); + assert!(old_value.is_none()); + + errors + } + + /// Obtains (and clears) the current set of region + /// constraints. The inference context is still usable: further + /// unifications will simply add new constraints. + /// + /// This method is not meant to be used with normal lexical region + /// resolution. Rather, it is used in the NLL mode as a kind of + /// interim hack: basically we run normal type-check and generate + /// region constraints as normal, but then we take them and + /// translate them into the form that the NLL solver + /// understands. See the NLL module for mode details. + pub fn take_and_reset_region_constraints(&self) -> RegionConstraintData<'tcx> { + assert!( + self.inner.borrow().region_obligations.is_empty(), + "region_obligations not empty: {:#?}", + self.inner.borrow().region_obligations + ); + + self.inner.borrow_mut().unwrap_region_constraints().take_and_reset_data() + } + + /// Gives temporary access to the region constraint data. + pub fn with_region_constraints<R>( + &self, + op: impl FnOnce(&RegionConstraintData<'tcx>) -> R, + ) -> R { + let mut inner = self.inner.borrow_mut(); + op(inner.unwrap_region_constraints().data()) + } +} diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs index bbe7d4c63f7..ccf11c61b57 100644 --- a/compiler/rustc_infer/src/infer/outlives/obligations.rs +++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs @@ -72,6 +72,8 @@ use rustc_middle::ty::subst::GenericArgKind; use rustc_middle::ty::{self, Region, SubstsRef, Ty, TyCtxt, TypeVisitableExt}; use smallvec::smallvec; +use super::env::OutlivesEnvironment; + impl<'tcx> InferCtxt<'tcx> { /// Registers that the given region obligation must be resolved /// from within the scope of `body_id`. These regions are enqueued @@ -112,39 +114,17 @@ impl<'tcx> InferCtxt<'tcx> { std::mem::take(&mut self.inner.borrow_mut().region_obligations) } - /// NOTE: Prefer using `TypeErrCtxt::check_region_obligations_and_report_errors` - /// instead of calling this directly. - /// /// Process the region obligations that must be proven (during /// `regionck`) for the given `body_id`, given information about - /// the region bounds in scope and so forth. This function must be - /// invoked for all relevant body-ids before region inference is - /// done (or else an assert will fire). + /// the region bounds in scope and so forth. /// /// See the `region_obligations` field of `InferCtxt` for some /// comments about how this function fits into the overall expected /// flow of the inferencer. The key point is that it is /// invoked after all type-inference variables have been bound -- - /// towards the end of regionck. This also ensures that the - /// region-bound-pairs are available (see comments above regarding - /// closures). - /// - /// # Parameters - /// - /// - `region_bound_pairs_map`: the set of region bounds implied by - /// the parameters and where-clauses. In particular, each pair - /// `('a, K)` in this list tells us that the bounds in scope - /// indicate that `K: 'a`, where `K` is either a generic - /// parameter like `T` or a projection like `T::Item`. - /// - `param_env` is the parameter environment for the enclosing function. - /// - `body_id` is the body-id whose region obligations are being - /// processed. - #[instrument(level = "debug", skip(self, region_bound_pairs))] - pub fn process_registered_region_obligations( - &self, - region_bound_pairs: &RegionBoundPairs<'tcx>, - param_env: ty::ParamEnv<'tcx>, - ) { + /// right before lexical region resolution. + #[instrument(level = "debug", skip(self, outlives_env))] + pub fn process_registered_region_obligations(&self, outlives_env: &OutlivesEnvironment<'tcx>) { assert!( !self.in_snapshot.get(), "cannot process registered region obligations in a snapshot" @@ -153,15 +133,16 @@ impl<'tcx> InferCtxt<'tcx> { let my_region_obligations = self.take_registered_region_obligations(); for RegionObligation { sup_type, sub_region, origin } in my_region_obligations { - debug!( - "process_registered_region_obligations: sup_type={:?} sub_region={:?} origin={:?}", - sup_type, sub_region, origin - ); - + debug!(?sup_type, ?sub_region, ?origin); let sup_type = self.resolve_vars_if_possible(sup_type); - let outlives = - &mut TypeOutlives::new(self, self.tcx, ®ion_bound_pairs, None, param_env); + let outlives = &mut TypeOutlives::new( + self, + self.tcx, + &outlives_env.region_bound_pairs(), + None, + outlives_env.param_env, + ); let category = origin.to_constraint_category(); outlives.type_must_outlive(origin, sup_type, sub_region, category); } diff --git a/compiler/rustc_infer/src/traits/engine.rs b/compiler/rustc_infer/src/traits/engine.rs index f75344f20b6..b8940e2f045 100644 --- a/compiler/rustc_infer/src/traits/engine.rs +++ b/compiler/rustc_infer/src/traits/engine.rs @@ -36,9 +36,10 @@ pub trait TraitEngine<'tcx>: 'tcx { obligation: PredicateObligation<'tcx>, ); + #[must_use] fn select_where_possible(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<FulfillmentError<'tcx>>; - fn collect_remaining_errors(&mut self) -> Vec<FulfillmentError<'tcx>>; + fn collect_remaining_errors(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<FulfillmentError<'tcx>>; fn pending_obligations(&self) -> Vec<PredicateObligation<'tcx>>; @@ -58,6 +59,7 @@ pub trait TraitEngineExt<'tcx> { obligations: impl IntoIterator<Item = PredicateObligation<'tcx>>, ); + #[must_use] fn select_all_or_error(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<FulfillmentError<'tcx>>; } @@ -78,6 +80,6 @@ impl<'tcx, T: ?Sized + TraitEngine<'tcx>> TraitEngineExt<'tcx> for T { return errors; } - self.collect_remaining_errors() + self.collect_remaining_errors(infcx) } } diff --git a/compiler/rustc_infer/src/traits/mod.rs b/compiler/rustc_infer/src/traits/mod.rs index dd9b2e548c7..e01b6caf430 100644 --- a/compiler/rustc_infer/src/traits/mod.rs +++ b/compiler/rustc_infer/src/traits/mod.rs @@ -128,7 +128,11 @@ pub enum FulfillmentErrorCode<'tcx> { CodeProjectionError(MismatchedProjectionTypes<'tcx>), CodeSubtypeError(ExpectedFound<Ty<'tcx>>, TypeError<'tcx>), // always comes from a SubtypePredicate CodeConstEquateError(ExpectedFound<Const<'tcx>>, TypeError<'tcx>), - CodeAmbiguity, + CodeAmbiguity { + /// Overflow reported from the new solver `-Ztrait-solver=next`, which will + /// be reported as an regular error as opposed to a fatal error. + overflow: bool, + }, } impl<'tcx, O> Obligation<'tcx, O> { diff --git a/compiler/rustc_infer/src/traits/structural_impls.rs b/compiler/rustc_infer/src/traits/structural_impls.rs index 3a5273b0359..1563d92af0e 100644 --- a/compiler/rustc_infer/src/traits/structural_impls.rs +++ b/compiler/rustc_infer/src/traits/structural_impls.rs @@ -46,7 +46,8 @@ impl<'tcx> fmt::Debug for traits::FulfillmentErrorCode<'tcx> { super::CodeConstEquateError(ref a, ref b) => { write!(f, "CodeConstEquateError({:?}, {:?})", a, b) } - super::CodeAmbiguity => write!(f, "Ambiguity"), + super::CodeAmbiguity { overflow: false } => write!(f, "Ambiguity"), + super::CodeAmbiguity { overflow: true } => write!(f, "Overflow"), super::CodeCycle(ref cycle) => write!(f, "Cycle({:?})", cycle), } } diff --git a/compiler/rustc_lexer/src/lib.rs b/compiler/rustc_lexer/src/lib.rs index 322ec31fb2c..b3f4b5cd5e5 100644 --- a/compiler/rustc_lexer/src/lib.rs +++ b/compiler/rustc_lexer/src/lib.rs @@ -95,7 +95,7 @@ pub enum TokenKind { Literal { kind: LiteralKind, suffix_start: u32 }, /// "'a" - Lifetime { starts_with_number: bool, contains_emoji: bool }, + Lifetime { starts_with_number: bool }, // One-char tokens: /// ";" @@ -632,13 +632,7 @@ impl Cursor<'_> { // If the first symbol is valid for identifier, it can be a lifetime. // Also check if it's a number for a better error reporting (so '0 will // be reported as invalid lifetime and not as unterminated char literal). - // We also have to account for potential `'🐱` emojis to avoid reporting - // it as an unterminated char literal. - is_id_start(self.first()) - || self.first().is_digit(10) - // FIXME(#108019): `unic-emoji-char` seems to have data tables only up to Unicode - // 5.0, but Unicode is already newer than this. - || unic_emoji_char::is_emoji(self.first()) + is_id_start(self.first()) || self.first().is_digit(10) }; if !can_be_a_lifetime { @@ -651,33 +645,16 @@ impl Cursor<'_> { return Literal { kind, suffix_start }; } - // Either a lifetime or a character literal. + // Either a lifetime or a character literal with + // length greater than 1. let starts_with_number = self.first().is_digit(10); - let mut contains_emoji = false; - // FIXME(#108019): `unic-emoji-char` seems to have data tables only up to Unicode - // 5.0, but Unicode is already newer than this. - if unic_emoji_char::is_emoji(self.first()) { - contains_emoji = true; - } else { - // Skip the literal contents. - // First symbol can be a number (which isn't a valid identifier start), - // so skip it without any checks. - self.bump(); - } - self.eat_while(|c| { - if is_id_continue(c) { - true - // FIXME(#108019): `unic-emoji-char` seems to have data tables only up to Unicode - // 5.0, but Unicode is already newer than this. - } else if unic_emoji_char::is_emoji(c) { - contains_emoji = true; - true - } else { - false - } - }); + // Skip the literal contents. + // First symbol can be a number (which isn't a valid identifier start), + // so skip it without any checks. + self.bump(); + self.eat_while(is_id_continue); // Check if after skipping literal contents we've met a closing // single quote (which means that user attempted to create a @@ -687,7 +664,7 @@ impl Cursor<'_> { let kind = Char { terminated: true }; Literal { kind, suffix_start: self.pos_within_token() } } else { - Lifetime { starts_with_number, contains_emoji } + Lifetime { starts_with_number } } } diff --git a/compiler/rustc_lexer/src/tests.rs b/compiler/rustc_lexer/src/tests.rs index 670d64fb983..e4c1787f2cc 100644 --- a/compiler/rustc_lexer/src/tests.rs +++ b/compiler/rustc_lexer/src/tests.rs @@ -235,7 +235,7 @@ fn lifetime() { check_lexing( "'abc", expect![[r#" - Token { kind: Lifetime { starts_with_number: false, contains_emoji: false }, len: 4 } + Token { kind: Lifetime { starts_with_number: false }, len: 4 } "#]], ); } diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index d9c8142226d..db15b176df0 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -91,7 +91,7 @@ lint_ty_qualified = usage of qualified `ty::{$ty}` lint_lintpass_by_hand = implementing `LintPass` by hand .help = try using `declare_lint_pass!` or `impl_lint_pass!` instead -lint_non_existant_doc_keyword = found non-existing keyword `{$keyword}` used in `#[doc(keyword = "...")]` +lint_non_existent_doc_keyword = found non-existing keyword `{$keyword}` used in `#[doc(keyword = "...")]` .help = only existing keywords are allowed in core/std lint_diag_out_of_impl = @@ -107,7 +107,7 @@ lint_cstring_ptr = getting the inner pointer of a temporary `CString` .note = pointers do not have a lifetime; when calling `as_ptr` the `CString` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned .help = for more information, see https://doc.rust-lang.org/reference/destructors.html -lint_multple_supertrait_upcastable = `{$ident}` is object-safe and has multiple supertraits +lint_multiple_supertrait_upcastable = `{$ident}` is object-safe and has multiple supertraits lint_identifier_non_ascii_char = identifier contains non-ASCII characters diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs index 9c7feadaf87..4ac589c2e10 100644 --- a/compiler/rustc_lint/src/internal.rs +++ b/compiler/rustc_lint/src/internal.rs @@ -2,7 +2,7 @@ //! Clippy. use crate::lints::{ - BadOptAccessDiag, DefaultHashTypesDiag, DiagOutOfImpl, LintPassByHand, NonExistantDocKeyword, + BadOptAccessDiag, DefaultHashTypesDiag, DiagOutOfImpl, LintPassByHand, NonExistentDocKeyword, QueryInstability, TyQualified, TykindDiag, TykindKind, UntranslatableDiag, }; use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext}; @@ -334,7 +334,7 @@ impl<'tcx> LateLintPass<'tcx> for ExistingDocKeyword { cx.emit_spanned_lint( EXISTING_DOC_KEYWORD, attr.span, - NonExistantDocKeyword { keyword }, + NonExistentDocKeyword { keyword }, ); } } @@ -424,7 +424,7 @@ impl LateLintPass<'_> for Diagnostics { } declare_tool_lint! { - /// The `bad_opt_access` lint detects accessing options by field instad of + /// The `bad_opt_access` lint detects accessing options by field instead of /// the wrapper function. pub rustc::BAD_OPT_ACCESS, Deny, diff --git a/compiler/rustc_lint/src/let_underscore.rs b/compiler/rustc_lint/src/let_underscore.rs index b83a9665fc0..3eefd1b0e08 100644 --- a/compiler/rustc_lint/src/let_underscore.rs +++ b/compiler/rustc_lint/src/let_underscore.rs @@ -25,7 +25,7 @@ declare_lint! { /// /// fn main() { /// #[warn(let_underscore_drop)] - /// // SomeStuct is dropped immediately instead of at end of scope, + /// // SomeStruct is dropped immediately instead of at end of scope, /// // so "Dropping SomeStruct" is printed before "end of main". /// // The order of prints would be reversed if SomeStruct was bound to /// // a name (such as "_foo"). diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index a2a7c93a7ca..bb863f09516 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -3,7 +3,7 @@ use crate::{ fluent_generated as fluent, late::unerased_lint_store, lints::{ - DeprecatedLintName, IgnoredUnlessCrateSpecified, OverruledAtributeLint, + DeprecatedLintName, IgnoredUnlessCrateSpecified, OverruledAttributeLint, RenamedOrRemovedLint, RenamedOrRemovedLintSuggestion, UnknownLint, UnknownLintSuggestion, }, }; @@ -612,7 +612,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { self.emit_spanned_lint( FORBIDDEN_LINT_GROUPS, src.span().into(), - OverruledAtributeLint { + OverruledAttributeLint { overruled: src.span(), lint_level: level.as_str(), lint_source: src.name(), diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 8ec4c2b3d46..1d5e02369f5 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -806,9 +806,9 @@ pub struct TyQualified { pub struct LintPassByHand; #[derive(LintDiagnostic)] -#[diag(lint_non_existant_doc_keyword)] +#[diag(lint_non_existent_doc_keyword)] #[help] -pub struct NonExistantDocKeyword { +pub struct NonExistentDocKeyword { pub keyword: Symbol, } @@ -875,7 +875,7 @@ impl AddToDiagnostic for NonBindingLetSub { // levels.rs #[derive(LintDiagnostic)] #[diag(lint_overruled_attribute)] -pub struct OverruledAtributeLint<'a> { +pub struct OverruledAttributeLint<'a> { #[label] pub overruled: Span, pub lint_level: &'a str, @@ -947,7 +947,7 @@ pub struct CStringPtr { // multiple_supertrait_upcastable.rs #[derive(LintDiagnostic)] -#[diag(lint_multple_supertrait_upcastable)] +#[diag(lint_multiple_supertrait_upcastable)] pub struct MultipleSupertraitUpcastable { pub ident: Ident, } @@ -1422,7 +1422,7 @@ pub struct UnusedResult<'a> { pub ty: Ty<'a>, } -// FIXME(davidtwco): this isn't properly translatable becauses of the +// FIXME(davidtwco): this isn't properly translatable because of the // pre/post strings #[derive(LintDiagnostic)] #[diag(lint_unused_closure)] @@ -1433,7 +1433,7 @@ pub struct UnusedClosure<'a> { pub post: &'a str, } -// FIXME(davidtwco): this isn't properly translatable becauses of the +// FIXME(davidtwco): this isn't properly translatable because of the // pre/post strings #[derive(LintDiagnostic)] #[diag(lint_unused_generator)] @@ -1444,7 +1444,7 @@ pub struct UnusedGenerator<'a> { pub post: &'a str, } -// FIXME(davidtwco): this isn't properly translatable becauses of the pre/post +// FIXME(davidtwco): this isn't properly translatable because of the pre/post // strings pub struct UnusedDef<'a, 'b> { pub pre: &'a str, diff --git a/compiler/rustc_lint/src/non_ascii_idents.rs b/compiler/rustc_lint/src/non_ascii_idents.rs index f130a98185d..4af879b4e91 100644 --- a/compiler/rustc_lint/src/non_ascii_idents.rs +++ b/compiler/rustc_lint/src/non_ascii_idents.rs @@ -250,7 +250,7 @@ impl EarlyLintPass for NonAsciiIdents { let latin_augmented_script_set = AugmentedScriptSet::for_char('A'); script_states.insert(latin_augmented_script_set, ScriptSetUsage::Verified); - let mut has_suspicous = false; + let mut has_suspicious = false; for (symbol, &sp) in symbols.iter() { let symbol_str = symbol.as_str(); for ch in symbol_str.chars() { @@ -278,14 +278,14 @@ impl EarlyLintPass for NonAsciiIdents { if !is_potential_mixed_script_confusable_char(ch) { ScriptSetUsage::Verified } else { - has_suspicous = true; + has_suspicious = true; ScriptSetUsage::Suspicious(vec![ch], sp) } }); } } - if has_suspicous { + if has_suspicious { let verified_augmented_script_sets = script_states .iter() .flat_map(|(k, v)| match v { diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index 69a8b691ab2..7ea472ed504 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -532,7 +532,7 @@ pub enum BuiltinLintDiagnostics { AmbiguousGlobReexports { /// The name for which collision(s) have occurred. name: String, - /// The name space for whihc the collision(s) occurred in. + /// The name space for which the collision(s) occurred in. namespace: String, /// Span where the name is first re-exported. first_reexport_span: Span, diff --git a/compiler/rustc_log/src/lib.rs b/compiler/rustc_log/src/lib.rs index 21f6a404a01..3cbb2c21e28 100644 --- a/compiler/rustc_log/src/lib.rs +++ b/compiler/rustc_log/src/lib.rs @@ -40,7 +40,6 @@ #![deny(rustc::untranslatable_diagnostic)] #![deny(rustc::diagnostic_outside_of_impl)] -#![feature(is_terminal)] use std::env::{self, VarError}; use std::fmt::{self, Display}; diff --git a/compiler/rustc_middle/src/infer/unify_key.rs b/compiler/rustc_middle/src/infer/unify_key.rs index d83a587a86a..a873854f068 100644 --- a/compiler/rustc_middle/src/infer/unify_key.rs +++ b/compiler/rustc_middle/src/infer/unify_key.rs @@ -58,7 +58,7 @@ impl<'tcx> UnifyValue for UnifiedRegion<'tcx> { fn unify_values(value1: &Self, value2: &Self) -> Result<Self, NoError> { // We pick the value of the least universe because it is compatible with more variables. - // This is *not* neccessary for soundness, but it allows more region variables to be + // This is *not* necessary for soundness, but it allows more region variables to be // resolved to the said value. #[cold] fn min_universe<'tcx>(r1: Region<'tcx>, r2: Region<'tcx>) -> Region<'tcx> { diff --git a/compiler/rustc_middle/src/macros.rs b/compiler/rustc_middle/src/macros.rs index a8d71ce030c..89014f62d4d 100644 --- a/compiler/rustc_middle/src/macros.rs +++ b/compiler/rustc_middle/src/macros.rs @@ -1,6 +1,6 @@ /// A macro for triggering an ICE. /// Calling `bug` instead of panicking will result in a nicer error message and should -/// therefore be prefered over `panic`/`unreachable` or others. +/// therefore be preferred over `panic`/`unreachable` or others. /// /// If you have a span available, you should use [`span_bug`] instead. /// diff --git a/compiler/rustc_middle/src/mir/interpret/allocation/init_mask.rs b/compiler/rustc_middle/src/mir/interpret/allocation/init_mask.rs index 9a02bc0cc15..dcb56a1755e 100644 --- a/compiler/rustc_middle/src/mir/interpret/allocation/init_mask.rs +++ b/compiler/rustc_middle/src/mir/interpret/allocation/init_mask.rs @@ -63,7 +63,7 @@ impl InitMask { } /// Sets a specified range to a value. If the range is out-of-bounds, the mask will grow to - /// accomodate it entirely. + /// accommodate it entirely. pub fn set_range(&mut self, range: AllocRange, new_state: bool) { let start = range.start; let end = range.end(); diff --git a/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs b/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs index ddd3f394358..318f93e12b5 100644 --- a/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs +++ b/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs @@ -14,7 +14,7 @@ use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; #[derive(HashStable)] pub struct ProvenanceMap<Prov = AllocId> { /// Provenance in this map applies from the given offset for an entire pointer-size worth of - /// bytes. Two entires in this map are always at least a pointer size apart. + /// bytes. Two entries in this map are always at least a pointer size apart. ptrs: SortedMap<Size, Prov>, /// Provenance in this map only applies to the given single byte. /// This map is disjoint from the previous. It will always be empty when diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 56755e588cb..2ea8602af12 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -1115,6 +1115,11 @@ pub struct VarDebugInfo<'tcx> { /// Where the data for this user variable is to be found. pub value: VarDebugInfoContents<'tcx>, + + /// When present, indicates what argument number this variable is in the function that it + /// originated from (starting from 1). Note, if MIR inlining is enabled, then this is the + /// argument number in the original function before it was inlined. + pub argument_index: Option<u16>, } /////////////////////////////////////////////////////////////////////////// diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index 6c4ea065abe..0a9fcd898b9 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -832,6 +832,7 @@ macro_rules! make_mir_visitor { name: _, source_info, value, + argument_index: _, } = var_debug_info; self.visit_source_info(source_info); diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs index 24d98665a7b..7d9aea02289 100644 --- a/compiler/rustc_middle/src/query/erase.rs +++ b/compiler/rustc_middle/src/query/erase.rs @@ -37,7 +37,7 @@ pub fn erase<T: EraseType>(src: T) -> Erase<T> { #[inline(always)] pub fn restore<T: EraseType>(value: Erase<T>) -> T { let value: Erased<<T as EraseType>::Result> = value; - // SAFETY: Due to the use of impl Trait in `Erase` the only way to safetly create an instance + // SAFETY: Due to the use of impl Trait in `Erase` the only way to safely create an instance // of `Erase` is to call `erase`, so we know that `value.data` is a valid instance of `T` of // the right size. unsafe { transmute_copy(&value.data) } diff --git a/compiler/rustc_middle/src/query/keys.rs b/compiler/rustc_middle/src/query/keys.rs index 3b0eec683de..23b28ac5ca9 100644 --- a/compiler/rustc_middle/src/query/keys.rs +++ b/compiler/rustc_middle/src/query/keys.rs @@ -26,7 +26,7 @@ pub trait Key: Sized { // // ...But r-a doesn't support them yet and using a default here causes r-a to not infer // return types of queries which is very annoying. Thus, until r-a support associated - // type defaults, plese restrain from using them here <3 + // type defaults, please restrain from using them here <3 // // r-a issue: <https://github.com/rust-lang/rust-analyzer/issues/13693> type CacheSelector; diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 2f6b7a3c860..568aa39e09a 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -97,7 +97,7 @@ rustc_queries! { /// Gives access to the HIR ID for the given `LocalDefId` owner `key` if any. /// - /// Definitions that were generated with no HIR, would be feeded to return `None`. + /// Definitions that were generated with no HIR, would be fed to return `None`. query opt_local_def_id_to_hir_id(key: LocalDefId) -> Option<hir::HirId>{ desc { |tcx| "getting HIR ID of `{}`", tcx.def_path_str(key.to_def_id()) } feedable diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index bc0ccc1ebc3..72caadaf661 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1347,7 +1347,7 @@ pub trait PrettyPrinter<'tcx>: p!(write("{}::{}", self.tcx().crate_name(def.did.krate), self.tcx().def_path(def.did).to_string_no_crate_verbose())) } } - defkind => bug!("`{:?}` has unexpcted defkind {:?}", ct, defkind), + defkind => bug!("`{:?}` has unexpected defkind {:?}", ct, defkind), } } ty::ConstKind::Infer(infer_ct) => { diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 24cbe8e8281..96c1577d52b 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -7,8 +7,8 @@ use crate::ty::subst::{GenericArg, InternalSubsts, SubstsRef}; use crate::ty::visit::ValidateBoundVars; use crate::ty::InferTy::*; use crate::ty::{ - self, AdtDef, Discr, FallibleTypeFolder, Term, Ty, TyCtxt, TypeFlags, TypeFoldable, - TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, + self, AdtDef, Discr, Term, Ty, TyCtxt, TypeFlags, TypeSuperVisitable, TypeVisitable, + TypeVisitableExt, TypeVisitor, }; use crate::ty::{List, ParamEnv}; use hir::def::DefKind; @@ -1156,81 +1156,6 @@ where } } -struct SkipBindersAt<'tcx> { - tcx: TyCtxt<'tcx>, - index: ty::DebruijnIndex, -} - -impl<'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for SkipBindersAt<'tcx> { - type Error = (); - - fn interner(&self) -> TyCtxt<'tcx> { - self.tcx - } - - fn try_fold_binder<T>(&mut self, t: Binder<'tcx, T>) -> Result<Binder<'tcx, T>, Self::Error> - where - T: ty::TypeFoldable<TyCtxt<'tcx>>, - { - self.index.shift_in(1); - let value = t.try_map_bound(|t| t.try_fold_with(self)); - self.index.shift_out(1); - value - } - - fn try_fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> { - if !ty.has_escaping_bound_vars() { - Ok(ty) - } else if let ty::Bound(index, bv) = *ty.kind() { - if index == self.index { - Err(()) - } else { - Ok(self.interner().mk_bound(index.shifted_out(1), bv)) - } - } else { - ty.try_super_fold_with(self) - } - } - - fn try_fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> { - if !r.has_escaping_bound_vars() { - Ok(r) - } else if let ty::ReLateBound(index, bv) = r.kind() { - if index == self.index { - Err(()) - } else { - Ok(self.interner().mk_re_late_bound(index.shifted_out(1), bv)) - } - } else { - r.try_super_fold_with(self) - } - } - - fn try_fold_const(&mut self, ct: ty::Const<'tcx>) -> Result<ty::Const<'tcx>, Self::Error> { - if !ct.has_escaping_bound_vars() { - Ok(ct) - } else if let ty::ConstKind::Bound(index, bv) = ct.kind() { - if index == self.index { - Err(()) - } else { - Ok(self.interner().mk_const( - ty::ConstKind::Bound(index.shifted_out(1), bv), - ct.ty().try_fold_with(self)?, - )) - } - } else { - ct.try_super_fold_with(self) - } - } - - fn try_fold_predicate( - &mut self, - p: ty::Predicate<'tcx>, - ) -> Result<ty::Predicate<'tcx>, Self::Error> { - if !p.has_escaping_bound_vars() { Ok(p) } else { p.try_super_fold_with(self) } - } -} - /// Represents the projection of an associated type. /// /// For a projection, this would be `<Ty as Trait<...>>::N`. @@ -1621,19 +1546,24 @@ impl<'tcx> Region<'tcx> { pub fn get_name(self) -> Option<Symbol> { if self.has_name() { - let name = match *self { + match *self { ty::ReEarlyBound(ebr) => Some(ebr.name), ty::ReLateBound(_, br) => br.kind.get_name(), ty::ReFree(fr) => fr.bound_region.get_name(), ty::ReStatic => Some(kw::StaticLifetime), ty::RePlaceholder(placeholder) => placeholder.bound.kind.get_name(), _ => None, - }; - - return name; + } + } else { + None } + } - None + pub fn get_name_or_anon(self) -> Symbol { + match self.get_name() { + Some(name) => name, + None => sym::anon, + } } /// Is this region named by the user? @@ -1767,10 +1697,10 @@ impl<'tcx> Region<'tcx> { matches!(self.kind(), ty::ReVar(_)) } - pub fn as_var(self) -> Option<RegionVid> { + pub fn as_var(self) -> RegionVid { match self.kind() { - ty::ReVar(vid) => Some(vid), - _ => None, + ty::ReVar(vid) => vid, + _ => bug!("expected region {:?} to be of kind ReVar", self), } } } diff --git a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs index 54028dfe87b..931fe1b2433 100644 --- a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs +++ b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs @@ -148,6 +148,11 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> { )), ) }, + @call("mir_offset", args) => { + let ptr = self.parse_operand(args[0])?; + let offset = self.parse_operand(args[1])?; + Ok(Rvalue::BinaryOp(BinOp::Offset, Box::new((ptr, offset)))) + }, @call("mir_len", args) => Ok(Rvalue::Len(self.parse_place(args[0])?)), ExprKind::Borrow { borrow_kind, arg } => Ok( Rvalue::Ref(self.tcx.lifetimes.re_erased, *borrow_kind, self.parse_place(*arg)?) diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index 2d52102db2c..4926ff85de3 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -2242,6 +2242,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { name, source_info: debug_source_info, value: VarDebugInfoContents::Place(for_arm_body.into()), + argument_index: None, }); let locals = if has_guard.0 { let ref_for_guard = self.local_decls.push(LocalDecl::<'tcx> { @@ -2260,6 +2261,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { name, source_info: debug_source_info, value: VarDebugInfoContents::Place(ref_for_guard.into()), + argument_index: None, }); LocalsForNode::ForGuard { ref_for_guard, for_arm_body } } else { diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index 415f5b1b1e1..bc50bcbc3d0 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -811,6 +811,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { name, source_info: SourceInfo::outermost(captured_place.var_ident.span), value: VarDebugInfoContents::Place(use_place), + argument_index: None, }); let capture = Capture { captured_place, use_place, mutability }; @@ -827,7 +828,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { expr: &Expr<'tcx>, ) -> BlockAnd<()> { // Allocate locals for the function arguments - for param in arguments.iter() { + for (argument_index, param) in arguments.iter().enumerate() { let source_info = SourceInfo::outermost(param.pat.as_ref().map_or(self.fn_span, |pat| pat.span)); let arg_local = @@ -839,6 +840,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { name, source_info, value: VarDebugInfoContents::Place(arg_local.into()), + argument_index: Some(argument_index as u16 + 1), }); } } diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index 431c3255ab2..43e787db41a 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -593,7 +593,7 @@ pub struct MultipleMutBorrows { #[primary_span] pub span: Span, #[subdiagnostic] - pub occurences: Vec<Conflict>, + pub occurrences: Vec<Conflict>, } #[derive(Diagnostic)] @@ -602,7 +602,7 @@ pub struct AlreadyBorrowed { #[primary_span] pub span: Span, #[subdiagnostic] - pub occurences: Vec<Conflict>, + pub occurrences: Vec<Conflict>, } #[derive(Diagnostic)] @@ -611,7 +611,7 @@ pub struct AlreadyMutBorrowed { #[primary_span] pub span: Span, #[subdiagnostic] - pub occurences: Vec<Conflict>, + pub occurrences: Vec<Conflict>, } #[derive(Diagnostic)] @@ -620,7 +620,7 @@ pub struct MovedWhileBorrowed { #[primary_span] pub span: Span, #[subdiagnostic] - pub occurences: Vec<Conflict>, + pub occurrences: Vec<Conflict>, } #[derive(Subdiagnostic)] diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index 0882b473f10..bac46db2b1e 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -966,30 +966,30 @@ fn check_borrow_conflicts_in_at_patterns<'tcx>(cx: &MatchVisitor<'_, '_, 'tcx>, let report_mut_ref = !conflicts_mut_ref.is_empty(); let report_move_conflict = !conflicts_move.is_empty(); - let mut occurences = match mut_outer { + let mut occurrences = match mut_outer { Mutability::Mut => vec![Conflict::Mut { span: pat.span, name }], Mutability::Not => vec![Conflict::Ref { span: pat.span, name }], }; - occurences.extend(conflicts_mut_mut); - occurences.extend(conflicts_mut_ref); - occurences.extend(conflicts_move); + occurrences.extend(conflicts_mut_mut); + occurrences.extend(conflicts_mut_ref); + occurrences.extend(conflicts_move); // Report errors if any. if report_mut_mut { // Report mutability conflicts for e.g. `ref mut x @ Some(ref mut y)`. - sess.emit_err(MultipleMutBorrows { span: pat.span, occurences }); + sess.emit_err(MultipleMutBorrows { span: pat.span, occurrences }); } else if report_mut_ref { // Report mutability conflicts for e.g. `ref x @ Some(ref mut y)` or the converse. match mut_outer { Mutability::Mut => { - sess.emit_err(AlreadyMutBorrowed { span: pat.span, occurences }); + sess.emit_err(AlreadyMutBorrowed { span: pat.span, occurrences }); } Mutability::Not => { - sess.emit_err(AlreadyBorrowed { span: pat.span, occurences }); + sess.emit_err(AlreadyBorrowed { span: pat.span, occurrences }); } }; } else if report_move_conflict { // Report by-ref and by-move conflicts, e.g. `ref x @ y`. - sess.emit_err(MovedWhileBorrowed { span: pat.span, occurences }); + sess.emit_err(MovedWhileBorrowed { span: pat.span, occurrences }); } } diff --git a/compiler/rustc_mir_dataflow/src/framework/graphviz.rs b/compiler/rustc_mir_dataflow/src/framework/graphviz.rs index c188105eae8..707729f8f21 100644 --- a/compiler/rustc_mir_dataflow/src/framework/graphviz.rs +++ b/compiler/rustc_mir_dataflow/src/framework/graphviz.rs @@ -394,8 +394,8 @@ where ) -> io::Result<()> { let diffs = StateDiffCollector::run(body, block, self.results.results(), self.style); - let mut befores = diffs.before.map(|v| v.into_iter()); - let mut afters = diffs.after.into_iter(); + let mut diffs_before = diffs.before.map(|v| v.into_iter()); + let mut diffs_after = diffs.after.into_iter(); let next_in_dataflow_order = |it: &mut std::vec::IntoIter<_>| { if A::Direction::IS_FORWARD { it.next().unwrap() } else { it.next_back().unwrap() } @@ -405,8 +405,8 @@ where let statement_str = format!("{statement:?}"); let index_str = format!("{i}"); - let after = next_in_dataflow_order(&mut afters); - let before = befores.as_mut().map(next_in_dataflow_order); + let after = next_in_dataflow_order(&mut diffs_after); + let before = diffs_before.as_mut().map(next_in_dataflow_order); self.write_row(w, &index_str, &statement_str, |_this, w, fmt| { if let Some(before) = before { @@ -417,11 +417,11 @@ where })?; } - let after = next_in_dataflow_order(&mut afters); - let before = befores.as_mut().map(next_in_dataflow_order); + let after = next_in_dataflow_order(&mut diffs_after); + let before = diffs_before.as_mut().map(next_in_dataflow_order); - assert!(afters.is_empty()); - assert!(befores.as_ref().map_or(true, ExactSizeIterator::is_empty)); + assert!(diffs_after.is_empty()); + assert!(diffs_before.as_ref().map_or(true, ExactSizeIterator::is_empty)); let terminator = body[block].terminator(); let mut terminator_str = String::new(); diff --git a/compiler/rustc_mir_transform/src/dest_prop.rs b/compiler/rustc_mir_transform/src/dest_prop.rs index 811935aa990..39164917770 100644 --- a/compiler/rustc_mir_transform/src/dest_prop.rs +++ b/compiler/rustc_mir_transform/src/dest_prop.rs @@ -83,7 +83,7 @@ //! that ever have their address taken. Of course that requires actually having alias analysis //! (and a model to build it on), so this might be a bit of a ways off. //! -//! * Various perf improvents. There are a bunch of comments in here marked `PERF` with ideas for +//! * Various perf improvements. There are a bunch of comments in here marked `PERF` with ideas for //! how to do things more efficiently. However, the complexity of the pass as a whole should be //! kept in mind. //! diff --git a/compiler/rustc_mir_transform/src/generator.rs b/compiler/rustc_mir_transform/src/generator.rs index 159780319ba..4c4423721fb 100644 --- a/compiler/rustc_mir_transform/src/generator.rs +++ b/compiler/rustc_mir_transform/src/generator.rs @@ -1556,6 +1556,13 @@ impl<'tcx> MirPass<'tcx> for StateTransform { body.arg_count = 2; // self, resume arg body.spread_arg = None; + // The original arguments to the function are no longer arguments, mark them as such. + // Otherwise they'll conflict with our new arguments, which although they don't have + // argument_index set, will get emitted as unnamed arguments. + for var in &mut body.var_debug_info { + var.argument_index = None; + } + body.generator.as_mut().unwrap().yield_ty = None; body.generator.as_mut().unwrap().generator_layout = Some(layout); diff --git a/compiler/rustc_mir_transform/src/unreachable_prop.rs b/compiler/rustc_mir_transform/src/unreachable_prop.rs index d4b1cfe4337..bd1724bf842 100644 --- a/compiler/rustc_mir_transform/src/unreachable_prop.rs +++ b/compiler/rustc_mir_transform/src/unreachable_prop.rs @@ -99,7 +99,7 @@ where // // This generates a `switchInt() -> [0: 0, 1: 1, otherwise: unreachable]`, which allows us or LLVM to // turn it into just `x` later. Without the unreachable, such a transformation would be illegal. - // If the otherwise branch is unreachable, we can delete all other unreacahble targets, as they will + // If the otherwise branch is unreachable, we can delete all other unreachable targets, as they will // still point to the unreachable and therefore not lose reachability information. let reachable_iter = targets.iter().filter(|(_, bb)| !is_unreachable(*bb)); diff --git a/compiler/rustc_monomorphize/src/partitioning/mod.rs b/compiler/rustc_monomorphize/src/partitioning/mod.rs index 7ac1c9e057e..18aa0742c09 100644 --- a/compiler/rustc_monomorphize/src/partitioning/mod.rs +++ b/compiler/rustc_monomorphize/src/partitioning/mod.rs @@ -474,7 +474,7 @@ fn collect_and_partition_mono_items(tcx: TyCtxt<'_>, (): ()) -> (&DefIdSet, &[Co (tcx.arena.alloc(mono_items), codegen_units) } -/// Outputs stats about instantation counts and estimated size, per `MonoItem`'s +/// Outputs stats about instantiation counts and estimated size, per `MonoItem`'s /// def, to a file in the given output directory. fn dump_mono_items_stats<'tcx>( tcx: TyCtxt<'tcx>, diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl index e21bbd0217b..f11d0ed0f01 100644 --- a/compiler/rustc_parse/messages.ftl +++ b/compiler/rustc_parse/messages.ftl @@ -738,3 +738,7 @@ parse_box_syntax_removed = `box_syntax` has been removed parse_bad_return_type_notation_output = return type not allowed with return type notation .suggestion = remove the return type + +parse_bad_return_type_notation_dotdot = + return type notation uses `()` instead of `(..)` for elided arguments + .suggestion = remove the `..` diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index aead216b61c..069217165fa 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -2324,3 +2324,11 @@ pub(crate) struct BadReturnTypeNotationOutput { #[suggestion(code = "", applicability = "maybe-incorrect")] pub span: Span, } + +#[derive(Diagnostic)] +#[diag(parse_bad_return_type_notation_dotdot)] +pub(crate) struct BadReturnTypeNotationDotDot { + #[primary_span] + #[suggestion(code = "", applicability = "maybe-incorrect")] + pub span: Span, +} diff --git a/compiler/rustc_parse/src/lexer/diagnostics.rs b/compiler/rustc_parse/src/lexer/diagnostics.rs index c4b9fdc81c5..9e6d27bf036 100644 --- a/compiler/rustc_parse/src/lexer/diagnostics.rs +++ b/compiler/rustc_parse/src/lexer/diagnostics.rs @@ -21,7 +21,7 @@ pub struct TokenTreeDiagInfo { pub matching_block_spans: Vec<(Span, Span)>, } -pub fn same_identation_level(sm: &SourceMap, open_sp: Span, close_sp: Span) -> bool { +pub fn same_indentation_level(sm: &SourceMap, open_sp: Span, close_sp: Span) -> bool { match (sm.span_to_margin(open_sp), sm.span_to_margin(close_sp)) { (Some(open_padding), Some(close_padding)) => open_padding == close_padding, _ => false, @@ -67,13 +67,13 @@ pub fn report_suspicious_mismatch_block( let mut matched_spans: Vec<(Span, bool)> = diag_info .matching_block_spans .iter() - .map(|&(open, close)| (open.with_hi(close.lo()), same_identation_level(sm, open, close))) + .map(|&(open, close)| (open.with_hi(close.lo()), same_indentation_level(sm, open, close))) .collect(); // sort by `lo`, so the large block spans in the front matched_spans.sort_by_key(|(span, _)| span.lo()); - // We use larger block whose identation is well to cover those inner mismatched blocks + // We use larger block whose indentation is well to cover those inner mismatched blocks // O(N^2) here, but we are on error reporting path, so it is fine for i in 0..matched_spans.len() { let (block_span, same_ident) = matched_spans[i]; diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs index e41d0f7047b..9e856c9f212 100644 --- a/compiler/rustc_parse/src/lexer/mod.rs +++ b/compiler/rustc_parse/src/lexer/mod.rs @@ -223,21 +223,16 @@ impl<'a> StringReader<'a> { }; token::Literal(token::Lit { kind, symbol, suffix }) } - rustc_lexer::TokenKind::Lifetime { starts_with_number, contains_emoji } => { + rustc_lexer::TokenKind::Lifetime { starts_with_number } => { // Include the leading `'` in the real identifier, for macro // expansion purposes. See #12512 for the gory details of why // this is necessary. let lifetime_name = self.str_from(start); if starts_with_number { let span = self.mk_sp(start, self.pos); - let mut diag = self.sess.struct_err("lifetimes or labels cannot start with a number"); + let mut diag = self.sess.struct_err("lifetimes cannot start with a number"); diag.set_span(span); diag.stash(span, StashKey::LifetimeIsChar); - } else if contains_emoji { - let span = self.mk_sp(start, self.pos); - let mut diag = self.sess.struct_err("lifetimes or labels cannot contain emojis"); - diag.set_span(span); - diag.stash(span, StashKey::LifetimeContainsEmoji); } let ident = Symbol::intern(lifetime_name); token::Lifetime(ident) diff --git a/compiler/rustc_parse/src/lexer/tokentrees.rs b/compiler/rustc_parse/src/lexer/tokentrees.rs index 36fd1e37d65..7c2c0895193 100644 --- a/compiler/rustc_parse/src/lexer/tokentrees.rs +++ b/compiler/rustc_parse/src/lexer/tokentrees.rs @@ -1,5 +1,5 @@ use super::diagnostics::report_suspicious_mismatch_block; -use super::diagnostics::same_identation_level; +use super::diagnostics::same_indentation_level; use super::diagnostics::TokenTreeDiagInfo; use super::{StringReader, UnmatchedDelim}; use rustc_ast::token::{self, Delimiter, Token}; @@ -153,7 +153,7 @@ impl<'a> TokenTreesReader<'a> { unclosed_delimiter = Some(sp); }; for (brace, brace_span) in &self.diag_info.open_braces { - if same_identation_level(&sm, self.token.span, *brace_span) + if same_indentation_level(&sm, self.token.span, *brace_span) && brace == &close_delim { // high likelihood of these two corresponding diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index c4605e63cf3..03c82fbd329 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -2767,7 +2767,7 @@ impl<'a> Parser<'a> { (token::DotDotEq, token::Gt) ) { // `error_inclusive_range_match_arrow` handles cases like `0..=> {}`, - // so we supress the error here + // so we suppress the error here err.delay_as_bug(); this.bump(); } else { diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index f1c9f0109f8..c25c23d849f 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -290,16 +290,17 @@ impl<'a> Parser<'a> { })?; let span = lo.to(self.prev_token.span); AngleBracketedArgs { args, span }.into() - } else if self.token.kind == token::OpenDelim(Delimiter::Parenthesis) + } else if self.may_recover() + && self.token.kind == token::OpenDelim(Delimiter::Parenthesis) // FIXME(return_type_notation): Could also recover `...` here. && self.look_ahead(1, |tok| tok.kind == token::DotDot) { - let lo = self.token.span; self.bump(); + self.sess + .emit_err(errors::BadReturnTypeNotationDotDot { span: self.token.span }); self.bump(); self.expect(&token::CloseDelim(Delimiter::Parenthesis))?; let span = lo.to(self.prev_token.span); - self.sess.gated_spans.gate(sym::return_type_notation, span); if self.eat_noexpect(&token::RArrow) { let lo = self.prev_token.span; @@ -308,7 +309,13 @@ impl<'a> Parser<'a> { .emit_err(errors::BadReturnTypeNotationOutput { span: lo.to(ty.span) }); } - P(GenericArgs::ReturnTypeNotation(span)) + ParenthesizedArgs { + span, + inputs: ThinVec::new(), + inputs_span: span, + output: ast::FnRetTy::Default(self.prev_token.span.shrink_to_hi()), + } + .into() } else { // `(T, U) -> R` let (inputs, _) = self.parse_paren_comma_seq(|p| p.parse_ty())?; @@ -566,13 +573,13 @@ impl<'a> Parser<'a> { }; let span = lo.to(self.prev_token.span); - // Gate associated type bounds, e.g., `Iterator<Item: Ord>`. if let AssocConstraintKind::Bound { .. } = kind { - if gen_args.as_ref().map_or(false, |args| { - matches!(args, GenericArgs::ReturnTypeNotation(..)) - }) { - // This is already gated in `parse_path_segment` + if let Some(ast::GenericArgs::Parenthesized(args)) = &gen_args + && args.inputs.is_empty() + && matches!(args.output, ast::FnRetTy::Default(..)) + { + self.sess.gated_spans.gate(sym::return_type_notation, span); } else { self.sess.gated_spans.gate(sym::associated_type_bounds, span); } diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs index 1c5410c5658..7de84db211e 100644 --- a/compiler/rustc_parse_format/src/lib.rs +++ b/compiler/rustc_parse_format/src/lib.rs @@ -909,7 +909,7 @@ fn find_width_map_from_snippet( // Strip quotes. let snippet = &snippet[1..snippet.len() - 1]; - // Macros like `println` add a newline at the end. That technically doens't make them "literals" anymore, but it's fine + // Macros like `println` add a newline at the end. That technically doesn't make them "literals" anymore, but it's fine // since we will never need to point our spans there, so we lie about it here by ignoring it. // Since there might actually be newlines in the source code, we need to normalize away all trailing newlines. // If we only trimmed it off the input, `format!("\n")` would cause a mismatch as here we they actually match up. diff --git a/compiler/rustc_passes/src/hir_id_validator.rs b/compiler/rustc_passes/src/hir_id_validator.rs index 9418f3cd322..3942a73befd 100644 --- a/compiler/rustc_passes/src/hir_id_validator.rs +++ b/compiler/rustc_passes/src/hir_id_validator.rs @@ -8,8 +8,6 @@ use rustc_middle::hir::nested_filter; use rustc_middle::ty::TyCtxt; pub fn check_crate(tcx: TyCtxt<'_>) { - tcx.dep_graph.assert_ignored(); - if tcx.sess.opts.unstable_opts.hir_stats { crate::hir_stats::print_hir_stats(tcx); } diff --git a/compiler/rustc_passes/src/hir_stats.rs b/compiler/rustc_passes/src/hir_stats.rs index ce44f709f3b..47e032758f2 100644 --- a/compiler/rustc_passes/src/hir_stats.rs +++ b/compiler/rustc_passes/src/hir_stats.rs @@ -666,7 +666,7 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> { fn visit_generic_args(&mut self, g: &'v ast::GenericArgs) { record_variants!( (self, g, g, Id::None, ast, GenericArgs, GenericArgs), - [AngleBracketed, Parenthesized, ReturnTypeNotation] + [AngleBracketed, Parenthesized] ); ast_visit::walk_generic_args(self, g) } diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs index 534d13b1ae0..a9a2e6dd04c 100644 --- a/compiler/rustc_query_system/src/dep_graph/graph.rs +++ b/compiler/rustc_query_system/src/dep_graph/graph.rs @@ -143,7 +143,7 @@ impl<K: DepKind> DepGraph<K> { assert_eq!(_green_node_index, DepNodeIndex::SINGLETON_DEPENDENCYLESS_ANON_NODE); // Instantiate a dependy-less red node only once for anonymous queries. - let (_red_node_index, _prev_and_index) = current.intern_node( + let (red_node_index, red_node_prev_index_and_color) = current.intern_node( profiler, &prev_graph, DepNode { kind: DepKind::RED, hash: Fingerprint::ZERO.into() }, @@ -151,8 +151,21 @@ impl<K: DepKind> DepGraph<K> { None, false, ); - assert_eq!(_red_node_index, DepNodeIndex::FOREVER_RED_NODE); - assert!(matches!(_prev_and_index, None | Some((_, DepNodeColor::Red)))); + assert_eq!(red_node_index, DepNodeIndex::FOREVER_RED_NODE); + match red_node_prev_index_and_color { + None => { + // This is expected when we have no previous compilation session. + assert!(prev_graph_node_count == 0); + } + Some((prev_red_node_index, DepNodeColor::Red)) => { + assert_eq!(prev_red_node_index.as_usize(), red_node_index.as_usize()); + colors.insert(prev_red_node_index, DepNodeColor::Red); + } + Some((_, DepNodeColor::Green(_))) => { + // There must be a logic error somewhere if we hit this branch. + panic!("DepNodeIndex::FOREVER_RED_NODE evaluated to DepNodeColor::Green") + } + } DepGraph { data: Some(Lrc::new(DepGraphData { @@ -353,10 +366,8 @@ impl<K: DepKind> DepGraphData<K> { })) }; - let task_deps_ref = match &task_deps { - Some(deps) => TaskDepsRef::Allow(deps), - None => TaskDepsRef::Ignore, - }; + let task_deps_ref = + task_deps.as_ref().map(TaskDepsRef::Allow).unwrap_or(TaskDepsRef::EvalAlways); let result = K::with_deps(task_deps_ref, || task(cx, arg)); let edges = task_deps.map_or_else(|| smallvec![], |lock| lock.into_inner().reads); @@ -461,6 +472,11 @@ impl<K: DepKind> DepGraph<K> { K::read_deps(|task_deps| { let mut task_deps = match task_deps { TaskDepsRef::Allow(deps) => deps.lock(), + TaskDepsRef::EvalAlways => { + // We don't need to record dependencies of eval_always + // queries. They are re-evaluated unconditionally anyway. + return; + } TaskDepsRef::Ignore => return, TaskDepsRef::Forbid => { panic!("Illegal read of: {dep_node_index:?}") @@ -563,7 +579,10 @@ impl<K: DepKind> DepGraph<K> { let mut edges = SmallVec::new(); K::read_deps(|task_deps| match task_deps { TaskDepsRef::Allow(deps) => edges.extend(deps.lock().reads.iter().copied()), - TaskDepsRef::Ignore => {} // During HIR lowering, we have no dependencies. + TaskDepsRef::EvalAlways => { + edges.push(DepNodeIndex::FOREVER_RED_NODE); + } + TaskDepsRef::Ignore => {} TaskDepsRef::Forbid => { panic!("Cannot summarize when dependencies are not recorded.") } @@ -1356,10 +1375,13 @@ pub enum TaskDepsRef<'a, K: DepKind> { /// `TaskDeps`. This is used when executing a 'normal' query /// (no `eval_always` modifier) Allow(&'a Lock<TaskDeps<K>>), - /// New dependencies are ignored. This is used when - /// executing an `eval_always` query, since there's no + /// This is used when executing an `eval_always` query. We don't /// need to track dependencies for a query that's always - /// re-executed. This is also used for `dep_graph.with_ignore` + /// re-executed -- but we need to know that this is an `eval_always` + /// query in order to emit dependencies to `DepNodeIndex::FOREVER_RED_NODE` + /// when directly feeding other queries. + EvalAlways, + /// New dependencies are ignored. This is also used for `dep_graph.with_ignore`. Ignore, /// Any attempt to add new dependencies will cause a panic. /// This is used when decoding a query result from disk, diff --git a/compiler/rustc_resolve/messages.ftl b/compiler/rustc_resolve/messages.ftl index 2628f247c54..01f002c9408 100644 --- a/compiler/rustc_resolve/messages.ftl +++ b/compiler/rustc_resolve/messages.ftl @@ -42,7 +42,7 @@ resolve_try_adding_local_generic_param_on_method = try adding a local generic parameter in this method instead resolve_help_try_using_local_generic_param = - try using a local generic paramter instead + try using a local generic parameter instead resolve_name_is_already_used_as_generic_parameter = the name `{$name}` is already used for a generic parameter in this item's generic parameters diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 31ac3f1c151..90a2fa89cd2 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -598,7 +598,7 @@ struct LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { /// The current set of local scopes for types and values. ribs: PerNS<Vec<Rib<'a>>>, - /// Previous poped `rib`, only used for diagnostic. + /// Previous popped `rib`, only used for diagnostic. last_block_rib: Option<Rib<'a>>, /// The current set of local scopes, for labels. @@ -1116,7 +1116,6 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast, } } } - GenericArgs::ReturnTypeNotation(_span) => {} } } } diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 99fad22d4a1..572b0c4cf64 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -312,7 +312,6 @@ impl<'a> From<&'a ast::PathSegment> for Segment { (args.span, found_lifetimes) } GenericArgs::Parenthesized(args) => (args.span, true), - GenericArgs::ReturnTypeNotation(span) => (*span, false), } } else { (DUMMY_SP, false) @@ -1652,7 +1651,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { misc2: AmbiguityErrorMisc::None, }; if !self.matches_previous_ambiguity_error(&ambiguity_error) { - // avoid dumplicated span information to be emitt out + // avoid duplicated span information to be emitt out self.ambiguity_errors.push(ambiguity_error); } } diff --git a/compiler/rustc_span/src/edit_distance.rs b/compiler/rustc_span/src/edit_distance.rs index 9fe9e3a7a5f..259f4238654 100644 --- a/compiler/rustc_span/src/edit_distance.rs +++ b/compiler/rustc_span/src/edit_distance.rs @@ -219,7 +219,7 @@ fn find_best_match_for_name_impl( } // We have a tie among several candidates, try to select the best among them ignoring substrings. - // For example, the candidates list `force_capture`, `capture`, and user inputed `forced_capture`, + // For example, the candidates list `force_capture`, `capture`, and user inputted `forced_capture`, // we select `force_capture` with a extra round of edit distance calculation. if next_candidates.len() > 1 { debug_assert!(use_substring_score); diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs index 0bb42a3a71f..08c4414034a 100644 --- a/compiler/rustc_span/src/hygiene.rs +++ b/compiler/rustc_span/src/hygiene.rs @@ -1207,7 +1207,7 @@ impl HygieneEncodeContext { // a `SyntaxContext` that we haven't seen before while !self.latest_ctxts.lock().is_empty() || !self.latest_expns.lock().is_empty() { debug!( - "encode_hygiene: Serializing a round of {:?} SyntaxContextDatas: {:?}", + "encode_hygiene: Serializing a round of {:?} SyntaxContextData: {:?}", self.latest_ctxts.lock().len(), self.latest_ctxts ); diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 7affad9aa01..6bfae377152 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -357,6 +357,7 @@ symbols! { always, and, and_then, + anon, anonymous_lifetime_in_impl_trait, any, append_const_msg, @@ -800,6 +801,7 @@ symbols! { ignore, impl_header_lifetime_elision, impl_lint_pass, + impl_trait_in_assoc_type, impl_trait_in_bindings, impl_trait_in_fn_trait_return, impl_trait_projections, @@ -1173,7 +1175,9 @@ symbols! { reg32, reg64, reg_abcd, + reg_addr, reg_byte, + reg_data, reg_iw, reg_nonzero, reg_pair, diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs index a0730fbb650..57011aa8a14 100644 --- a/compiler/rustc_target/src/abi/call/mod.rs +++ b/compiler/rustc_target/src/abi/call/mod.rs @@ -755,7 +755,7 @@ impl FromStr for Conv { "AmdGpuKernel" => Ok(Conv::AmdGpuKernel), "AvrInterrupt" => Ok(Conv::AvrInterrupt), "AvrNonBlockingInterrupt" => Ok(Conv::AvrNonBlockingInterrupt), - _ => Err(format!("'{s}' is not a valid value for entry function call convetion.")), + _ => Err(format!("'{s}' is not a valid value for entry function call convention.")), } } } diff --git a/compiler/rustc_target/src/asm/m68k.rs b/compiler/rustc_target/src/asm/m68k.rs new file mode 100644 index 00000000000..8c857550cf2 --- /dev/null +++ b/compiler/rustc_target/src/asm/m68k.rs @@ -0,0 +1,81 @@ +use super::{InlineAsmArch, InlineAsmType}; +use rustc_macros::HashStable_Generic; +use rustc_span::Symbol; +use std::fmt; + +def_reg_class! { + M68k M68kInlineAsmRegClass { + reg, + reg_addr, + reg_data, + } +} + +impl M68kInlineAsmRegClass { + pub fn valid_modifiers(self, _arch: super::InlineAsmArch) -> &'static [char] { + &[] + } + + pub fn suggest_class(self, _arch: InlineAsmArch, _ty: InlineAsmType) -> Option<Self> { + None + } + + pub fn suggest_modifier( + self, + _arch: InlineAsmArch, + _ty: InlineAsmType, + ) -> Option<(char, &'static str)> { + None + } + + pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<(char, &'static str)> { + None + } + + pub fn supported_types( + self, + _arch: InlineAsmArch, + ) -> &'static [(InlineAsmType, Option<Symbol>)] { + match self { + Self::reg => types! { _: I16, I32; }, + Self::reg_data => types! { _: I8, I16, I32; }, + Self::reg_addr => types! { _: I16, I32; }, + } + } +} + +def_regs! { + M68k M68kInlineAsmReg M68kInlineAsmRegClass { + d0: reg, reg_data = ["d0"], + d1: reg, reg_data = ["d1"], + d2: reg, reg_data = ["d2"], + d3: reg, reg_data = ["d3"], + d4: reg, reg_data = ["d4"], + d5: reg, reg_data = ["d5"], + d6: reg, reg_data = ["d6"], + d7: reg, reg_data = ["d7"], + a0: reg, reg_addr = ["a0"], + a1: reg, reg_addr = ["a1"], + a2: reg, reg_addr = ["a2"], + a3: reg, reg_addr = ["a3"], + #error = ["a4"] => + "a4 is used internally by LLVM and cannot be used as an operand for inline asm", + #error = ["a5", "bp"] => + "a5 is used internally by LLVM and cannot be used as an operand for inline asm", + #error = ["a6", "fp"] => + "a6 is used internally by LLVM and cannot be used as an operand for inline asm", + #error = ["a7", "sp", "usp", "ssp", "isp"] => + "the stack pointer cannot be used as an operand for inline asm", + } +} + +impl M68kInlineAsmReg { + pub fn emit( + self, + out: &mut dyn fmt::Write, + _arch: InlineAsmArch, + _modifier: Option<char>, + ) -> fmt::Result { + out.write_str(self.name()) + } +} diff --git a/compiler/rustc_target/src/asm/mod.rs b/compiler/rustc_target/src/asm/mod.rs index 0dbfd426781..3f9c850b352 100644 --- a/compiler/rustc_target/src/asm/mod.rs +++ b/compiler/rustc_target/src/asm/mod.rs @@ -168,6 +168,7 @@ mod arm; mod avr; mod bpf; mod hexagon; +mod m68k; mod mips; mod msp430; mod nvptx; @@ -183,6 +184,7 @@ pub use arm::{ArmInlineAsmReg, ArmInlineAsmRegClass}; pub use avr::{AvrInlineAsmReg, AvrInlineAsmRegClass}; pub use bpf::{BpfInlineAsmReg, BpfInlineAsmRegClass}; pub use hexagon::{HexagonInlineAsmReg, HexagonInlineAsmRegClass}; +pub use m68k::{M68kInlineAsmReg, M68kInlineAsmRegClass}; pub use mips::{MipsInlineAsmReg, MipsInlineAsmRegClass}; pub use msp430::{Msp430InlineAsmReg, Msp430InlineAsmRegClass}; pub use nvptx::{NvptxInlineAsmReg, NvptxInlineAsmRegClass}; @@ -214,6 +216,7 @@ pub enum InlineAsmArch { Bpf, Avr, Msp430, + M68k, } impl FromStr for InlineAsmArch { @@ -240,6 +243,7 @@ impl FromStr for InlineAsmArch { "bpf" => Ok(Self::Bpf), "avr" => Ok(Self::Avr), "msp430" => Ok(Self::Msp430), + "m68k" => Ok(Self::M68k), _ => Err(()), } } @@ -262,6 +266,7 @@ pub enum InlineAsmReg { Bpf(BpfInlineAsmReg), Avr(AvrInlineAsmReg), Msp430(Msp430InlineAsmReg), + M68k(M68kInlineAsmReg), // Placeholder for invalid register constraints for the current target Err, } @@ -280,6 +285,7 @@ impl InlineAsmReg { Self::Bpf(r) => r.name(), Self::Avr(r) => r.name(), Self::Msp430(r) => r.name(), + Self::M68k(r) => r.name(), Self::Err => "<reg>", } } @@ -297,6 +303,7 @@ impl InlineAsmReg { Self::Bpf(r) => InlineAsmRegClass::Bpf(r.reg_class()), Self::Avr(r) => InlineAsmRegClass::Avr(r.reg_class()), Self::Msp430(r) => InlineAsmRegClass::Msp430(r.reg_class()), + Self::M68k(r) => InlineAsmRegClass::M68k(r.reg_class()), Self::Err => InlineAsmRegClass::Err, } } @@ -328,6 +335,7 @@ impl InlineAsmReg { InlineAsmArch::Bpf => Self::Bpf(BpfInlineAsmReg::parse(name)?), InlineAsmArch::Avr => Self::Avr(AvrInlineAsmReg::parse(name)?), InlineAsmArch::Msp430 => Self::Msp430(Msp430InlineAsmReg::parse(name)?), + InlineAsmArch::M68k => Self::M68k(M68kInlineAsmReg::parse(name)?), }) } @@ -351,6 +359,7 @@ impl InlineAsmReg { Self::Bpf(r) => r.validate(arch, reloc_model, target_features, target, is_clobber), Self::Avr(r) => r.validate(arch, reloc_model, target_features, target, is_clobber), Self::Msp430(r) => r.validate(arch, reloc_model, target_features, target, is_clobber), + Self::M68k(r) => r.validate(arch, reloc_model, target_features, target, is_clobber), Self::Err => unreachable!(), } } @@ -375,6 +384,7 @@ impl InlineAsmReg { Self::Bpf(r) => r.emit(out, arch, modifier), Self::Avr(r) => r.emit(out, arch, modifier), Self::Msp430(r) => r.emit(out, arch, modifier), + Self::M68k(r) => r.emit(out, arch, modifier), Self::Err => unreachable!("Use of InlineAsmReg::Err"), } } @@ -392,6 +402,7 @@ impl InlineAsmReg { Self::Bpf(r) => r.overlapping_regs(|r| cb(Self::Bpf(r))), Self::Avr(r) => r.overlapping_regs(|r| cb(Self::Avr(r))), Self::Msp430(_) => cb(self), + Self::M68k(_) => cb(self), Self::Err => unreachable!("Use of InlineAsmReg::Err"), } } @@ -414,6 +425,7 @@ pub enum InlineAsmRegClass { Bpf(BpfInlineAsmRegClass), Avr(AvrInlineAsmRegClass), Msp430(Msp430InlineAsmRegClass), + M68k(M68kInlineAsmRegClass), // Placeholder for invalid register constraints for the current target Err, } @@ -435,6 +447,7 @@ impl InlineAsmRegClass { Self::Bpf(r) => r.name(), Self::Avr(r) => r.name(), Self::Msp430(r) => r.name(), + Self::M68k(r) => r.name(), Self::Err => rustc_span::symbol::sym::reg, } } @@ -458,6 +471,7 @@ impl InlineAsmRegClass { Self::Bpf(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Bpf), Self::Avr(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Avr), Self::Msp430(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Msp430), + Self::M68k(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::M68k), Self::Err => unreachable!("Use of InlineAsmRegClass::Err"), } } @@ -488,6 +502,7 @@ impl InlineAsmRegClass { Self::Bpf(r) => r.suggest_modifier(arch, ty), Self::Avr(r) => r.suggest_modifier(arch, ty), Self::Msp430(r) => r.suggest_modifier(arch, ty), + Self::M68k(r) => r.suggest_modifier(arch, ty), Self::Err => unreachable!("Use of InlineAsmRegClass::Err"), } } @@ -514,6 +529,7 @@ impl InlineAsmRegClass { Self::Bpf(r) => r.default_modifier(arch), Self::Avr(r) => r.default_modifier(arch), Self::Msp430(r) => r.default_modifier(arch), + Self::M68k(r) => r.default_modifier(arch), Self::Err => unreachable!("Use of InlineAsmRegClass::Err"), } } @@ -539,6 +555,7 @@ impl InlineAsmRegClass { Self::Bpf(r) => r.supported_types(arch), Self::Avr(r) => r.supported_types(arch), Self::Msp430(r) => r.supported_types(arch), + Self::M68k(r) => r.supported_types(arch), Self::Err => unreachable!("Use of InlineAsmRegClass::Err"), } } @@ -569,6 +586,7 @@ impl InlineAsmRegClass { InlineAsmArch::Bpf => Self::Bpf(BpfInlineAsmRegClass::parse(name)?), InlineAsmArch::Avr => Self::Avr(AvrInlineAsmRegClass::parse(name)?), InlineAsmArch::Msp430 => Self::Msp430(Msp430InlineAsmRegClass::parse(name)?), + InlineAsmArch::M68k => Self::M68k(M68kInlineAsmRegClass::parse(name)?), }) } @@ -590,6 +608,7 @@ impl InlineAsmRegClass { Self::Bpf(r) => r.valid_modifiers(arch), Self::Avr(r) => r.valid_modifiers(arch), Self::Msp430(r) => r.valid_modifiers(arch), + Self::M68k(r) => r.valid_modifiers(arch), Self::Err => unreachable!("Use of InlineAsmRegClass::Err"), } } @@ -776,6 +795,11 @@ pub fn allocatable_registers( msp430::fill_reg_map(arch, reloc_model, target_features, target, &mut map); map } + InlineAsmArch::M68k => { + let mut map = m68k::regclass_map(); + m68k::fill_reg_map(arch, reloc_model, target_features, target, &mut map); + map + } } } diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 192b2ab0ca2..4e5a821f0f6 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -123,7 +123,7 @@ pub enum Lld { /// target properties, in accordance with the first design goal. /// /// The first component of the flavor is tightly coupled with the compilation target, -/// while the `Cc` and `Lld` flags can vary withing the same target. +/// while the `Cc` and `Lld` flags can vary within the same target. #[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)] pub enum LinkerFlavor { /// Unix-like linker with GNU extensions (both naked and compiler-wrapped forms). diff --git a/compiler/rustc_trait_selection/src/solve/canonicalize.rs b/compiler/rustc_trait_selection/src/solve/canonicalize.rs index 55025e2e72b..25e7439ece7 100644 --- a/compiler/rustc_trait_selection/src/solve/canonicalize.rs +++ b/compiler/rustc_trait_selection/src/solve/canonicalize.rs @@ -13,7 +13,7 @@ use rustc_middle::ty::TypeVisitableExt; use rustc_middle::ty::{self, Ty}; use rustc_middle::ty::{TypeFoldable, TypeFolder, TypeSuperFoldable}; -/// Whether we're canonicalizing a query input or the query reponse. +/// Whether we're canonicalizing a query input or the query response. /// /// When canonicalizing an input we're in the context of the caller /// while canonicalizing the response happens in the context of the @@ -21,7 +21,7 @@ use rustc_middle::ty::{TypeFoldable, TypeFolder, TypeSuperFoldable}; #[derive(Debug, Clone, Copy)] pub enum CanonicalizeMode { Input, - /// FIXME: We currently return region constraints refering to + /// FIXME: We currently return region constraints referring to /// placeholders and inference variables from a binder instantiated /// inside of the query. /// diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs index 861fa0a305a..ada868705c7 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs @@ -42,7 +42,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { /// /// - `var_values`: a map from bound variables in the canonical goal to /// the values inferred while solving the instantiated goal. - /// - `external_constraints`: additional constraints which aren't expressable + /// - `external_constraints`: additional constraints which aren't expressible /// using simple unification of inference variables. #[instrument(level = "debug", skip(self))] pub(in crate::solve) fn evaluate_added_goals_and_make_canonical_response( @@ -113,7 +113,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { } /// This returns the substitutions to instantiate the bound variables of - /// the canonical reponse. This depends on the `original_values` for the + /// the canonical response. This depends on the `original_values` for the /// bound variables. fn compute_query_response_substitution( &self, diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs index 76a2a587911..32bd10f0beb 100644 --- a/compiler/rustc_trait_selection/src/solve/fulfill.rs +++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs @@ -1,6 +1,7 @@ use std::mem; use rustc_infer::infer::InferCtxt; +use rustc_infer::traits::solve::MaybeCause; use rustc_infer::traits::Obligation; use rustc_infer::traits::{ query::NoSolution, FulfillmentError, FulfillmentErrorCode, MismatchedProjectionTypes, @@ -41,13 +42,31 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> { self.obligations.push(obligation); } - fn collect_remaining_errors(&mut self) -> Vec<FulfillmentError<'tcx>> { + fn collect_remaining_errors(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<FulfillmentError<'tcx>> { self.obligations .drain(..) - .map(|obligation| FulfillmentError { - obligation: obligation.clone(), - code: FulfillmentErrorCode::CodeAmbiguity, - root_obligation: obligation, + .map(|obligation| { + let code = + infcx.probe(|_| match infcx.evaluate_root_goal(obligation.clone().into()) { + Ok((_, Certainty::Maybe(MaybeCause::Ambiguity), _)) => { + FulfillmentErrorCode::CodeAmbiguity { overflow: false } + } + Ok((_, Certainty::Maybe(MaybeCause::Overflow), _)) => { + FulfillmentErrorCode::CodeAmbiguity { overflow: true } + } + Ok((_, Certainty::Yes, _)) => { + bug!("did not expect successful goal when collecting ambiguity errors") + } + Err(_) => { + bug!("did not expect selection error when collecting ambiguity errors") + } + }); + + FulfillmentError { + obligation: obligation.clone(), + code, + root_obligation: obligation, + } }) .collect() } diff --git a/compiler/rustc_trait_selection/src/solve/search_graph/mod.rs b/compiler/rustc_trait_selection/src/solve/search_graph/mod.rs index 42c28686f5c..050269fa973 100644 --- a/compiler/rustc_trait_selection/src/solve/search_graph/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/search_graph/mod.rs @@ -153,7 +153,7 @@ impl<'tcx> SearchGraph<'tcx> { /// coinductive cycles. /// /// When we encounter a coinductive cycle, we have to prove the final result of that cycle - /// while we are still computing that result. Because of this we continously recompute the + /// while we are still computing that result. Because of this we continuously recompute the /// cycle until the result of the previous iteration is equal to the final result, at which /// point we are done. /// diff --git a/compiler/rustc_trait_selection/src/solve/search_graph/overflow.rs b/compiler/rustc_trait_selection/src/solve/search_graph/overflow.rs index 574f3e9a577..e0a2e0c5cc2 100644 --- a/compiler/rustc_trait_selection/src/solve/search_graph/overflow.rs +++ b/compiler/rustc_trait_selection/src/solve/search_graph/overflow.rs @@ -45,7 +45,7 @@ impl OverflowData { /// Updating the current limit when hitting overflow. fn deal_with_overflow(&mut self) { // When first hitting overflow we reduce the overflow limit - // for all future goals to prevent hangs if there's an exponental + // for all future goals to prevent hangs if there's an exponential // blowup. self.current_limit.0 = self.default_limit.0 / 8; } diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index a53d414be9e..182d995c4eb 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -9,7 +9,6 @@ use crate::infer::InferCtxt; use crate::traits::project::ProjectAndUnifyResult; use rustc_infer::infer::DefineOpaqueTypes; use rustc_middle::mir::interpret::ErrorHandled; -use rustc_middle::ty::fold::{TypeFolder, TypeSuperFoldable}; use rustc_middle::ty::visit::TypeVisitableExt; use rustc_middle::ty::{ImplPolarity, Region, RegionVid}; @@ -187,7 +186,8 @@ impl<'tcx> AutoTraitFinder<'tcx> { panic!("Unable to fulfill trait {:?} for '{:?}': {:?}", trait_did, ty, errors); } - infcx.process_registered_region_obligations(&Default::default(), full_env); + let outlives_env = OutlivesEnvironment::new(full_env); + infcx.process_registered_region_obligations(&outlives_env); let region_data = infcx.inner.borrow_mut().unwrap_region_constraints().region_constraint_data().clone(); @@ -851,23 +851,3 @@ impl<'tcx> AutoTraitFinder<'tcx> { infcx.freshen(p) } } - -/// Replaces all ReVars in a type with ty::Region's, using the provided map -pub struct RegionReplacer<'a, 'tcx> { - vid_to_region: &'a FxHashMap<ty::RegionVid, ty::Region<'tcx>>, - tcx: TyCtxt<'tcx>, -} - -impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for RegionReplacer<'a, 'tcx> { - fn interner(&self) -> TyCtxt<'tcx> { - self.tcx - } - - fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { - (match *r { - ty::ReVar(vid) => self.vid_to_region.get(&vid).cloned(), - _ => None, - }) - .unwrap_or_else(|| r.super_fold_with(self)) - } -} diff --git a/compiler/rustc_trait_selection/src/traits/chalk_fulfill.rs b/compiler/rustc_trait_selection/src/traits/chalk_fulfill.rs index b42a49eb47b..28967e1cc55 100644 --- a/compiler/rustc_trait_selection/src/traits/chalk_fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/chalk_fulfill.rs @@ -40,13 +40,16 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> { self.obligations.insert(obligation); } - fn collect_remaining_errors(&mut self) -> Vec<FulfillmentError<'tcx>> { + fn collect_remaining_errors( + &mut self, + _infcx: &InferCtxt<'tcx>, + ) -> Vec<FulfillmentError<'tcx>> { // any remaining obligations are errors self.obligations .iter() .map(|obligation| FulfillmentError { obligation: obligation.clone(), - code: FulfillmentErrorCode::CodeAmbiguity, + code: FulfillmentErrorCode::CodeAmbiguity { overflow: false }, // FIXME - does Chalk have a notation of 'root obligation'? // This is just for diagnostics, so it's okay if this is wrong root_obligation: obligation.clone(), diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 53d4f95e9e3..3c918b6028d 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -405,9 +405,6 @@ fn resolve_negative_obligation<'tcx>( param_env, infcx.implied_bounds_tys(param_env, body_def_id, wf_tys), ); - - infcx.process_registered_region_obligations(outlives_env.region_bound_pairs(), param_env); - infcx.resolve_regions(&outlives_env).is_empty() } diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs index 8acc31cd410..2beebe94b6d 100644 --- a/compiler/rustc_trait_selection/src/traits/engine.rs +++ b/compiler/rustc_trait_selection/src/traits/engine.rs @@ -6,11 +6,13 @@ use super::{ChalkFulfillmentContext, FulfillmentContext}; use crate::solve::FulfillmentCtxt as NextFulfillmentCtxt; use crate::traits::NormalizeExt; use rustc_data_structures::fx::FxIndexSet; +use rustc_errors::ErrorGuaranteed; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_infer::infer::at::ToTrace; use rustc_infer::infer::canonical::{ Canonical, CanonicalQueryResponse, CanonicalVarValues, QueryResponse, }; +use rustc_infer::infer::outlives::env::OutlivesEnvironment; use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, InferOk}; use rustc_infer::traits::query::Fallible; use rustc_infer::traits::{ @@ -173,14 +175,33 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> { .map(|infer_ok| self.register_infer_ok_obligations(infer_ok)) } + #[must_use] pub fn select_where_possible(&self) -> Vec<FulfillmentError<'tcx>> { self.engine.borrow_mut().select_where_possible(self.infcx) } + #[must_use] pub fn select_all_or_error(&self) -> Vec<FulfillmentError<'tcx>> { self.engine.borrow_mut().select_all_or_error(self.infcx) } + /// Resolves regions and reports errors. + /// + /// Takes ownership of the context as doing trait solving afterwards + /// will result in region constraints getting ignored. + pub fn resolve_regions_and_report_errors( + self, + generic_param_scope: LocalDefId, + outlives_env: &OutlivesEnvironment<'tcx>, + ) -> Result<(), ErrorGuaranteed> { + let errors = self.infcx.resolve_regions(&outlives_env); + if errors.is_empty() { + Ok(()) + } else { + Err(self.infcx.err_ctxt().report_region_errors(generic_param_scope, &errors)) + } + } + pub fn assumed_wf_types( &self, param_env: ty::ParamEnv<'tcx>, diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 6ebf056f0e8..0ef6579664a 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -125,6 +125,8 @@ pub trait TypeErrCtxtExt<'tcx> { + Print<'tcx, FmtPrinter<'tcx, 'tcx>, Output = FmtPrinter<'tcx, 'tcx>>, <T as Print<'tcx, FmtPrinter<'tcx, 'tcx>>>::Error: std::fmt::Debug; + fn report_overflow_no_abort(&self, obligation: PredicateObligation<'tcx>) -> ErrorGuaranteed; + fn report_fulfillment_errors(&self, errors: &[FulfillmentError<'tcx>]) -> ErrorGuaranteed; fn report_overflow_obligation<T>( @@ -602,6 +604,14 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { ); } + fn report_overflow_no_abort(&self, obligation: PredicateObligation<'tcx>) -> ErrorGuaranteed { + let obligation = self.resolve_vars_if_possible(obligation); + let mut err = self.build_overflow_error(&obligation.predicate, obligation.cause.span, true); + self.note_obligation_cause(&mut err, &obligation); + self.point_at_returns_when_relevant(&mut err, &obligation); + err.emit() + } + fn report_selection_error( &self, mut obligation: PredicateObligation<'tcx>, @@ -1658,9 +1668,12 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { FulfillmentErrorCode::CodeProjectionError(ref e) => { self.report_projection_error(&error.obligation, e); } - FulfillmentErrorCode::CodeAmbiguity => { + FulfillmentErrorCode::CodeAmbiguity { overflow: false } => { self.maybe_report_ambiguity(&error.obligation); } + FulfillmentErrorCode::CodeAmbiguity { overflow: true } => { + self.report_overflow_no_abort(error.obligation.clone()); + } FulfillmentErrorCode::CodeSubtypeError(ref expected_found, ref err) => { self.report_mismatched_types( &error.obligation.cause, @@ -1763,7 +1776,10 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { // constrain inference variables a bit more to nested obligations from normalize so // we can have more helpful errors. - ocx.select_where_possible(); + // + // we intentionally drop errors from normalization here, + // since the normalization is just done to improve the error message. + let _ = ocx.select_where_possible(); if let Err(new_err) = ocx.eq_exp( &obligation.cause, @@ -2380,8 +2396,8 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } if let Some(ty::subst::GenericArgKind::Type(_)) = subst.map(|subst| subst.unpack()) + && let Some(body_id) = self.tcx.hir().maybe_body_owned_by(obligation.cause.body_id) { - let body_id = self.tcx.hir().body_owned_by(obligation.cause.body_id); let mut expr_finder = FindExprBySpan::new(span); expr_finder.visit_expr(&self.tcx.hir().body(body_id).value); diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 07e31e87bfb..26cadab3e9f 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -133,8 +133,15 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> { .register_obligation(PendingPredicateObligation { obligation, stalled_on: vec![] }); } - fn collect_remaining_errors(&mut self) -> Vec<FulfillmentError<'tcx>> { - self.predicates.to_errors(CodeAmbiguity).into_iter().map(to_fulfillment_error).collect() + fn collect_remaining_errors( + &mut self, + _infcx: &InferCtxt<'tcx>, + ) -> Vec<FulfillmentError<'tcx>> { + self.predicates + .to_errors(CodeAmbiguity { overflow: false }) + .into_iter() + .map(to_fulfillment_error) + .collect() } fn select_where_possible(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<FulfillmentError<'tcx>> { diff --git a/compiler/rustc_trait_selection/src/traits/misc.rs b/compiler/rustc_trait_selection/src/traits/misc.rs index 0bde43c54df..af567c07438 100644 --- a/compiler/rustc_trait_selection/src/traits/misc.rs +++ b/compiler/rustc_trait_selection/src/traits/misc.rs @@ -117,10 +117,6 @@ pub fn type_allowed_to_implement_copy<'tcx>( FxIndexSet::from_iter([self_type]), ), ); - infcx.process_registered_region_obligations( - outlives_env.region_bound_pairs(), - param_env, - ); let errors = infcx.resolve_regions(&outlives_env); if !errors.is_empty() { infringing.push((field, ty, InfringingFieldsReason::Regions(errors))); diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index a794d20d683..1f5bbc178f7 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -294,7 +294,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { return; } - // Keep this funtion in sync with extract_tupled_inputs_and_output_from_callable + // Keep this function in sync with extract_tupled_inputs_and_output_from_callable // until the old solver (and thus this function) is removed. // Okay to skip binder because what we are inspecting doesn't involve bound regions. @@ -406,7 +406,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } match obligation.self_ty().skip_binder().kind() { - // Fast path to avoid evaluating an obligation that trivally holds. + // Fast path to avoid evaluating an obligation that trivially holds. // There may be more bounds, but these are checked by the regular path. ty::FnPtr(..) => return false, // These may potentially implement `FnPtr` diff --git a/compiler/rustc_ty_utils/messages.ftl b/compiler/rustc_ty_utils/messages.ftl index a1e97bb95bc..15a14112f4a 100644 --- a/compiler/rustc_ty_utils/messages.ftl +++ b/compiler/rustc_ty_utils/messages.ftl @@ -12,7 +12,7 @@ ty_utils_array_not_supported = array construction is not supported in generic co ty_utils_block_not_supported = blocks are not supported in generic constants -ty_utils_never_to_any_not_supported = converting nevers to any is not supported in generic constants +ty_utils_never_to_any_not_supported = coercing the `never` type is not supported in generic constants ty_utils_tuple_not_supported = tuple construction is not supported in generic constants @@ -54,4 +54,4 @@ ty_utils_multiple_array_fields_simd_type = monomorphising SIMD type `{$ty}` with ty_utils_oversized_simd_type = monomorphising SIMD type `{$ty}` of length greater than {$max_lanes} -ty_utils_non_primative_simd_type = monomorphising SIMD type `{$ty}` with a non-primitive-scalar (integer/float/pointer) element type `{$e_ty}` +ty_utils_non_primitive_simd_type = monomorphising SIMD type `{$ty}` with a non-primitive-scalar (integer/float/pointer) element type `{$e_ty}` diff --git a/compiler/rustc_ty_utils/src/errors.rs b/compiler/rustc_ty_utils/src/errors.rs index 3db3c98e9e2..3d3fc50e6e5 100644 --- a/compiler/rustc_ty_utils/src/errors.rs +++ b/compiler/rustc_ty_utils/src/errors.rs @@ -95,7 +95,7 @@ pub struct OversizedSimdType<'tcx> { } #[derive(Diagnostic)] -#[diag(ty_utils_non_primative_simd_type)] +#[diag(ty_utils_non_primitive_simd_type)] pub struct NonPrimitiveSimdType<'tcx> { pub ty: Ty<'tcx>, pub e_ty: Ty<'tcx>, diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index 63eb34f7d55..63ef1c72417 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -322,7 +322,7 @@ fn layout_of_uncached<'tcx>( if fi.ty(tcx, substs) != f0_ty { tcx.sess.delay_span_bug( DUMMY_SP, - "#[repr(simd)] was applied to an ADT with hetrogeneous field type", + "#[repr(simd)] was applied to an ADT with heterogeneous field type", ); return Err(LayoutError::Unknown(ty)); } diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index 8b23fbc7583..a3c98ae007e 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -83,7 +83,7 @@ pub trait CollectAndApply<T, R>: Sized { /// Produce a result of type `Self::Output` from `iter`. The result will /// typically be produced by applying `f` on the elements produced by /// `iter`, though this may not happen in some impls, e.g. if an error - /// occured during iteration. + /// occurred during iteration. fn collect_and_apply<I, F>(iter: I, f: F) -> Self::Output where I: Iterator<Item = Self>, diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs index 61db46314b7..da675379cd5 100644 --- a/library/alloc/src/collections/btree/map.rs +++ b/library/alloc/src/collections/btree/map.rs @@ -3183,7 +3183,7 @@ impl<'a, K: Ord, V, A: Allocator + Clone> CursorMut<'a, K, V, A> { panic!("key must be ordered above the current element"); } } - if let Some((next, _)) = self.peek_prev() { + if let Some((next, _)) = self.peek_next() { if &key >= next { panic!("key must be ordered below the next element"); } diff --git a/library/alloc/src/collections/btree/map/tests.rs b/library/alloc/src/collections/btree/map/tests.rs index 76c2f27b466..4311f21c925 100644 --- a/library/alloc/src/collections/btree/map/tests.rs +++ b/library/alloc/src/collections/btree/map/tests.rs @@ -2385,3 +2385,67 @@ fn test_cursor_mut() { assert_eq!(cur.key(), Some(&4)); assert_eq!(map, BTreeMap::from([(0, '?'), (1, 'a'), (3, 'c'), (4, 'd')])); } + +#[should_panic(expected = "key must be ordered above the previous element")] +#[test] +fn test_cursor_mut_insert_before_1() { + let mut map = BTreeMap::from([(1, 'a'), (2, 'b'), (3, 'c')]); + let mut cur = map.upper_bound_mut(Bound::Included(&2)); + cur.insert_before(0, 'd'); +} + +#[should_panic(expected = "key must be ordered above the previous element")] +#[test] +fn test_cursor_mut_insert_before_2() { + let mut map = BTreeMap::from([(1, 'a'), (2, 'b'), (3, 'c')]); + let mut cur = map.upper_bound_mut(Bound::Included(&2)); + cur.insert_before(1, 'd'); +} + +#[should_panic(expected = "key must be ordered below the current element")] +#[test] +fn test_cursor_mut_insert_before_3() { + let mut map = BTreeMap::from([(1, 'a'), (2, 'b'), (3, 'c')]); + let mut cur = map.upper_bound_mut(Bound::Included(&2)); + cur.insert_before(2, 'd'); +} + +#[should_panic(expected = "key must be ordered below the current element")] +#[test] +fn test_cursor_mut_insert_before_4() { + let mut map = BTreeMap::from([(1, 'a'), (2, 'b'), (3, 'c')]); + let mut cur = map.upper_bound_mut(Bound::Included(&2)); + cur.insert_before(3, 'd'); +} + +#[should_panic(expected = "key must be ordered above the current element")] +#[test] +fn test_cursor_mut_insert_after_1() { + let mut map = BTreeMap::from([(1, 'a'), (2, 'b'), (3, 'c')]); + let mut cur = map.upper_bound_mut(Bound::Included(&2)); + cur.insert_after(1, 'd'); +} + +#[should_panic(expected = "key must be ordered above the current element")] +#[test] +fn test_cursor_mut_insert_after_2() { + let mut map = BTreeMap::from([(1, 'a'), (2, 'b'), (3, 'c')]); + let mut cur = map.upper_bound_mut(Bound::Included(&2)); + cur.insert_after(2, 'd'); +} + +#[should_panic(expected = "key must be ordered below the next element")] +#[test] +fn test_cursor_mut_insert_after_3() { + let mut map = BTreeMap::from([(1, 'a'), (2, 'b'), (3, 'c')]); + let mut cur = map.upper_bound_mut(Bound::Included(&2)); + cur.insert_after(3, 'd'); +} + +#[should_panic(expected = "key must be ordered below the next element")] +#[test] +fn test_cursor_mut_insert_after_4() { + let mut map = BTreeMap::from([(1, 'a'), (2, 'b'), (3, 'c')]); + let mut cur = map.upper_bound_mut(Bound::Included(&2)); + cur.insert_after(4, 'd'); +} diff --git a/library/core/src/intrinsics/mir.rs b/library/core/src/intrinsics/mir.rs index 6690c1a76d5..d9d62eb759e 100644 --- a/library/core/src/intrinsics/mir.rs +++ b/library/core/src/intrinsics/mir.rs @@ -232,6 +232,7 @@ //! - `&`, `&mut`, `addr_of!`, and `addr_of_mut!` all work to create their associated rvalue. //! - [`Discriminant`] and [`Len`] have associated functions. //! - Unary and binary operations use their normal Rust syntax - `a * b`, `!c`, etc. +//! - The binary operation `Offset` can be created via [`Offset`]. //! - Checked binary operations are represented by wrapping the associated binop in [`Checked`]. //! - Array repetition syntax (`[foo; 10]`) creates the associated rvalue. //! @@ -289,6 +290,7 @@ define!( fn Discriminant<T>(place: T) -> <T as ::core::marker::DiscriminantKind>::Discriminant ); define!("mir_set_discriminant", fn SetDiscriminant<T>(place: T, index: u32)); +define!("mir_offset", fn Offset<T, U>(ptr: T, count: U) -> T); define!( "mir_field", /// Access the field with the given index of some place. diff --git a/library/core/src/panic/unwind_safe.rs b/library/core/src/panic/unwind_safe.rs index 9a6153f1253..7e7b6b4dbe9 100644 --- a/library/core/src/panic/unwind_safe.rs +++ b/library/core/src/panic/unwind_safe.rs @@ -28,7 +28,7 @@ use crate::task::{Context, Poll}; /// 2. This broken invariant is then later observed. /// /// Typically in Rust, it is difficult to perform step (2) because catching a -/// panic involves either spawning a thread (which in turns makes it difficult +/// panic involves either spawning a thread (which in turn makes it difficult /// to later witness broken invariants) or using the `catch_unwind` function in this /// module. Additionally, even if an invariant is witnessed, it typically isn't a /// problem in Rust because there are no uninitialized values (like in C or C++). diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs index 4b31c552eed..020c723925a 100644 --- a/library/std/src/io/mod.rs +++ b/library/std/src/io/mod.rs @@ -268,7 +268,7 @@ pub(crate) use self::stdio::attempt_print_to_stderr; #[unstable(feature = "internal_output_capture", issue = "none")] #[doc(no_inline, hidden)] pub use self::stdio::set_output_capture; -#[unstable(feature = "is_terminal", issue = "98070")] +#[stable(feature = "is_terminal", since = "CURRENT_RUSTC_VERSION")] pub use self::stdio::IsTerminal; #[unstable(feature = "print_internals", issue = "none")] pub use self::stdio::{_eprint, _print}; diff --git a/library/std/src/io/stdio.rs b/library/std/src/io/stdio.rs index 1a3200a5c62..b2c57b8ddc7 100644 --- a/library/std/src/io/stdio.rs +++ b/library/std/src/io/stdio.rs @@ -1047,7 +1047,7 @@ pub(crate) fn attempt_print_to_stderr(args: fmt::Arguments<'_>) { } /// Trait to determine if a descriptor/handle refers to a terminal/tty. -#[unstable(feature = "is_terminal", issue = "98070")] +#[stable(feature = "is_terminal", since = "CURRENT_RUSTC_VERSION")] pub trait IsTerminal: crate::sealed::Sealed { /// Returns `true` if the descriptor/handle refers to a terminal/tty. /// @@ -1063,6 +1063,7 @@ pub trait IsTerminal: crate::sealed::Sealed { /// Note that this [may change in the future][changes]. /// /// [changes]: io#platform-specific-behavior + #[stable(feature = "is_terminal", since = "CURRENT_RUSTC_VERSION")] fn is_terminal(&self) -> bool; } @@ -1071,7 +1072,7 @@ macro_rules! impl_is_terminal { #[unstable(feature = "sealed", issue = "none")] impl crate::sealed::Sealed for $t {} - #[unstable(feature = "is_terminal", issue = "98070")] + #[stable(feature = "is_terminal", since = "CURRENT_RUSTC_VERSION")] impl IsTerminal for $t { #[inline] fn is_terminal(&self) -> bool { diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 736b3c0497c..71f3576c93d 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -254,7 +254,6 @@ #![feature(exhaustive_patterns)] #![feature(if_let_guard)] #![feature(intra_doc_pointers)] -#![feature(is_terminal)] #![feature(lang_items)] #![feature(let_chains)] #![feature(linkage)] diff --git a/library/std/src/os/fd/owned.rs b/library/std/src/os/fd/owned.rs index a40d39c5e44..6a6e6f33158 100644 --- a/library/std/src/os/fd/owned.rs +++ b/library/std/src/os/fd/owned.rs @@ -201,7 +201,7 @@ macro_rules! impl_is_terminal { #[unstable(feature = "sealed", issue = "none")] impl crate::sealed::Sealed for $t {} - #[unstable(feature = "is_terminal", issue = "98070")] + #[stable(feature = "is_terminal", since = "CURRENT_RUSTC_VERSION")] impl crate::io::IsTerminal for $t { #[inline] fn is_terminal(&self) -> bool { diff --git a/library/std/src/os/windows/io/handle.rs b/library/std/src/os/windows/io/handle.rs index 1dfecc57338..f6622874625 100644 --- a/library/std/src/os/windows/io/handle.rs +++ b/library/std/src/os/windows/io/handle.rs @@ -389,7 +389,7 @@ macro_rules! impl_is_terminal { #[unstable(feature = "sealed", issue = "none")] impl crate::sealed::Sealed for $t {} - #[unstable(feature = "is_terminal", issue = "98070")] + #[stable(feature = "is_terminal", since = "CURRENT_RUSTC_VERSION")] impl crate::io::IsTerminal for $t { #[inline] fn is_terminal(&self) -> bool { diff --git a/library/std/src/sync/mpmc/list.rs b/library/std/src/sync/mpmc/list.rs index ec6c0726ac7..406a331a309 100644 --- a/library/std/src/sync/mpmc/list.rs +++ b/library/std/src/sync/mpmc/list.rs @@ -549,6 +549,18 @@ impl<T> Channel<T> { let mut head = self.head.index.load(Ordering::Acquire); let mut block = self.head.block.load(Ordering::Acquire); + // If we're going to be dropping messages we need to synchronize with initialization + if head >> SHIFT != tail >> SHIFT { + // The block can be null here only if a sender is in the process of initializing the + // channel while another sender managed to send a message by inserting it into the + // semi-initialized channel and advanced the tail. + // In that case, just wait until it gets initialized. + while block.is_null() { + backoff.spin_heavy(); + block = self.head.block.load(Ordering::Acquire); + } + } + unsafe { // Drop all messages between head and tail and deallocate the heap-allocated blocks. while head >> SHIFT != tail >> SHIFT { diff --git a/library/std/src/sys/unix/kernel_copy.rs b/library/std/src/sys/unix/kernel_copy.rs index 73b9bef7e2a..16c8e0c0ebf 100644 --- a/library/std/src/sys/unix/kernel_copy.rs +++ b/library/std/src/sys/unix/kernel_copy.rs @@ -17,11 +17,9 @@ //! Once it has obtained all necessary pieces and brought any wrapper types into a state where they //! can be safely bypassed it will attempt to use the `copy_file_range(2)`, //! `sendfile(2)` or `splice(2)` syscalls to move data directly between file descriptors. -//! Since those syscalls have requirements that cannot be fully checked in advance and -//! gathering additional information about file descriptors would require additional syscalls -//! anyway it simply attempts to use them one after another (guided by inaccurate hints) to -//! figure out which one works and falls back to the generic read-write copy loop if none of them -//! does. +//! Since those syscalls have requirements that cannot be fully checked in advance it attempts +//! to use them one after another (guided by hints) to figure out which one works and +//! falls back to the generic read-write copy loop if none of them does. //! Once a working syscall is found for a pair of file descriptors it will be called in a loop //! until the copy operation is completed. //! @@ -84,14 +82,10 @@ pub(crate) fn copy_spec<R: Read + ?Sized, W: Write + ?Sized>( /// The methods on this type only provide hints, due to `AsRawFd` and `FromRawFd` the inferred /// type may be wrong. enum FdMeta { - /// We obtained the FD from a type that can contain any type of `FileType` and queried the metadata - /// because it is cheaper than probing all possible syscalls (reader side) Metadata(Metadata), Socket, Pipe, - /// We don't have any metadata, e.g. because the original type was `File` which can represent - /// any `FileType` and we did not query the metadata either since it did not seem beneficial - /// (writer side) + /// We don't have any metadata because the stat syscall failed NoneObtained, } @@ -131,6 +125,39 @@ impl FdMeta { } } +/// Returns true either if changes made to the source after a sendfile/splice call won't become +/// visible in the sink or the source has explicitly opted into such behavior (e.g. by splicing +/// a file into a pipe, the pipe being the source in this case). +/// +/// This will prevent File -> Pipe and File -> Socket splicing/sendfile optimizations to uphold +/// the Read/Write API semantics of io::copy. +/// +/// Note: This is not 100% airtight, the caller can use the RawFd conversion methods to turn a +/// regular file into a TcpSocket which will be treated as a socket here without checking. +fn safe_kernel_copy(source: &FdMeta, sink: &FdMeta) -> bool { + match (source, sink) { + // Data arriving from a socket is safe because the sender can't modify the socket buffer. + // Data arriving from a pipe is safe(-ish) because either the sender *copied* + // the bytes into the pipe OR explicitly performed an operation that enables zero-copy, + // thus promising not to modify the data later. + (FdMeta::Socket, _) => true, + (FdMeta::Pipe, _) => true, + (FdMeta::Metadata(meta), _) + if meta.file_type().is_fifo() || meta.file_type().is_socket() => + { + true + } + // Data going into non-pipes/non-sockets is safe because the "later changes may become visible" issue + // only happens for pages sitting in send buffers or pipes. + (_, FdMeta::Metadata(meta)) + if !meta.file_type().is_fifo() && !meta.file_type().is_socket() => + { + true + } + _ => false, + } +} + struct CopyParams(FdMeta, Option<RawFd>); struct Copier<'a, 'b, R: Read + ?Sized, W: Write + ?Sized> { @@ -186,7 +213,8 @@ impl<R: CopyRead, W: CopyWrite> SpecCopy for Copier<'_, '_, R, W> { // So we just try and fallback if needed. // If current file offsets + write sizes overflow it may also fail, we do not try to fix that and instead // fall back to the generic copy loop. - if input_meta.potential_sendfile_source() { + if input_meta.potential_sendfile_source() && safe_kernel_copy(&input_meta, &output_meta) + { let result = sendfile_splice(SpliceMode::Sendfile, readfd, writefd, max_write); result.update_take(reader); @@ -197,7 +225,9 @@ impl<R: CopyRead, W: CopyWrite> SpecCopy for Copier<'_, '_, R, W> { } } - if input_meta.maybe_fifo() || output_meta.maybe_fifo() { + if (input_meta.maybe_fifo() || output_meta.maybe_fifo()) + && safe_kernel_copy(&input_meta, &output_meta) + { let result = sendfile_splice(SpliceMode::Splice, readfd, writefd, max_write); result.update_take(reader); @@ -298,13 +328,13 @@ impl CopyRead for &File { impl CopyWrite for File { fn properties(&self) -> CopyParams { - CopyParams(FdMeta::NoneObtained, Some(self.as_raw_fd())) + CopyParams(fd_to_meta(self), Some(self.as_raw_fd())) } } impl CopyWrite for &File { fn properties(&self) -> CopyParams { - CopyParams(FdMeta::NoneObtained, Some(self.as_raw_fd())) + CopyParams(fd_to_meta(*self), Some(self.as_raw_fd())) } } @@ -401,13 +431,13 @@ impl CopyRead for StdinLock<'_> { impl CopyWrite for StdoutLock<'_> { fn properties(&self) -> CopyParams { - CopyParams(FdMeta::NoneObtained, Some(self.as_raw_fd())) + CopyParams(fd_to_meta(self), Some(self.as_raw_fd())) } } impl CopyWrite for StderrLock<'_> { fn properties(&self) -> CopyParams { - CopyParams(FdMeta::NoneObtained, Some(self.as_raw_fd())) + CopyParams(fd_to_meta(self), Some(self.as_raw_fd())) } } diff --git a/library/std/src/sys/unix/kernel_copy/tests.rs b/library/std/src/sys/unix/kernel_copy/tests.rs index 3fe849e23e2..a524270e3fb 100644 --- a/library/std/src/sys/unix/kernel_copy/tests.rs +++ b/library/std/src/sys/unix/kernel_copy/tests.rs @@ -83,6 +83,48 @@ fn copies_append_mode_sink() -> Result<()> { Ok(()) } +#[test] +fn dont_splice_pipes_from_files() -> Result<()> { + // splicing to a pipe and then modifying the source could lead to changes + // becoming visible in an unexpected order. + + use crate::io::SeekFrom; + use crate::os::unix::fs::FileExt; + use crate::process::{ChildStdin, ChildStdout}; + use crate::sys_common::FromInner; + + let (read_end, write_end) = crate::sys::pipe::anon_pipe()?; + + let mut read_end = ChildStdout::from_inner(read_end); + let mut write_end = ChildStdin::from_inner(write_end); + + let tmp_path = tmpdir(); + let file = tmp_path.join("to_be_modified"); + let mut file = + crate::fs::OpenOptions::new().create_new(true).read(true).write(true).open(file)?; + + const SZ: usize = libc::PIPE_BUF as usize; + + // put data in page cache + let mut buf: [u8; SZ] = [0x01; SZ]; + file.write_all(&buf).unwrap(); + + // copy page into pipe + file.seek(SeekFrom::Start(0)).unwrap(); + assert!(io::copy(&mut file, &mut write_end).unwrap() == SZ as u64); + + // modify file + buf[0] = 0x02; + file.write_at(&buf, 0).unwrap(); + + // read from pipe + read_end.read_exact(buf.as_mut_slice()).unwrap(); + + assert_eq!(buf[0], 0x01, "data in pipe should reflect the original, not later modifications"); + + Ok(()) +} + #[bench] fn bench_file_to_file_copy(b: &mut test::Bencher) { const BYTES: usize = 128 * 1024; diff --git a/library/test/src/lib.rs b/library/test/src/lib.rs index 88d8e5fe97a..9fb31ed7663 100644 --- a/library/test/src/lib.rs +++ b/library/test/src/lib.rs @@ -17,7 +17,6 @@ #![unstable(feature = "test", issue = "50297")] #![doc(test(attr(deny(warnings))))] #![feature(internal_output_capture)] -#![feature(is_terminal)] #![feature(staged_api)] #![feature(process_exitcode_internals)] #![feature(panic_can_unwind)] diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs index f9387a0fc80..fcaa698317d 100644 --- a/src/bootstrap/check.rs +++ b/src/bootstrap/check.rs @@ -237,7 +237,7 @@ impl Step for Rustc { target, cargo_subcommand(builder.kind), ); - rustc_cargo(builder, &mut cargo, target); + rustc_cargo(builder, &mut cargo, target, compiler.stage); // For ./x.py clippy, don't run with --all-targets because // linting tests and benchmarks can produce very noisy results @@ -323,7 +323,7 @@ impl Step for CodegenBackend { cargo .arg("--manifest-path") .arg(builder.src.join(format!("compiler/rustc_codegen_{}/Cargo.toml", backend))); - rustc_cargo_env(builder, &mut cargo, target); + rustc_cargo_env(builder, &mut cargo, target, compiler.stage); let msg = if compiler.host == target { format!("Checking stage{} {} artifacts ({target})", builder.top_stage, backend) diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 85d1c12cc6a..d96e10485c2 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -696,7 +696,7 @@ impl Step for Rustc { )); let mut cargo = builder.cargo(compiler, Mode::Rustc, SourceType::InTree, target, "build"); - rustc_cargo(builder, &mut cargo, target); + rustc_cargo(builder, &mut cargo, target, compiler.stage); if builder.config.rust_profile_use.is_some() && builder.config.rust_profile_generate.is_some() @@ -813,16 +813,21 @@ impl Step for Rustc { } } -pub fn rustc_cargo(builder: &Builder<'_>, cargo: &mut Cargo, target: TargetSelection) { +pub fn rustc_cargo(builder: &Builder<'_>, cargo: &mut Cargo, target: TargetSelection, stage: u32) { cargo .arg("--features") .arg(builder.rustc_features(builder.kind)) .arg("--manifest-path") .arg(builder.src.join("compiler/rustc/Cargo.toml")); - rustc_cargo_env(builder, cargo, target); + rustc_cargo_env(builder, cargo, target, stage); } -pub fn rustc_cargo_env(builder: &Builder<'_>, cargo: &mut Cargo, target: TargetSelection) { +pub fn rustc_cargo_env( + builder: &Builder<'_>, + cargo: &mut Cargo, + target: TargetSelection, + stage: u32, +) { // Set some configuration variables picked up by build scripts and // the compiler alike cargo @@ -867,83 +872,86 @@ pub fn rustc_cargo_env(builder: &Builder<'_>, cargo: &mut Cargo, target: TargetS cargo.env("RUSTC_VERIFY_LLVM_IR", "1"); } - // Pass down configuration from the LLVM build into the build of - // rustc_llvm and rustc_codegen_llvm. - // // Note that this is disabled if LLVM itself is disabled or we're in a check // build. If we are in a check build we still go ahead here presuming we've // detected that LLVM is already built and good to go which helps prevent // busting caches (e.g. like #71152). - if builder.config.llvm_enabled() - && (builder.kind != Kind::Check - || crate::llvm::prebuilt_llvm_config(builder, target).is_ok()) - { - if builder.is_rust_llvm(target) { - cargo.env("LLVM_RUSTLLVM", "1"); - } - let llvm::LlvmResult { llvm_config, .. } = builder.ensure(llvm::Llvm { target }); - cargo.env("LLVM_CONFIG", &llvm_config); - if let Some(s) = target_config.and_then(|c| c.llvm_config.as_ref()) { - cargo.env("CFG_LLVM_ROOT", s); + if builder.config.llvm_enabled() { + let building_is_expensive = crate::llvm::prebuilt_llvm_config(builder, target).is_err(); + // `top_stage == stage` might be false for `check --stage 1`, if we are building the stage 1 compiler + let can_skip_build = builder.kind == Kind::Check && builder.top_stage == stage; + let should_skip_build = building_is_expensive && can_skip_build; + if !should_skip_build { + rustc_llvm_env(builder, cargo, target) } + } +} - // Some LLVM linker flags (-L and -l) may be needed to link `rustc_llvm`. Its build script - // expects these to be passed via the `LLVM_LINKER_FLAGS` env variable, separated by - // whitespace. - // - // For example: - // - on windows, when `clang-cl` is used with instrumentation, we need to manually add - // clang's runtime library resource directory so that the profiler runtime library can be - // found. This is to avoid the linker errors about undefined references to - // `__llvm_profile_instrument_memop` when linking `rustc_driver`. - let mut llvm_linker_flags = String::new(); - if builder.config.llvm_profile_generate && target.contains("msvc") { - if let Some(ref clang_cl_path) = builder.config.llvm_clang_cl { - // Add clang's runtime library directory to the search path - let clang_rt_dir = get_clang_cl_resource_dir(clang_cl_path); - llvm_linker_flags.push_str(&format!("-L{}", clang_rt_dir.display())); - } - } +/// Pass down configuration from the LLVM build into the build of +/// rustc_llvm and rustc_codegen_llvm. +fn rustc_llvm_env(builder: &Builder<'_>, cargo: &mut Cargo, target: TargetSelection) { + let target_config = builder.config.target_config.get(&target); - // The config can also specify its own llvm linker flags. - if let Some(ref s) = builder.config.llvm_ldflags { - if !llvm_linker_flags.is_empty() { - llvm_linker_flags.push_str(" "); - } - llvm_linker_flags.push_str(s); + if builder.is_rust_llvm(target) { + cargo.env("LLVM_RUSTLLVM", "1"); + } + let llvm::LlvmResult { llvm_config, .. } = builder.ensure(llvm::Llvm { target }); + cargo.env("LLVM_CONFIG", &llvm_config); + if let Some(s) = target_config.and_then(|c| c.llvm_config.as_ref()) { + cargo.env("CFG_LLVM_ROOT", s); + } + + // Some LLVM linker flags (-L and -l) may be needed to link `rustc_llvm`. Its build script + // expects these to be passed via the `LLVM_LINKER_FLAGS` env variable, separated by + // whitespace. + // + // For example: + // - on windows, when `clang-cl` is used with instrumentation, we need to manually add + // clang's runtime library resource directory so that the profiler runtime library can be + // found. This is to avoid the linker errors about undefined references to + // `__llvm_profile_instrument_memop` when linking `rustc_driver`. + let mut llvm_linker_flags = String::new(); + if builder.config.llvm_profile_generate && target.contains("msvc") { + if let Some(ref clang_cl_path) = builder.config.llvm_clang_cl { + // Add clang's runtime library directory to the search path + let clang_rt_dir = get_clang_cl_resource_dir(clang_cl_path); + llvm_linker_flags.push_str(&format!("-L{}", clang_rt_dir.display())); } + } - // Set the linker flags via the env var that `rustc_llvm`'s build script will read. + // The config can also specify its own llvm linker flags. + if let Some(ref s) = builder.config.llvm_ldflags { if !llvm_linker_flags.is_empty() { - cargo.env("LLVM_LINKER_FLAGS", llvm_linker_flags); + llvm_linker_flags.push_str(" "); } + llvm_linker_flags.push_str(s); + } - // Building with a static libstdc++ is only supported on linux right now, - // not for MSVC or macOS - if builder.config.llvm_static_stdcpp - && !target.contains("freebsd") - && !target.contains("msvc") - && !target.contains("apple") - && !target.contains("solaris") - { - let file = compiler_file( - builder, - builder.cxx(target).unwrap(), - target, - CLang::Cxx, - "libstdc++.a", - ); - cargo.env("LLVM_STATIC_STDCPP", file); - } - if builder.llvm_link_shared() { - cargo.env("LLVM_LINK_SHARED", "1"); - } - if builder.config.llvm_use_libcxx { - cargo.env("LLVM_USE_LIBCXX", "1"); - } - if builder.config.llvm_optimize && !builder.config.llvm_release_debuginfo { - cargo.env("LLVM_NDEBUG", "1"); - } + // Set the linker flags via the env var that `rustc_llvm`'s build script will read. + if !llvm_linker_flags.is_empty() { + cargo.env("LLVM_LINKER_FLAGS", llvm_linker_flags); + } + + // Building with a static libstdc++ is only supported on linux right now, + // not for MSVC or macOS + if builder.config.llvm_static_stdcpp + && !target.contains("freebsd") + && !target.contains("msvc") + && !target.contains("apple") + && !target.contains("solaris") + { + let file = + compiler_file(builder, builder.cxx(target).unwrap(), target, CLang::Cxx, "libstdc++.a"); + cargo.env("LLVM_STATIC_STDCPP", file); + } + if builder.llvm_link_shared() { + cargo.env("LLVM_LINK_SHARED", "1"); + } + if builder.config.llvm_use_libcxx { + cargo.env("LLVM_USE_LIBCXX", "1"); + } + if builder.config.llvm_optimize && !builder.config.llvm_release_debuginfo { + cargo.env("LLVM_NDEBUG", "1"); } } @@ -1090,7 +1098,7 @@ impl Step for CodegenBackend { cargo .arg("--manifest-path") .arg(builder.src.join(format!("compiler/rustc_codegen_{}/Cargo.toml", backend))); - rustc_cargo_env(builder, &mut cargo, target); + rustc_cargo_env(builder, &mut cargo, target, compiler.stage); let tmp_stamp = out_dir.join(".tmp.stamp"); diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index be43affa404..9ad98eb5702 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -696,7 +696,7 @@ impl Step for Rustc { cargo.rustdocflag("-Znormalize-docs"); cargo.rustdocflag("--show-type-layout"); cargo.rustdocflag("--generate-link-to-definition"); - compile::rustc_cargo(builder, &mut cargo, target); + compile::rustc_cargo(builder, &mut cargo, target, compiler.stage); cargo.arg("-Zunstable-options"); cargo.arg("-Zskip-rustdoc-fingerprint"); diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index f9c5837b7d6..cc0e34c6035 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -1064,6 +1064,8 @@ impl Step for RustdocGUI { cargo.env("RUSTDOCFLAGS", "-Zunstable-options --generate-link-to-definition"); } else if entry.file_name() == "scrape_examples" { cargo.arg("-Zrustdoc-scrape-examples"); + } else if entry.file_name() == "extend_css" { + cargo.env("RUSTDOCFLAGS", &format!("--extend-css extra.css")); } builder.run(&mut cargo); } @@ -2146,7 +2148,7 @@ impl Step for Crate { compile::std_cargo(builder, target, compiler.stage, &mut cargo); } Mode::Rustc => { - compile::rustc_cargo(builder, &mut cargo, target); + compile::rustc_cargo(builder, &mut cargo, target, compiler.stage); } _ => panic!("can only test libraries"), }; diff --git a/src/doc/rustc/src/platform-support/loongarch-linux.md b/src/doc/rustc/src/platform-support/loongarch-linux.md index e046ec244ec..d7d31d8724c 100644 --- a/src/doc/rustc/src/platform-support/loongarch-linux.md +++ b/src/doc/rustc/src/platform-support/loongarch-linux.md @@ -6,12 +6,12 @@ [LoongArch]: https://loongson.github.io/LoongArch-Documentation/README-EN.html -The target name follow this format: `<machine>-<vendor>-<os><fabi_suffix>, where `<machine>` specifies the CPU family/model, `<vendor>` specifies the vendor and `<os>` the operating system name. +The target name follow this format: `<machine>-<vendor>-<os><fabi_suffix>`, where `<machine>` specifies the CPU family/model, `<vendor>` specifies the vendor and `<os>` the operating system name. While the integer base ABI is implied by the machine field, the floating point base ABI type is encoded into the os field of the specifier using the string suffix `<fabi-suffix>`. | `<fabi-suffix>` | `Description` | |------------------------|--------------------------------------------------------------------| -| f64 | The base ABI use 64-bits FPRs for parameter passing.(lp64d)| +| f64 | The base ABI use 64-bits FPRs for parameter passing. (lp64d)| | f32 | The base ABI uses 32-bit FPRs for parameter passing. (lp64f)| | sf | The base ABI uses no FPR for parameter passing. (lp64s) | @@ -26,9 +26,9 @@ While the integer base ABI is implied by the machine field, the floating po ## Target maintainers -- [ZHAI xiaojuan](https://github.com/zhaixiaojuan) `zhaixiaojuan@loongson.cn` -- [WANG rui](https://github.com/heiher) `wangrui@loongson.cn` -- [ZHAI xiang](https://github.com/xiangzhai) `zhaixiang@loongson.cn` +- [ZHAI Xiaojuan](https://github.com/zhaixiaojuan) `zhaixiaojuan@loongson.cn` +- [WANG Rui](https://github.com/heiher) `wangrui@loongson.cn` +- [ZHAI Xiang](https://github.com/xiangzhai) `zhaixiang@loongson.cn` - [WANG Xuerui](https://github.com/xen0n) `git@xen0n.name` ## Requirements diff --git a/src/doc/rustdoc/src/command-line-arguments.md b/src/doc/rustdoc/src/command-line-arguments.md index 2a2e51b2f63..dfc80426372 100644 --- a/src/doc/rustdoc/src/command-line-arguments.md +++ b/src/doc/rustdoc/src/command-line-arguments.md @@ -320,10 +320,7 @@ $ rustdoc src/lib.rs --extend-css extra.css ``` With this flag, the contents of the files you pass are included at the bottom -of Rustdoc's `theme.css` file. - -While this flag is stable, the contents of `theme.css` are not, so be careful! -Updates may break your theme extensions. +of the `theme.css` file. ## `--sysroot`: override the system root diff --git a/src/doc/unstable-book/src/language-features/asm-experimental-arch.md b/src/doc/unstable-book/src/language-features/asm-experimental-arch.md index 0a48eb4f81a..1f52ab75010 100644 --- a/src/doc/unstable-book/src/language-features/asm-experimental-arch.md +++ b/src/doc/unstable-book/src/language-features/asm-experimental-arch.md @@ -16,6 +16,7 @@ This feature tracks `asm!` and `global_asm!` support for the following architect - SPIR-V - AVR - MSP430 +- M68k ## Register classes @@ -41,6 +42,9 @@ This feature tracks `asm!` and `global_asm!` support for the following architect | AVR | `reg_iw` | `r25r24`, `X`, `Z` | `w` | | AVR | `reg_ptr` | `X`, `Z` | `e` | | MSP430 | `reg` | `r[0-15]` | `r` | +| M68k | `reg` | `d[0-7]`, `a[0-7]` | `r` | +| M68k | `reg_data` | `d[0-7]` | `d` | +| M68k | `reg_addr` | `a[0-3]` | `a` | > **Notes**: > - NVPTX doesn't have a fixed register set, so named registers are not supported. @@ -70,6 +74,8 @@ This feature tracks `asm!` and `global_asm!` support for the following architect | AVR | `reg`, `reg_upper` | None | `i8` | | AVR | `reg_pair`, `reg_iw`, `reg_ptr` | None | `i16` | | MSP430 | `reg` | None | `i8`, `i16` | +| M68k | `reg`, `reg_addr` | None | `i16`, `i32` | +| M68k | `reg_data` | None | `i8`, `i16`, `i32` | ## Register aliases @@ -88,6 +94,9 @@ This feature tracks `asm!` and `global_asm!` support for the following architect | MSP430 | `r2` | `sr` | | MSP430 | `r3` | `cg` | | MSP430 | `r4` | `fp` | +| M68k | `a5` | `bp` | +| M68k | `a6` | `fp` | +| M68k | `a7` | `sp`, `usp`, `ssp`, `isp` | > **Notes**: > - TI does not mandate a frame pointer for MSP430, but toolchains are allowed @@ -98,7 +107,7 @@ This feature tracks `asm!` and `global_asm!` support for the following architect | Architecture | Unsupported register | Reason | | ------------ | --------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | All | `sp` | The stack pointer must be restored to its original value at the end of an asm code block. | -| All | `fr` (Hexagon), `$fp` (MIPS), `Y` (AVR), `r4` (MSP430) | The frame pointer cannot be used as an input or output. | +| All | `fr` (Hexagon), `$fp` (MIPS), `Y` (AVR), `r4` (MSP430), `a6` (M68k) | The frame pointer cannot be used as an input or output. | | All | `r19` (Hexagon) | This is used internally by LLVM as a "base pointer" for functions with complex stack frames. | | MIPS | `$0` or `$zero` | This is a constant zero register which can't be modified. | | MIPS | `$1` or `$at` | Reserved for assembler. | @@ -108,6 +117,7 @@ This feature tracks `asm!` and `global_asm!` support for the following architect | Hexagon | `lr` | This is the link register which cannot be used as an input or output. | | AVR | `r0`, `r1`, `r1r0` | Due to an issue in LLVM, the `r0` and `r1` registers cannot be used as inputs or outputs. If modified, they must be restored to their original values before the end of the block. | |MSP430 | `r0`, `r2`, `r3` | These are the program counter, status register, and constant generator respectively. Neither the status register nor constant generator can be written to. | +| M68k | `a4`, `a5` | Used internally by LLVM for the base pointer and global base pointer. | ## Template modifiers @@ -130,3 +140,5 @@ These flags registers must be restored upon exiting the asm block if the `preser - The status register `SREG`. - MSP430 - The status register `r2`. +- M68k + - The condition code register `ccr`. diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index c848089dad6..512c5c85d6a 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -6,7 +6,6 @@ use std::path::PathBuf; use std::str::FromStr; use rustc_data_structures::fx::FxHashMap; -use rustc_driver::print_flag_list; use rustc_session::config::{ self, parse_crate_types_from_list, parse_externs, parse_target_triple, CrateType, }; @@ -328,14 +327,7 @@ impl Options { return Err(0); } - let z_flags = matches.opt_strs("Z"); - if z_flags.iter().any(|x| *x == "help") { - print_flag_list("-Z", config::Z_OPTIONS); - return Err(0); - } - let c_flags = matches.opt_strs("C"); - if c_flags.iter().any(|x| *x == "help") { - print_flag_list("-C", config::CG_OPTIONS); + if rustc_driver::describe_flag_categories(&matches) { return Err(0); } diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 1a896b411ab..daf10e5b88a 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -398,6 +398,8 @@ fn run_test( compiler.stdin(Stdio::piped()); compiler.stderr(Stdio::piped()); + debug!("compiler invocation for doctest: {:?}", compiler); + let mut child = compiler.spawn().expect("Failed to spawn rustc process"); { let stdin = child.stdin.as_mut().expect("Failed to open stdin"); diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 9df19352567..6fbb4508662 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -384,6 +384,7 @@ img { font-size: 0.875rem; flex: 0 0 200px; overflow-y: scroll; + overscroll-behavior: contain; position: sticky; height: 100vh; top: 0; @@ -1531,7 +1532,7 @@ However, it's not needed with smaller screen width because the doc/code block is /* WARNING: RUSTDOC_MOBILE_BREAKPOINT MEDIA QUERY If you update this line, then you also need to update the line with the same warning -in main.js +in source-script.js */ @media (max-width: 700px) { /* When linking to an item with an `id` (for instance, by clicking a link in the sidebar, diff --git a/src/librustdoc/html/static/css/settings.css b/src/librustdoc/html/static/css/settings.css index 920f45c4bba..d13c783d2e4 100644 --- a/src/librustdoc/html/static/css/settings.css +++ b/src/librustdoc/html/static/css/settings.css @@ -8,7 +8,7 @@ height: 1.2rem; width: 1.2rem; color: inherit; - border: 1px solid currentColor; + border: 2px solid var(--settings-input-border-color); outline: none; -webkit-appearance: none; cursor: pointer; @@ -52,6 +52,7 @@ } .setting-check input:checked { background-color: var(--settings-input-color); + border-width: 1px; } .setting-radio input:focus, .setting-check input:focus { box-shadow: 0 0 1px 1px var(--settings-input-color); diff --git a/src/librustdoc/html/static/css/themes/ayu.css b/src/librustdoc/html/static/css/themes/ayu.css index 90cf689ad33..7145baad256 100644 --- a/src/librustdoc/html/static/css/themes/ayu.css +++ b/src/librustdoc/html/static/css/themes/ayu.css @@ -7,6 +7,7 @@ Original by Dempfi (https://github.com/dempfi/ayu) --main-background-color: #0f1419; --main-color: #c5c5c5; --settings-input-color: #ffb454; + --settings-input-border-color: #999; --settings-button-color: #fff; --settings-button-border-focus: #e0e0e0; --sidebar-background-color: #14191f; diff --git a/src/librustdoc/html/static/css/themes/dark.css b/src/librustdoc/html/static/css/themes/dark.css index e8cd0693139..3c1186a5649 100644 --- a/src/librustdoc/html/static/css/themes/dark.css +++ b/src/librustdoc/html/static/css/themes/dark.css @@ -2,6 +2,7 @@ --main-background-color: #353535; --main-color: #ddd; --settings-input-color: #2196f3; + --settings-input-border-color: #999; --settings-button-color: #000; --settings-button-border-focus: #ffb900; --sidebar-background-color: #505050; diff --git a/src/librustdoc/html/static/css/themes/light.css b/src/librustdoc/html/static/css/themes/light.css index 5e3f14e483f..f8c287137de 100644 --- a/src/librustdoc/html/static/css/themes/light.css +++ b/src/librustdoc/html/static/css/themes/light.css @@ -2,6 +2,7 @@ --main-background-color: white; --main-color: black; --settings-input-color: #2196f3; + --settings-input-border-color: #717171; --settings-button-color: #000; --settings-button-border-focus: #717171; --sidebar-background-color: #F5F5F5; diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index a6655663b82..6f5987e68bf 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -4,11 +4,6 @@ "use strict"; -// WARNING: RUSTDOC_MOBILE_BREAKPOINT MEDIA QUERY -// If you update this line, then you also need to update the media query with the same -// warning in rustdoc.css -window.RUSTDOC_MOBILE_BREAKPOINT = 700; - // Given a basename (e.g. "storage") and an extension (e.g. ".js"), return a URL // for a resource under the root-path, with the resource-suffix. function resourcePath(basename, extension) { @@ -730,65 +725,18 @@ function preLoadCss(cssUrl) { window.rustdoc_add_line_numbers_to_examples(); } - let oldSidebarScrollPosition = null; - - // Scroll locking used both here and in source-script.js - - window.rustdocMobileScrollLock = function() { - const mobile_topbar = document.querySelector(".mobile-topbar"); - if (window.innerWidth <= window.RUSTDOC_MOBILE_BREAKPOINT) { - // This is to keep the scroll position on mobile. - oldSidebarScrollPosition = window.scrollY; - document.body.style.width = `${document.body.offsetWidth}px`; - document.body.style.position = "fixed"; - document.body.style.top = `-${oldSidebarScrollPosition}px`; - if (mobile_topbar) { - mobile_topbar.style.top = `${oldSidebarScrollPosition}px`; - mobile_topbar.style.position = "relative"; - } - } else { - oldSidebarScrollPosition = null; - } - }; - - window.rustdocMobileScrollUnlock = function() { - const mobile_topbar = document.querySelector(".mobile-topbar"); - if (oldSidebarScrollPosition !== null) { - // This is to keep the scroll position on mobile. - document.body.style.width = ""; - document.body.style.position = ""; - document.body.style.top = ""; - if (mobile_topbar) { - mobile_topbar.style.top = ""; - mobile_topbar.style.position = ""; - } - // The scroll position is lost when resetting the style, hence why we store it in - // `oldSidebarScrollPosition`. - window.scrollTo(0, oldSidebarScrollPosition); - oldSidebarScrollPosition = null; - } - }; - function showSidebar() { window.hideAllModals(false); - window.rustdocMobileScrollLock(); const sidebar = document.getElementsByClassName("sidebar")[0]; addClass(sidebar, "shown"); } function hideSidebar() { - window.rustdocMobileScrollUnlock(); const sidebar = document.getElementsByClassName("sidebar")[0]; removeClass(sidebar, "shown"); } window.addEventListener("resize", () => { - if (window.innerWidth > window.RUSTDOC_MOBILE_BREAKPOINT && - oldSidebarScrollPosition !== null) { - // If the user opens the sidebar in "mobile" mode, and then grows the browser window, - // we need to switch away from mobile mode and make the main content area scrollable. - hideSidebar(); - } if (window.CURRENT_TOOLTIP_ELEMENT) { // As a workaround to the behavior of `contains: layout` used in doc togglers, // tooltip popovers are positioned using javascript. diff --git a/src/librustdoc/html/static/js/source-script.js b/src/librustdoc/html/static/js/source-script.js index 6c0f03b5bb0..9aa75517330 100644 --- a/src/librustdoc/html/static/js/source-script.js +++ b/src/librustdoc/html/static/js/source-script.js @@ -15,8 +15,13 @@ const NAME_OFFSET = 0; const DIRS_OFFSET = 1; const FILES_OFFSET = 2; +// WARNING: RUSTDOC_MOBILE_BREAKPOINT MEDIA QUERY +// If you update this line, then you also need to update the media query with the same +// warning in rustdoc.css +const RUSTDOC_MOBILE_BREAKPOINT = 700; + function closeSidebarIfMobile() { - if (window.innerWidth < window.RUSTDOC_MOBILE_BREAKPOINT) { + if (window.innerWidth < RUSTDOC_MOBILE_BREAKPOINT) { updateLocalStorage("source-sidebar-show", "false"); } } @@ -69,12 +74,10 @@ function createDirEntry(elem, parent, fullPath, hasFoundFile) { function toggleSidebar() { const child = this.parentNode.children[0]; if (child.innerText === ">") { - window.rustdocMobileScrollLock(); addClass(document.documentElement, "source-sidebar-expanded"); child.innerText = "<"; updateLocalStorage("source-sidebar-show", "true"); } else { - window.rustdocMobileScrollUnlock(); removeClass(document.documentElement, "source-sidebar-expanded"); child.innerText = ">"; updateLocalStorage("source-sidebar-show", "false"); diff --git a/src/librustdoc/html/templates/page.html b/src/librustdoc/html/templates/page.html index 532660e3d33..9133f899af6 100644 --- a/src/librustdoc/html/templates/page.html +++ b/src/librustdoc/html/templates/page.html @@ -64,7 +64,7 @@ </noscript> {# #} {% if layout.css_file_extension.is_some() %} <link rel="stylesheet" {#+ #} - href="{{static_root_path|safe}}theme{{page.resource_suffix}}.css"> {# #} + href="{{page.root_path|safe}}theme{{page.resource_suffix}}.css"> {# #} {% endif %} {% if !layout.favicon.is_empty() %} <link rel="icon" href="{{layout.favicon}}"> {# #} diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 79f53ee57cc..b3640eab953 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -7,7 +7,6 @@ #![feature(assert_matches)] #![feature(box_patterns)] #![feature(drain_filter)] -#![feature(is_terminal)] #![feature(let_chains)] #![feature(test)] #![feature(never_type)] @@ -15,6 +14,7 @@ #![feature(type_ascription)] #![feature(iter_intersperse)] #![feature(type_alias_impl_trait)] +#![cfg_attr(not(bootstrap), feature(impl_trait_in_assoc_type))] #![recursion_limit = "256"] #![warn(rustc::internal)] #![allow(clippy::collapsible_if, clippy::collapsible_else_if)] diff --git a/src/tools/clippy/tests/ui/crashes/ice-6252.stderr b/src/tools/clippy/tests/ui/crashes/ice-6252.stderr index efdd56dd47d..4787282f504 100644 --- a/src/tools/clippy/tests/ui/crashes/ice-6252.stderr +++ b/src/tools/clippy/tests/ui/crashes/ice-6252.stderr @@ -6,11 +6,11 @@ LL | _n: PhantomData, | help: consider importing one of these items | -LL | use core::marker::PhantomData; +LL + use core::marker::PhantomData; | -LL | use serde::__private::PhantomData; +LL + use serde::__private::PhantomData; | -LL | use std::marker::PhantomData; +LL + use std::marker::PhantomData; | error[E0412]: cannot find type `VAL` in this scope diff --git a/src/tools/clippy/tests/ui/derivable_impls.stderr b/src/tools/clippy/tests/ui/derivable_impls.stderr index 81963c3be5b..8089f5ea0fc 100644 --- a/src/tools/clippy/tests/ui/derivable_impls.stderr +++ b/src/tools/clippy/tests/ui/derivable_impls.stderr @@ -14,7 +14,8 @@ LL | | } = help: remove the manual implementation... help: ...and instead derive it | -LL | #[derive(Default)] +LL + #[derive(Default)] +LL | struct FooDefault<'a> { | error: this `impl` can be derived @@ -30,7 +31,8 @@ LL | | } = help: remove the manual implementation... help: ...and instead derive it | -LL | #[derive(Default)] +LL + #[derive(Default)] +LL | struct TupleDefault(bool, i32, u64); | error: this `impl` can be derived @@ -46,7 +48,8 @@ LL | | } = help: remove the manual implementation... help: ...and instead derive it | -LL | #[derive(Default)] +LL + #[derive(Default)] +LL | struct StrDefault<'a>(&'a str); | error: this `impl` can be derived @@ -62,7 +65,8 @@ LL | | } = help: remove the manual implementation... help: ...and instead derive it | -LL | #[derive(Default)] +LL + #[derive(Default)] +LL | struct Y(u32); | error: this `impl` can be derived @@ -78,7 +82,8 @@ LL | | } = help: remove the manual implementation... help: ...and instead derive it | -LL | #[derive(Default)] +LL + #[derive(Default)] +LL | struct WithoutSelfCurly { | error: this `impl` can be derived @@ -94,7 +99,8 @@ LL | | } = help: remove the manual implementation... help: ...and instead derive it | -LL | #[derive(Default)] +LL + #[derive(Default)] +LL | struct WithoutSelfParan(bool); | error: this `impl` can be derived @@ -110,7 +116,8 @@ LL | | } = help: remove the manual implementation... help: ...and instead derive it | -LL | #[derive(Default)] +LL + #[derive(Default)] +LL | pub struct RepeatDefault1 { | error: this `impl` can be derived @@ -126,7 +133,8 @@ LL | | } = help: remove the manual implementation... help: ...and instead derive it... | -LL | #[derive(Default)] +LL + #[derive(Default)] +LL | pub enum SimpleEnum { | help: ...and mark the default variant | diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs index 5c8aba6d441..f67a718ba73 100644 --- a/src/tools/miri/src/lib.rs +++ b/src/tools/miri/src/lib.rs @@ -7,7 +7,6 @@ #![feature(yeet_expr)] #![feature(nonzero_ops)] #![feature(local_key_cell_methods)] -#![feature(is_terminal)] #![feature(round_ties_even)] // Configure clippy and other lints #![allow( diff --git a/src/tools/miri/tests/pass/shims/fs.rs b/src/tools/miri/tests/pass/shims/fs.rs index 7a9974f3938..e379288de01 100644 --- a/src/tools/miri/tests/pass/shims/fs.rs +++ b/src/tools/miri/tests/pass/shims/fs.rs @@ -3,7 +3,6 @@ #![feature(io_error_more)] #![feature(io_error_uncategorized)] -#![feature(is_terminal)] use std::collections::HashMap; use std::ffi::{c_char, OsString}; diff --git a/src/tools/miri/tests/pass/shims/io.rs b/src/tools/miri/tests/pass/shims/io.rs index 4d43549a930..295723957a4 100644 --- a/src/tools/miri/tests/pass/shims/io.rs +++ b/src/tools/miri/tests/pass/shims/io.rs @@ -1,5 +1,3 @@ -#![feature(is_terminal)] - use std::io::IsTerminal; fn main() { diff --git a/src/tools/rust-installer/Cargo.toml b/src/tools/rust-installer/Cargo.toml index 788e556b0c6..97734f048ab 100644 --- a/src/tools/rust-installer/Cargo.toml +++ b/src/tools/rust-installer/Cargo.toml @@ -22,7 +22,3 @@ remove_dir_all = "0.5" [dependencies.clap] features = ["derive"] version = "3.1" - -[target."cfg(windows)".dependencies] -lazy_static = "1" -winapi = { version = "0.3", features = ["errhandlingapi", "handleapi", "ioapiset", "winerror", "winioctl", "winnt"] } diff --git a/src/tools/rust-installer/src/remove_dir_all.rs b/src/tools/rust-installer/src/remove_dir_all.rs deleted file mode 100644 index 11097652865..00000000000 --- a/src/tools/rust-installer/src/remove_dir_all.rs +++ /dev/null @@ -1,860 +0,0 @@ -#![allow(non_snake_case)] - -use std::io; -use std::path::Path; - -#[cfg(not(windows))] -pub fn remove_dir_all(path: &Path) -> io::Result<()> { - ::std::fs::remove_dir_all(path) -} - -#[cfg(windows)] -pub fn remove_dir_all(path: &Path) -> io::Result<()> { - win::remove_dir_all(path) -} - -#[cfg(windows)] -mod win { - use winapi::ctypes::{c_uint, c_ushort}; - use winapi::shared::minwindef::{BOOL, DWORD, FALSE, FILETIME, LPVOID}; - use winapi::shared::winerror::{ - ERROR_CALL_NOT_IMPLEMENTED, ERROR_INSUFFICIENT_BUFFER, ERROR_NO_MORE_FILES, - }; - use winapi::um::errhandlingapi::{GetLastError, SetLastError}; - use winapi::um::fileapi::{ - CreateFileW, FindFirstFileW, FindNextFileW, GetFileInformationByHandle, - }; - use winapi::um::fileapi::{BY_HANDLE_FILE_INFORMATION, CREATE_ALWAYS, CREATE_NEW}; - use winapi::um::fileapi::{FILE_BASIC_INFO, FILE_RENAME_INFO, TRUNCATE_EXISTING}; - use winapi::um::fileapi::{OPEN_ALWAYS, OPEN_EXISTING}; - use winapi::um::handleapi::{CloseHandle, INVALID_HANDLE_VALUE}; - use winapi::um::ioapiset::DeviceIoControl; - use winapi::um::libloaderapi::{GetModuleHandleW, GetProcAddress}; - use winapi::um::minwinbase::{ - FileBasicInfo, FileRenameInfo, FILE_INFO_BY_HANDLE_CLASS, WIN32_FIND_DATAW, - }; - use winapi::um::winbase::SECURITY_SQOS_PRESENT; - use winapi::um::winbase::{ - FILE_FLAG_BACKUP_SEMANTICS, FILE_FLAG_DELETE_ON_CLOSE, FILE_FLAG_OPEN_REPARSE_POINT, - }; - use winapi::um::winioctl::FSCTL_GET_REPARSE_POINT; - use winapi::um::winnt::{DELETE, FILE_ATTRIBUTE_DIRECTORY, HANDLE, LPCWSTR}; - use winapi::um::winnt::{FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_REPARSE_POINT}; - use winapi::um::winnt::{FILE_GENERIC_WRITE, FILE_WRITE_DATA, GENERIC_READ, GENERIC_WRITE}; - use winapi::um::winnt::{FILE_READ_ATTRIBUTES, FILE_WRITE_ATTRIBUTES}; - use winapi::um::winnt::{FILE_SHARE_DELETE, FILE_SHARE_READ, FILE_SHARE_WRITE}; - use winapi::um::winnt::{IO_REPARSE_TAG_MOUNT_POINT, IO_REPARSE_TAG_SYMLINK, LARGE_INTEGER}; - - use std::ffi::{OsStr, OsString}; - use std::io; - use std::mem; - use std::os::windows::ffi::{OsStrExt, OsStringExt}; - use std::path::{Path, PathBuf}; - use std::ptr; - use std::sync::Arc; - - pub fn remove_dir_all(path: &Path) -> io::Result<()> { - // On Windows it is not enough to just recursively remove the contents of a - // directory and then the directory itself. Deleting does not happen - // instantaneously, but is scheduled. - // To work around this, we move the file or directory to some `base_dir` - // right before deletion to avoid races. - // - // As `base_dir` we choose the parent dir of the directory we want to - // remove. We very probably have permission to create files here, as we - // already need write permission in this dir to delete the directory. And it - // should be on the same volume. - // - // To handle files with names like `CON` and `morse .. .`, and when a - // directory structure is so deep it needs long path names the path is first - // converted to a `//?/`-path with `get_path()`. - // - // To make sure we don't leave a moved file laying around if the process - // crashes before we can delete the file, we do all operations on an file - // handle. By opening a file with `FILE_FLAG_DELETE_ON_CLOSE` Windows will - // always delete the file when the handle closes. - // - // All files are renamed to be in the `base_dir`, and have their name - // changed to "rm-<counter>". After every rename the counter is increased. - // Rename should not overwrite possibly existing files in the base dir. So - // if it fails with `AlreadyExists`, we just increase the counter and try - // again. - // - // For read-only files and directories we first have to remove the read-only - // attribute before we can move or delete them. This also removes the - // attribute from possible hardlinks to the file, so just before closing we - // restore the read-only attribute. - // - // If 'path' points to a directory symlink or junction we should not - // recursively remove the target of the link, but only the link itself. - // - // Moving and deleting is guaranteed to succeed if we are able to open the - // file with `DELETE` permission. If others have the file open we only have - // `DELETE` permission if they have specified `FILE_SHARE_DELETE`. We can - // also delete the file now, but it will not disappear until all others have - // closed the file. But no-one can open the file after we have flagged it - // for deletion. - - // Open the path once to get the canonical path, file type and attributes. - let (path, metadata) = { - let mut opts = OpenOptions::new(); - opts.access_mode(FILE_READ_ATTRIBUTES); - opts.custom_flags(FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT); - let file = File::open(path, &opts)?; - (get_path(&file)?, file.file_attr()?) - }; - - let mut ctx = RmdirContext { - base_dir: match path.parent() { - Some(dir) => dir, - None => { - return Err(io::Error::new( - io::ErrorKind::PermissionDenied, - "can't delete root directory", - )) - } - }, - readonly: metadata.perm().readonly(), - counter: 0, - }; - - let filetype = metadata.file_type(); - if filetype.is_dir() { - remove_dir_all_recursive(path.as_ref(), &mut ctx) - } else if filetype.is_symlink_dir() { - remove_item(path.as_ref(), &mut ctx) - } else { - Err(io::Error::new( - io::ErrorKind::PermissionDenied, - "Not a directory", - )) - } - } - - fn readdir(p: &Path) -> io::Result<ReadDir> { - let root = p.to_path_buf(); - let star = p.join("*"); - let path = to_u16s(&star)?; - - unsafe { - let mut wfd = mem::zeroed(); - let find_handle = FindFirstFileW(path.as_ptr(), &mut wfd); - if find_handle != INVALID_HANDLE_VALUE { - Ok(ReadDir { - handle: FindNextFileHandle(find_handle), - root: Arc::new(root), - first: Some(wfd), - }) - } else { - Err(io::Error::last_os_error()) - } - } - } - - struct RmdirContext<'a> { - base_dir: &'a Path, - readonly: bool, - counter: u64, - } - - fn remove_dir_all_recursive(path: &Path, ctx: &mut RmdirContext) -> io::Result<()> { - let dir_readonly = ctx.readonly; - for child in readdir(path)? { - let child = child?; - let child_type = child.file_type()?; - ctx.readonly = child.metadata()?.perm().readonly(); - if child_type.is_dir() { - remove_dir_all_recursive(&child.path(), ctx)?; - } else { - remove_item(&child.path().as_ref(), ctx)?; - } - } - ctx.readonly = dir_readonly; - remove_item(path, ctx) - } - - fn remove_item(path: &Path, ctx: &mut RmdirContext) -> io::Result<()> { - if !ctx.readonly { - let mut opts = OpenOptions::new(); - opts.access_mode(DELETE); - opts.custom_flags( - FILE_FLAG_BACKUP_SEMANTICS | // delete directory - FILE_FLAG_OPEN_REPARSE_POINT | // delete symlink - FILE_FLAG_DELETE_ON_CLOSE, - ); - let file = File::open(path, &opts)?; - move_item(&file, ctx) - } else { - // remove read-only permision - set_perm(&path, FilePermissions::new())?; - // move and delete file, similar to !readonly. - // only the access mode is different. - let mut opts = OpenOptions::new(); - opts.access_mode(DELETE | FILE_WRITE_ATTRIBUTES); - opts.custom_flags( - FILE_FLAG_BACKUP_SEMANTICS - | FILE_FLAG_OPEN_REPARSE_POINT - | FILE_FLAG_DELETE_ON_CLOSE, - ); - let file = File::open(path, &opts)?; - move_item(&file, ctx)?; - // restore read-only flag just in case there are other hard links - let mut perm = FilePermissions::new(); - perm.set_readonly(true); - let _ = file.set_perm(perm); // ignore if this fails - Ok(()) - } - } - - macro_rules! compat_fn { - ($module:ident: $( - fn $symbol:ident($($argname:ident: $argtype:ty),*) - -> $rettype:ty { - $($body:expr);* - } - )*) => ($( - #[allow(unused_variables)] - unsafe fn $symbol($($argname: $argtype),*) -> $rettype { - use std::sync::atomic::{AtomicUsize, Ordering}; - use std::mem; - use std::ffi::CString; - type F = unsafe extern "system" fn($($argtype),*) -> $rettype; - - lazy_static! { static ref PTR: AtomicUsize = AtomicUsize::new(0);} - - fn lookup(module: &str, symbol: &str) -> Option<usize> { - let mut module: Vec<u16> = module.encode_utf16().collect(); - module.push(0); - let symbol = CString::new(symbol).unwrap(); - unsafe { - let handle = GetModuleHandleW(module.as_ptr()); - match GetProcAddress(handle, symbol.as_ptr()) as usize { - 0 => None, - n => Some(n), - } - } - } - - fn store_func(ptr: &AtomicUsize, module: &str, symbol: &str, - fallback: usize) -> usize { - let value = lookup(module, symbol).unwrap_or(fallback); - ptr.store(value, Ordering::SeqCst); - value - } - - fn load() -> usize { - store_func(&PTR, stringify!($module), stringify!($symbol), fallback as usize) - } - unsafe extern "system" fn fallback($($argname: $argtype),*) - -> $rettype { - $($body);* - } - - let addr = match PTR.load(Ordering::SeqCst) { - 0 => load(), - n => n, - }; - mem::transmute::<usize, F>(addr)($($argname),*) - } - )*) - } - - compat_fn! { - kernel32: - fn GetFinalPathNameByHandleW(_hFile: HANDLE, - _lpszFilePath: LPCWSTR, - _cchFilePath: DWORD, - _dwFlags: DWORD) -> DWORD { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); 0 - } - fn SetFileInformationByHandle(_hFile: HANDLE, - _FileInformationClass: FILE_INFO_BY_HANDLE_CLASS, - _lpFileInformation: LPVOID, - _dwBufferSize: DWORD) -> BOOL { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); 0 - } - } - - fn cvt(i: i32) -> io::Result<i32> { - if i == 0 { - Err(io::Error::last_os_error()) - } else { - Ok(i) - } - } - - fn to_u16s<S: AsRef<OsStr>>(s: S) -> io::Result<Vec<u16>> { - fn inner(s: &OsStr) -> io::Result<Vec<u16>> { - let mut maybe_result: Vec<u16> = s.encode_wide().collect(); - if maybe_result.iter().any(|&u| u == 0) { - return Err(io::Error::new( - io::ErrorKind::InvalidInput, - "strings passed to WinAPI cannot contain NULs", - )); - } - maybe_result.push(0); - Ok(maybe_result) - } - inner(s.as_ref()) - } - - fn truncate_utf16_at_nul<'a>(v: &'a [u16]) -> &'a [u16] { - match v.iter().position(|c| *c == 0) { - // don't include the 0 - Some(i) => &v[..i], - None => v, - } - } - - fn fill_utf16_buf<F1, F2, T>(mut f1: F1, f2: F2) -> io::Result<T> - where - F1: FnMut(*mut u16, DWORD) -> DWORD, - F2: FnOnce(&[u16]) -> T, - { - // Start off with a stack buf but then spill over to the heap if we end up - // needing more space. - let mut stack_buf = [0u16; 512]; - let mut heap_buf = Vec::new(); - unsafe { - let mut n = stack_buf.len(); - loop { - let buf = if n <= stack_buf.len() { - &mut stack_buf[..] - } else { - let extra = n - heap_buf.len(); - heap_buf.reserve(extra); - heap_buf.set_len(n); - &mut heap_buf[..] - }; - - // This function is typically called on windows API functions which - // will return the correct length of the string, but these functions - // also return the `0` on error. In some cases, however, the - // returned "correct length" may actually be 0! - // - // To handle this case we call `SetLastError` to reset it to 0 and - // then check it again if we get the "0 error value". If the "last - // error" is still 0 then we interpret it as a 0 length buffer and - // not an actual error. - SetLastError(0); - let k = match f1(buf.as_mut_ptr(), n as DWORD) { - 0 if GetLastError() == 0 => 0, - 0 => return Err(io::Error::last_os_error()), - n => n, - } as usize; - if k == n && GetLastError() == ERROR_INSUFFICIENT_BUFFER { - n *= 2; - } else if k >= n { - n = k; - } else { - return Ok(f2(&buf[..k])); - } - } - } - } - - #[derive(Clone, PartialEq, Eq, Debug, Default)] - struct FilePermissions { - readonly: bool, - } - - impl FilePermissions { - fn new() -> FilePermissions { - Default::default() - } - fn readonly(&self) -> bool { - self.readonly - } - fn set_readonly(&mut self, readonly: bool) { - self.readonly = readonly - } - } - - #[derive(Clone)] - struct OpenOptions { - // generic - read: bool, - write: bool, - append: bool, - truncate: bool, - create: bool, - create_new: bool, - // system-specific - custom_flags: u32, - access_mode: Option<DWORD>, - attributes: DWORD, - share_mode: DWORD, - security_qos_flags: DWORD, - security_attributes: usize, // FIXME: should be a reference - } - - impl OpenOptions { - fn new() -> OpenOptions { - OpenOptions { - // generic - read: false, - write: false, - append: false, - truncate: false, - create: false, - create_new: false, - // system-specific - custom_flags: 0, - access_mode: None, - share_mode: FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - attributes: 0, - security_qos_flags: 0, - security_attributes: 0, - } - } - fn custom_flags(&mut self, flags: u32) { - self.custom_flags = flags; - } - fn access_mode(&mut self, access_mode: u32) { - self.access_mode = Some(access_mode); - } - - fn get_access_mode(&self) -> io::Result<DWORD> { - const ERROR_INVALID_PARAMETER: i32 = 87; - - match (self.read, self.write, self.append, self.access_mode) { - (_, _, _, Some(mode)) => Ok(mode), - (true, false, false, None) => Ok(GENERIC_READ), - (false, true, false, None) => Ok(GENERIC_WRITE), - (true, true, false, None) => Ok(GENERIC_READ | GENERIC_WRITE), - (false, _, true, None) => Ok(FILE_GENERIC_WRITE & !FILE_WRITE_DATA), - (true, _, true, None) => Ok(GENERIC_READ | (FILE_GENERIC_WRITE & !FILE_WRITE_DATA)), - (false, false, false, None) => { - Err(io::Error::from_raw_os_error(ERROR_INVALID_PARAMETER)) - } - } - } - - fn get_creation_mode(&self) -> io::Result<DWORD> { - const ERROR_INVALID_PARAMETER: i32 = 87; - - match (self.write, self.append) { - (true, false) => {} - (false, false) => { - if self.truncate || self.create || self.create_new { - return Err(io::Error::from_raw_os_error(ERROR_INVALID_PARAMETER)); - } - } - (_, true) => { - if self.truncate && !self.create_new { - return Err(io::Error::from_raw_os_error(ERROR_INVALID_PARAMETER)); - } - } - } - - Ok(match (self.create, self.truncate, self.create_new) { - (false, false, false) => OPEN_EXISTING, - (true, false, false) => OPEN_ALWAYS, - (false, true, false) => TRUNCATE_EXISTING, - (true, true, false) => CREATE_ALWAYS, - (_, _, true) => CREATE_NEW, - }) - } - - fn get_flags_and_attributes(&self) -> DWORD { - self.custom_flags - | self.attributes - | self.security_qos_flags - | if self.security_qos_flags != 0 { - SECURITY_SQOS_PRESENT - } else { - 0 - } - | if self.create_new { - FILE_FLAG_OPEN_REPARSE_POINT - } else { - 0 - } - } - } - - struct File { - handle: Handle, - } - - impl File { - fn open(path: &Path, opts: &OpenOptions) -> io::Result<File> { - let path = to_u16s(path)?; - let handle = unsafe { - CreateFileW( - path.as_ptr(), - opts.get_access_mode()?, - opts.share_mode, - opts.security_attributes as *mut _, - opts.get_creation_mode()?, - opts.get_flags_and_attributes(), - ptr::null_mut(), - ) - }; - if handle == INVALID_HANDLE_VALUE { - Err(io::Error::last_os_error()) - } else { - Ok(File { - handle: Handle::new(handle), - }) - } - } - - fn file_attr(&self) -> io::Result<FileAttr> { - unsafe { - let mut info: BY_HANDLE_FILE_INFORMATION = mem::zeroed(); - cvt(GetFileInformationByHandle(self.handle.raw(), &mut info))?; - let mut attr = FileAttr { - attributes: info.dwFileAttributes, - creation_time: info.ftCreationTime, - last_access_time: info.ftLastAccessTime, - last_write_time: info.ftLastWriteTime, - file_size: ((info.nFileSizeHigh as u64) << 32) | (info.nFileSizeLow as u64), - reparse_tag: 0, - }; - if attr.is_reparse_point() { - let mut b = [0; MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; - if let Ok((_, buf)) = self.reparse_point(&mut b) { - attr.reparse_tag = buf.ReparseTag; - } - } - Ok(attr) - } - } - - fn set_attributes(&self, attr: DWORD) -> io::Result<()> { - let zero: LARGE_INTEGER = unsafe { mem::zeroed() }; - - let mut info = FILE_BASIC_INFO { - CreationTime: zero, // do not change - LastAccessTime: zero, // do not change - LastWriteTime: zero, // do not change - ChangeTime: zero, // do not change - FileAttributes: attr, - }; - let size = mem::size_of_val(&info); - cvt(unsafe { - SetFileInformationByHandle( - self.handle.raw(), - FileBasicInfo, - &mut info as *mut _ as *mut _, - size as DWORD, - ) - })?; - Ok(()) - } - - fn rename(&self, new: &Path, replace: bool) -> io::Result<()> { - // &self must be opened with DELETE permission - use std::iter; - #[cfg(target_arch = "x86")] - const STRUCT_SIZE: usize = 12; - #[cfg(target_arch = "x86_64")] - const STRUCT_SIZE: usize = 20; - - // FIXME: check for internal NULs in 'new' - let mut data: Vec<u16> = iter::repeat(0u16) - .take(STRUCT_SIZE / 2) - .chain(new.as_os_str().encode_wide()) - .collect(); - data.push(0); - let size = data.len() * 2; - - unsafe { - // Thanks to alignment guarantees on Windows this works - // (8 for 32-bit and 16 for 64-bit) - let info = data.as_mut_ptr() as *mut FILE_RENAME_INFO; - // The type of ReplaceIfExists is BOOL, but it actually expects a - // BOOLEAN. This means true is -1, not c::TRUE. - (*info).ReplaceIfExists = if replace { -1 } else { FALSE }; - (*info).RootDirectory = ptr::null_mut(); - (*info).FileNameLength = (size - STRUCT_SIZE) as DWORD; - cvt(SetFileInformationByHandle( - self.handle().raw(), - FileRenameInfo, - data.as_mut_ptr() as *mut _ as *mut _, - size as DWORD, - ))?; - Ok(()) - } - } - fn set_perm(&self, perm: FilePermissions) -> io::Result<()> { - let attr = self.file_attr()?.attributes; - if perm.readonly == (attr & FILE_ATTRIBUTE_READONLY != 0) { - Ok(()) - } else if perm.readonly { - self.set_attributes(attr | FILE_ATTRIBUTE_READONLY) - } else { - self.set_attributes(attr & !FILE_ATTRIBUTE_READONLY) - } - } - - fn handle(&self) -> &Handle { - &self.handle - } - - fn reparse_point<'a>( - &self, - space: &'a mut [u8; MAXIMUM_REPARSE_DATA_BUFFER_SIZE], - ) -> io::Result<(DWORD, &'a REPARSE_DATA_BUFFER)> { - unsafe { - let mut bytes = 0; - cvt({ - DeviceIoControl( - self.handle.raw(), - FSCTL_GET_REPARSE_POINT, - ptr::null_mut(), - 0, - space.as_mut_ptr() as *mut _, - space.len() as DWORD, - &mut bytes, - ptr::null_mut(), - ) - })?; - Ok((bytes, &*(space.as_ptr() as *const REPARSE_DATA_BUFFER))) - } - } - } - - #[derive(Copy, Clone, PartialEq, Eq, Hash)] - enum FileType { - Dir, - File, - SymlinkFile, - SymlinkDir, - ReparsePoint, - MountPoint, - } - - impl FileType { - fn new(attrs: DWORD, reparse_tag: DWORD) -> FileType { - match ( - attrs & FILE_ATTRIBUTE_DIRECTORY != 0, - attrs & FILE_ATTRIBUTE_REPARSE_POINT != 0, - reparse_tag, - ) { - (false, false, _) => FileType::File, - (true, false, _) => FileType::Dir, - (false, true, IO_REPARSE_TAG_SYMLINK) => FileType::SymlinkFile, - (true, true, IO_REPARSE_TAG_SYMLINK) => FileType::SymlinkDir, - (true, true, IO_REPARSE_TAG_MOUNT_POINT) => FileType::MountPoint, - (_, true, _) => FileType::ReparsePoint, - // Note: if a _file_ has a reparse tag of the type IO_REPARSE_TAG_MOUNT_POINT it is - // invalid, as junctions always have to be dirs. We set the filetype to ReparsePoint - // to indicate it is something symlink-like, but not something you can follow. - } - } - - fn is_dir(&self) -> bool { - *self == FileType::Dir - } - fn is_symlink_dir(&self) -> bool { - *self == FileType::SymlinkDir || *self == FileType::MountPoint - } - } - - impl DirEntry { - fn new(root: &Arc<PathBuf>, wfd: &WIN32_FIND_DATAW) -> Option<DirEntry> { - let first_bytes = &wfd.cFileName[0..3]; - if first_bytes.starts_with(&[46, 0]) || first_bytes.starts_with(&[46, 46, 0]) { - None - } else { - Some(DirEntry { - root: root.clone(), - data: *wfd, - }) - } - } - - fn path(&self) -> PathBuf { - self.root.join(&self.file_name()) - } - - fn file_name(&self) -> OsString { - let filename = truncate_utf16_at_nul(&self.data.cFileName); - OsString::from_wide(filename) - } - - fn file_type(&self) -> io::Result<FileType> { - Ok(FileType::new( - self.data.dwFileAttributes, - /* reparse_tag = */ self.data.dwReserved0, - )) - } - - fn metadata(&self) -> io::Result<FileAttr> { - Ok(FileAttr { - attributes: self.data.dwFileAttributes, - creation_time: self.data.ftCreationTime, - last_access_time: self.data.ftLastAccessTime, - last_write_time: self.data.ftLastWriteTime, - file_size: ((self.data.nFileSizeHigh as u64) << 32) - | (self.data.nFileSizeLow as u64), - reparse_tag: if self.data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT != 0 { - // reserved unless this is a reparse point - self.data.dwReserved0 - } else { - 0 - }, - }) - } - } - - struct DirEntry { - root: Arc<PathBuf>, - data: WIN32_FIND_DATAW, - } - - struct ReadDir { - handle: FindNextFileHandle, - root: Arc<PathBuf>, - first: Option<WIN32_FIND_DATAW>, - } - - impl Iterator for ReadDir { - type Item = io::Result<DirEntry>; - fn next(&mut self) -> Option<io::Result<DirEntry>> { - if let Some(first) = self.first.take() { - if let Some(e) = DirEntry::new(&self.root, &first) { - return Some(Ok(e)); - } - } - unsafe { - let mut wfd = mem::zeroed(); - loop { - if FindNextFileW(self.handle.0, &mut wfd) == 0 { - if GetLastError() == ERROR_NO_MORE_FILES { - return None; - } else { - return Some(Err(io::Error::last_os_error())); - } - } - if let Some(e) = DirEntry::new(&self.root, &wfd) { - return Some(Ok(e)); - } - } - } - } - } - - #[derive(Clone)] - struct FileAttr { - attributes: DWORD, - creation_time: FILETIME, - last_access_time: FILETIME, - last_write_time: FILETIME, - file_size: u64, - reparse_tag: DWORD, - } - - impl FileAttr { - fn perm(&self) -> FilePermissions { - FilePermissions { - readonly: self.attributes & FILE_ATTRIBUTE_READONLY != 0, - } - } - - fn file_type(&self) -> FileType { - FileType::new(self.attributes, self.reparse_tag) - } - - fn is_reparse_point(&self) -> bool { - self.attributes & FILE_ATTRIBUTE_REPARSE_POINT != 0 - } - } - - #[repr(C)] - struct REPARSE_DATA_BUFFER { - ReparseTag: c_uint, - ReparseDataLength: c_ushort, - Reserved: c_ushort, - rest: (), - } - - const MAXIMUM_REPARSE_DATA_BUFFER_SIZE: usize = 16 * 1024; - - /// An owned container for `HANDLE` object, closing them on Drop. - /// - /// All methods are inherited through a `Deref` impl to `RawHandle` - struct Handle(RawHandle); - - use std::ops::Deref; - - /// A wrapper type for `HANDLE` objects to give them proper Send/Sync inference - /// as well as Rust-y methods. - /// - /// This does **not** drop the handle when it goes out of scope, use `Handle` - /// instead for that. - #[derive(Copy, Clone)] - struct RawHandle(HANDLE); - - unsafe impl Send for RawHandle {} - unsafe impl Sync for RawHandle {} - - impl Handle { - fn new(handle: HANDLE) -> Handle { - Handle(RawHandle::new(handle)) - } - } - - impl Deref for Handle { - type Target = RawHandle; - fn deref(&self) -> &RawHandle { - &self.0 - } - } - - impl Drop for Handle { - fn drop(&mut self) { - unsafe { - let _ = CloseHandle(self.raw()); - } - } - } - - impl RawHandle { - fn new(handle: HANDLE) -> RawHandle { - RawHandle(handle) - } - - fn raw(&self) -> HANDLE { - self.0 - } - } - - struct FindNextFileHandle(HANDLE); - - fn get_path(f: &File) -> io::Result<PathBuf> { - fill_utf16_buf( - |buf, sz| unsafe { - GetFinalPathNameByHandleW(f.handle.raw(), buf, sz, VOLUME_NAME_DOS) - }, - |buf| PathBuf::from(OsString::from_wide(buf)), - ) - } - - fn move_item(file: &File, ctx: &mut RmdirContext) -> io::Result<()> { - let mut tmpname = ctx.base_dir.join(format! {"rm-{}", ctx.counter}); - ctx.counter += 1; - // Try to rename the file. If it already exists, just retry with an other - // filename. - while let Err(err) = file.rename(tmpname.as_ref(), false) { - if err.kind() != io::ErrorKind::AlreadyExists { - return Err(err); - }; - tmpname = ctx.base_dir.join(format!("rm-{}", ctx.counter)); - ctx.counter += 1; - } - Ok(()) - } - - fn set_perm(path: &Path, perm: FilePermissions) -> io::Result<()> { - let mut opts = OpenOptions::new(); - opts.access_mode(FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES); - opts.custom_flags(FILE_FLAG_BACKUP_SEMANTICS); - let file = File::open(path, &opts)?; - file.set_perm(perm) - } - - const VOLUME_NAME_DOS: DWORD = 0x0; -} diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs index 0f08f5d0b70..7b7ee62a247 100644 --- a/src/tools/tidy/src/ui_tests.rs +++ b/src/tools/tidy/src/ui_tests.rs @@ -9,7 +9,7 @@ use std::path::{Path, PathBuf}; // FIXME: The following limits should be reduced eventually. const ENTRY_LIMIT: usize = 885; -const ROOT_ENTRY_LIMIT: usize = 881; +const ROOT_ENTRY_LIMIT: usize = 880; const ISSUES_ENTRY_LIMIT: usize = 1978; fn check_entries(tests_path: &Path, bad: &mut bool) { @@ -22,18 +22,19 @@ fn check_entries(tests_path: &Path, bad: &mut bool) { } } + let (mut max, mut max_root, mut max_issues) = (0usize, 0usize, 0usize); for (dir_path, count) in directories { // Use special values for these dirs. let is_root = tests_path.join("ui") == dir_path; let is_issues_dir = tests_path.join("ui/issues") == dir_path; - let limit = if is_root { - ROOT_ENTRY_LIMIT + let (limit, maxcnt) = if is_root { + (ROOT_ENTRY_LIMIT, &mut max_root) } else if is_issues_dir { - ISSUES_ENTRY_LIMIT + (ISSUES_ENTRY_LIMIT, &mut max_issues) } else { - ENTRY_LIMIT + (ENTRY_LIMIT, &mut max) }; - + *maxcnt = (*maxcnt).max(count); if count > limit { tidy_error!( bad, @@ -45,6 +46,21 @@ fn check_entries(tests_path: &Path, bad: &mut bool) { ); } } + if ENTRY_LIMIT > max { + tidy_error!(bad, "`ENTRY_LIMIT` is too high (is {ENTRY_LIMIT}, should be {max})"); + } + if ROOT_ENTRY_LIMIT > max_root { + tidy_error!( + bad, + "`ROOT_ENTRY_LIMIT` is too high (is {ROOT_ENTRY_LIMIT}, should be {max_root})" + ); + } + if ISSUES_ENTRY_LIMIT > max_issues { + tidy_error!( + bad, + "`ISSUES_ENTRY_LIMIT` is too high (is {ISSUES_ENTRY_LIMIT}, should be {max_issues})" + ); + } } pub fn check(path: &Path, bad: &mut bool) { diff --git a/tests/assembly/asm/m68k-types.rs b/tests/assembly/asm/m68k-types.rs new file mode 100644 index 00000000000..0322e615a19 --- /dev/null +++ b/tests/assembly/asm/m68k-types.rs @@ -0,0 +1,83 @@ +// assembly-output: emit-asm +// compile-flags: --target m68k-unknown-linux-gnu +// needs-llvm-components: m68k + +#![feature(no_core, lang_items, rustc_attrs, asm_experimental_arch)] +#![crate_type = "rlib"] +#![no_core] +#![allow(non_camel_case_types)] + +#[rustc_builtin_macro] +macro_rules! asm { + () => {}; +} +#[rustc_builtin_macro] +macro_rules! concat { + () => {}; +} + +#[lang = "sized"] +trait Sized {} +#[lang = "copy"] +trait Copy {} + +type ptr = *const u64; + +impl Copy for i8 {} +impl Copy for i16 {} +impl Copy for i32 {} +impl Copy for i64 {} +impl Copy for ptr {} + +macro_rules! check { + ($func:ident $ty:ident $class:ident $mov:literal) => { + #[no_mangle] + pub unsafe fn $func(x: $ty) -> $ty { + let y; + asm!(concat!($mov, " {}, {};"), out($class) y, in($class) x); + y + } + }; +} + +// CHECK-LABEL: reg_data_i8: +// CHECK: ;APP +// CHECK: move.b %d{{[0-9]}}, %d{{[0-9]}} +// CHECK: ;NO_APP +check!(reg_data_i8 i8 reg_data "move.b"); + +// CHECK-LABEL: reg_data_i16: +// CHECK: ;APP +// CHECK: move.w %d{{[0-9]}}, %d{{[0-9]}} +// CHECK: ;NO_APP +check!(reg_data_i16 i16 reg_data "move.w"); + +// CHECK-LABEL: reg_data_i32: +// CHECK: ;APP +// CHECK: move.l %d{{[0-9]}}, %d{{[0-9]}} +// CHECK: ;NO_APP +check!(reg_data_i32 i32 reg_data "move.l"); + +// CHECK-LABEL: reg_addr_i16: +// CHECK: ;APP +// CHECK: move.w %a{{[0-9]}}, %a{{[0-9]}} +// CHECK: ;NO_APP +check!(reg_addr_i16 i16 reg_addr "move.w"); + +// CHECK-LABEL: reg_addr_i32: +// CHECK: ;APP +// CHECK: move.l %a{{[0-9]}}, %a{{[0-9]}} +// CHECK: ;NO_APP +check!(reg_addr_i32 i32 reg_addr "move.l"); + +// CHECK-LABEL: reg_i16: +// CHECK: ;APP +// CHECK: move.w %{{[da][0-9]}}, %{{[da][0-9]}} +// CHECK: ;NO_APP +check!(reg_i16 i16 reg "move.w"); + +// CHECK-LABEL: reg_i32: +// CHECK: ;APP +// CHECK: move.l %{{[da][0-9]}}, %{{[da][0-9]}} +// CHECK: ;NO_APP +check!(reg_i32 i32 reg "move.l"); diff --git a/tests/codegen/inline-function-args-debug-info.rs b/tests/codegen/inline-function-args-debug-info.rs new file mode 100644 index 00000000000..e3d8caa49d4 --- /dev/null +++ b/tests/codegen/inline-function-args-debug-info.rs @@ -0,0 +1,20 @@ +// This test checks that debug information includes function argument indexes even if the function +// gets inlined by MIR inlining. Without function argument indexes, `info args` in gdb won't show +// arguments and their values for the current function. + +// compile-flags: -Zinline-mir=yes -Cdebuginfo=2 --edition=2021 + +#![crate_type = "lib"] + +pub fn outer_function(x: usize, y: usize) -> usize { + inner_function(x, y) + 1 +} + +#[inline] +fn inner_function(aaaa: usize, bbbb: usize) -> usize { + // CHECK: !DILocalVariable(name: "aaaa", arg: 1 + // CHECK-SAME: line: 14 + // CHECK: !DILocalVariable(name: "bbbb", arg: 2 + // CHECK-SAME: line: 14 + aaaa + bbbb +} diff --git a/tests/incremental/issue-108481-feed-eval-always.rs b/tests/incremental/issue-108481-feed-eval-always.rs new file mode 100644 index 00000000000..8f346a7207e --- /dev/null +++ b/tests/incremental/issue-108481-feed-eval-always.rs @@ -0,0 +1,16 @@ +// revisions: cpass1 cpass2 + +#![crate_type = "rlib"] + +use std::fmt::Debug; + +// MCVE kindly provided by Nilstrieb at +// https://github.com/rust-lang/rust/issues/108481#issuecomment-1493080185 + +#[derive(Debug)] +pub struct ConstGeneric<const CHUNK_SIZE: usize> { + _p: [(); CHUNK_SIZE], +} + +#[cfg(cpass1)] +impl<const CHUNK_SIZE: usize> ConstGeneric<CHUNK_SIZE> {} diff --git a/tests/mir-opt/building/custom/references.raw_pointer_offset.built.after.mir b/tests/mir-opt/building/custom/references.raw_pointer_offset.built.after.mir new file mode 100644 index 00000000000..f614aef4029 --- /dev/null +++ b/tests/mir-opt/building/custom/references.raw_pointer_offset.built.after.mir @@ -0,0 +1,10 @@ +// MIR for `raw_pointer_offset` after built + +fn raw_pointer_offset(_1: *const i32) -> *const i32 { + let mut _0: *const i32; // return place in scope 0 at $DIR/references.rs:+0:45: +0:55 + + bb0: { + _0 = Offset(_1, const 1_isize); // scope 0 at $DIR/references.rs:+2:9: +2:33 + return; // scope 0 at $DIR/references.rs:+3:9: +3:17 + } +} diff --git a/tests/mir-opt/building/custom/references.rs b/tests/mir-opt/building/custom/references.rs index a1c896de04c..f87f6664c7a 100644 --- a/tests/mir-opt/building/custom/references.rs +++ b/tests/mir-opt/building/custom/references.rs @@ -45,11 +45,22 @@ pub fn raw_pointer(x: *const i32) -> *const i32 { }) } +// EMIT_MIR references.raw_pointer_offset.built.after.mir +#[custom_mir(dialect = "built")] +pub fn raw_pointer_offset(x: *const i32) -> *const i32 { + mir!({ + RET = Offset(x, 1_isize); + Return() + }) +} + fn main() { let mut x = 5; + let arr = [1, 2]; assert_eq!(*mut_ref(&mut x), 5); assert_eq!(*immut_ref(&x), 5); unsafe { assert_eq!(*raw_pointer(addr_of!(x)), 5); + assert_eq!(*raw_pointer_offset(addr_of!(arr[0])), 2); } } diff --git a/tests/run-make/rustdoc-shared-flags/Makefile b/tests/run-make/rustdoc-shared-flags/Makefile new file mode 100644 index 00000000000..a2a7d7b3634 --- /dev/null +++ b/tests/run-make/rustdoc-shared-flags/Makefile @@ -0,0 +1,18 @@ +include ../tools.mk + +all: z_help c_help list_passes + +c_help: + $(RUSTC) -C help > $(TMPDIR)/rustc.c_help.txt + $(RUSTDOC) -C help > $(TMPDIR)/rustdoc.c_help.txt + $(DIFF) $(TMPDIR)/rustc.c_help.txt $(TMPDIR)/rustdoc.c_help.txt + +z_help: + $(RUSTC) -Z help > $(TMPDIR)/rustc.z_help.txt + $(RUSTDOC) -Z help > $(TMPDIR)/rustdoc.z_help.txt + $(DIFF) $(TMPDIR)/rustc.z_help.txt $(TMPDIR)/rustdoc.z_help.txt + +list_passes: + $(RUSTC) -C passes=list > $(TMPDIR)/rustc.passes.txt + $(RUSTDOC) -C passes=list > $(TMPDIR)/rustdoc.passes.txt + $(DIFF) $(TMPDIR)/rustc.passes.txt $(TMPDIR)/rustdoc.passes.txt diff --git a/tests/run-make/rustdoc-verify-output-files/Makefile b/tests/run-make/rustdoc-verify-output-files/Makefile index 57ac7078d14..76f233ab445 100644 --- a/tests/run-make/rustdoc-verify-output-files/Makefile +++ b/tests/run-make/rustdoc-verify-output-files/Makefile @@ -14,7 +14,7 @@ all: $(RUSTDOC) src/lib.rs --crate-name foobar --crate-type lib --out-dir $(OUTPUT_DIR) # Check if everything exactly same - $(DIFF) -r -q $(OUTPUT_DIR) $(TMP_OUTPUT_DIR) + $(DIFF) -r $(OUTPUT_DIR) $(TMP_OUTPUT_DIR) # Generate json doc on the same output $(RUSTDOC) src/lib.rs --crate-name foobar --crate-type lib --out-dir $(OUTPUT_DIR) -Z unstable-options --output-format json @@ -29,4 +29,4 @@ all: $(RUSTDOC) src/lib.rs --crate-name foobar --crate-type lib --out-dir $(OUTPUT_DIR) -Z unstable-options --output-format json # Check if all docs(including both json and html formats) are still the same after multiple compilations - $(DIFF) -r -q $(OUTPUT_DIR) $(TMP_OUTPUT_DIR) + $(DIFF) -r $(OUTPUT_DIR) $(TMP_OUTPUT_DIR) diff --git a/tests/rustdoc-gui/extend-css.goml b/tests/rustdoc-gui/extend-css.goml new file mode 100644 index 00000000000..fb34469df6c --- /dev/null +++ b/tests/rustdoc-gui/extend-css.goml @@ -0,0 +1,5 @@ +// Test to ensure that the `--extend-css` option is working as expected. +go-to: "file://" + |DOC_PATH| + "/extend_css/index.html" +show-text: true +// The text from the `.extend` element should be red. +assert-css: (".extend", {"color": "rgb(255, 0, 0)"}) diff --git a/tests/rustdoc-gui/search-filter.goml b/tests/rustdoc-gui/search-filter.goml index f114c57ff21..d739471a625 100644 --- a/tests/rustdoc-gui/search-filter.goml +++ b/tests/rustdoc-gui/search-filter.goml @@ -16,6 +16,7 @@ press-key: "ArrowDown" press-key: "ArrowDown" press-key: "ArrowDown" press-key: "ArrowDown" +press-key: "ArrowDown" press-key: "Enter" // Waiting for the search results to appear... wait-for: "#search-tabs" @@ -41,6 +42,7 @@ press-key: "ArrowUp" press-key: "ArrowUp" press-key: "ArrowUp" press-key: "ArrowUp" +press-key: "ArrowUp" press-key: "Enter" // Waiting for the search results to appear... wait-for: "#search-tabs" diff --git a/tests/rustdoc-gui/settings.goml b/tests/rustdoc-gui/settings.goml index cfb037245d1..733be9bebba 100644 --- a/tests/rustdoc-gui/settings.goml +++ b/tests/rustdoc-gui/settings.goml @@ -56,11 +56,12 @@ move-cursor-to: "#settings-menu > a" assert-css: ( "#theme-dark", { - "border-color": "rgb(221, 221, 221)", + "border-color": "rgb(153, 153, 153)", "box-shadow": "rgb(53, 53, 53) 0px 0px 0px 3px inset", + "border-width": "2px", }, ) -assert-css: ("#theme-light", {"border-color": "rgb(221, 221, 221)", "box-shadow": "none"}) +assert-css: ("#theme-light", {"border-color": "rgb(153, 153, 153)", "box-shadow": "none"}) // Let's start with the hover for radio buttons. move-cursor-to: "#theme-dark" assert-css: ( @@ -68,26 +69,36 @@ assert-css: ( { "border-color": "rgb(33, 150, 243)", "box-shadow": "rgb(53, 53, 53) 0px 0px 0px 3px inset", + "border-width": "2px", }, ) move-cursor-to: "#theme-light" -assert-css: ("#theme-light", {"border-color": "rgb(33, 150, 243)", "box-shadow": "none"}) +assert-css: ( + "#theme-light", + { + "border-color": "rgb(33, 150, 243)", + "box-shadow": "none", + "border-width": "2px", + } +) move-cursor-to: "#theme-ayu" // Let's now check with the focus for radio buttons. focus: "#theme-dark" assert-css: ( "#theme-dark", { - "border-color": "rgb(221, 221, 221)", + "border-color": "rgb(153, 153, 153)", "box-shadow": "rgb(53, 53, 53) 0px 0px 0px 3px inset, rgb(33, 150, 243) 0px 0px 2px 2px", + "border-width": "2px", }, ) focus: "#theme-light" assert-css: ( "#theme-light", { - "border-color": "rgb(221, 221, 221)", + "border-color": "rgb(153, 153, 153)", "box-shadow": "rgb(33, 150, 243) 0px 0px 1px 1px", + "border-width": "2px", }, ) // Now we check we both focus and hover for radio buttons. @@ -98,6 +109,7 @@ assert-css: ( { "border-color": "rgb(33, 150, 243)", "box-shadow": "rgb(53, 53, 53) 0px 0px 0px 3px inset, rgb(33, 150, 243) 0px 0px 2px 2px", + "border-width": "2px", }, ) move-cursor-to: "#theme-light" @@ -107,6 +119,7 @@ assert-css: ( { "border-color": "rgb(33, 150, 243)", "box-shadow": "rgb(33, 150, 243) 0px 0px 1px 1px", + "border-width": "2px", }, ) // Now we check the setting-radio-name is on a different line than the label. @@ -142,7 +155,18 @@ assert-css: ( "#auto-hide-large-items", { "background-color": "rgb(33, 150, 243)", - "border-color": "rgb(221, 221, 221)", + "border-color": "rgb(153, 153, 153)", + // 1px border when checked + "border-width": "1px", + }, +) +assert-css: ( + "#auto-hide-method-docs", + { + "background-color": "rgba(0, 0, 0, 0)", + "border-color": "rgb(153, 153, 153)", + // 2px border when unchecked + "border-width": "2px", }, ) // Let's start with the hover for toggles. @@ -152,6 +176,18 @@ assert-css: ( { "background-color": "rgb(33, 150, 243)", "border-color": "rgb(33, 150, 243)", + // 1px border when checked + "border-width": "1px", + }, +) +move-cursor-to: "#auto-hide-method-docs" +assert-css: ( + "#auto-hide-method-docs", + { + "background-color": "rgba(0, 0, 0, 0)", + "border-color": "rgb(33, 150, 243)", + // 2px border when unchecked + "border-width": "2px", }, ) move-cursor-to: "#settings-menu > a" @@ -161,8 +197,21 @@ assert-css: ( "#auto-hide-large-items", { "background-color": "rgb(33, 150, 243)", - "border-color": "rgb(221, 221, 221)", + "border-color": "rgb(153, 153, 153)", + "box-shadow": "rgb(33, 150, 243) 0px 0px 1px 1px", + // 1px border when checked + "border-width": "1px", + }, +) +focus: "#auto-hide-method-docs" +assert-css: ( + "#auto-hide-method-docs", + { + "background-color": "rgba(0, 0, 0, 0)", + "border-color": "rgb(153, 153, 153)", "box-shadow": "rgb(33, 150, 243) 0px 0px 1px 1px", + // 2px border when unchecked + "border-width": "2px", }, ) // Now we check we both focus and hover for toggles. @@ -174,6 +223,20 @@ assert-css: ( "background-color": "rgb(33, 150, 243)", "border-color": "rgb(33, 150, 243)", "box-shadow": "rgb(33, 150, 243) 0px 0px 1px 1px", + // 1px border when checked + "border-width": "1px", + }, +) +move-cursor-to: "#auto-hide-method-docs" +focus: "#auto-hide-method-docs" +assert-css: ( + "#auto-hide-method-docs", + { + "background-color": "rgba(0, 0, 0, 0)", + "border-color": "rgb(33, 150, 243)", + "box-shadow": "rgb(33, 150, 243) 0px 0px 1px 1px", + // 2px border when unchecked + "border-width": "2px", }, ) diff --git a/tests/rustdoc-gui/sidebar-mobile-scroll.goml b/tests/rustdoc-gui/sidebar-mobile-scroll.goml index 84811437eb2..d58d1d48726 100644 --- a/tests/rustdoc-gui/sidebar-mobile-scroll.goml +++ b/tests/rustdoc-gui/sidebar-mobile-scroll.goml @@ -1,31 +1,12 @@ -// This test ensures that the mobile sidebar preserves scroll position. +// This test ensures that the mobile disables scrolling the page. go-to: "file://" + |DOC_PATH| + "/test_docs/struct.Foo.html" -// Switching to "mobile view" by reducing the width to 600px. -set-window-size: (700, 600) -assert-css: (".sidebar", {"display": "block", "left": "-1000px"}) - -// Scroll down. -scroll-to: "//h2[@id='blanket-implementations']" -assert-window-property: {"pageYOffset": "622"} - -// Open the sidebar menu. -click: ".sidebar-menu-toggle" -wait-for-css: (".sidebar", {"left": "0px"}) - -// We are no longer "scrolled". It's important that the user can't -// scroll the body at all, but these test scripts are run only in Chrome, -// and we need to use a more complicated solution to this problem because -// of Mobile Safari... -assert-window-property: {"pageYOffset": "0"} - -// Close the sidebar menu. Make sure the scroll position gets restored. -click: ".sidebar-menu-toggle" -wait-for-css: (".sidebar", {"left": "-1000px"}) -assert-window-property: {"pageYOffset": "622"} - -// Now test that scrollability returns when the browser window is just resized. -click: ".sidebar-menu-toggle" -wait-for-css: (".sidebar", {"left": "0px"}) -assert-window-property: {"pageYOffset": "0"} -set-window-size: (900, 600) -assert-window-property: {"pageYOffset": "622"} +set-window-size: (1280, 800) // desktop +assert-css: (".sidebar", {"overscroll-behavior": "contain"}) +set-window-size: (700, 600) // mobile +assert-css: (".sidebar", {"overscroll-behavior": "contain"}) + +go-to: "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html" +set-window-size: (1280, 800) // desktop +assert-css: (".sidebar", {"overscroll-behavior": "contain"}) +set-window-size: (700, 600) // mobile +assert-css: (".sidebar", {"overscroll-behavior": "contain"}) diff --git a/tests/rustdoc-gui/sidebar-source-code-display.goml b/tests/rustdoc-gui/sidebar-source-code-display.goml index f34e30b724d..20bf0596f95 100644 --- a/tests/rustdoc-gui/sidebar-source-code-display.goml +++ b/tests/rustdoc-gui/sidebar-source-code-display.goml @@ -183,22 +183,12 @@ wait-for-css: (".sidebar", {"left": "-1000px"}) // The "scrollTop" property should be the same. assert-window-property: {"pageYOffset": "2542"} -// We now check that the scroll position is restored if the window is resized. -set-window-size: (500, 700) -click: "#src-sidebar-toggle" -wait-for-css: ("#source-sidebar", {"visibility": "visible"}) -assert-window-property: {"pageYOffset": "0"} -set-window-size: (900, 900) -assert-window-property: {"pageYOffset": "2542"} -set-window-size: (500, 700) -click: "#src-sidebar-toggle" -wait-for-css: ("#source-sidebar", {"visibility": "hidden"}) - // We now check that opening the sidebar and clicking a link will close it. // The behavior here on mobile is different than the behavior on desktop, // but common sense dictates that if you have a list of files that fills the entire screen, and // you click one of them, you probably want to actually see the file's contents, and not just // make it the current selection. +set-window-size: (500, 700) click: "#src-sidebar-toggle" wait-for-css: ("#source-sidebar", {"visibility": "visible"}) assert-local-storage: {"rustdoc-source-sidebar-show": "true"} diff --git a/tests/rustdoc-gui/sidebar-source-code.goml b/tests/rustdoc-gui/sidebar-source-code.goml index 96ea7202433..520b2c59b0f 100644 --- a/tests/rustdoc-gui/sidebar-source-code.goml +++ b/tests/rustdoc-gui/sidebar-source-code.goml @@ -73,7 +73,7 @@ assert: "//*[@class='dir-entry' and @open]/*[text()='sub_mod']" // Only "another_folder" should be "open" in "lib2". assert: "//*[@class='dir-entry' and not(@open)]/*[text()='another_mod']" // All other trees should be collapsed. -assert-count: ("//*[@id='source-sidebar']/details[not(text()='lib2') and not(@open)]", 8) +assert-count: ("//*[@id='source-sidebar']/details[not(text()='lib2') and not(@open)]", 9) // We now switch to mobile mode. set-window-size: (600, 600) diff --git a/tests/rustdoc-gui/source-code-page.goml b/tests/rustdoc-gui/source-code-page.goml index 1ac403308eb..42f3200e967 100644 --- a/tests/rustdoc-gui/source-code-page.goml +++ b/tests/rustdoc-gui/source-code-page.goml @@ -102,7 +102,7 @@ assert: ".source-sidebar-expanded" // We check that the first entry of the sidebar is collapsed assert-property: ("#source-sidebar details:first-of-type", {"open": "false"}) -assert-text: ("#source-sidebar details:first-of-type > summary", "http") +assert-text: ("#source-sidebar details:first-of-type > summary", "extend_css") // We now click on it. click: "#source-sidebar details:first-of-type > summary" assert-property: ("#source-sidebar details:first-of-type", {"open": "true"}) diff --git a/tests/rustdoc-gui/src/extend_css/Cargo.lock b/tests/rustdoc-gui/src/extend_css/Cargo.lock new file mode 100644 index 00000000000..7101a6f0ffb --- /dev/null +++ b/tests/rustdoc-gui/src/extend_css/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "extend_css" +version = "0.1.0" diff --git a/tests/rustdoc-gui/src/extend_css/Cargo.toml b/tests/rustdoc-gui/src/extend_css/Cargo.toml new file mode 100644 index 00000000000..91683fe8964 --- /dev/null +++ b/tests/rustdoc-gui/src/extend_css/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "extend_css" +version = "0.1.0" +edition = "2018" + +[lib] +path = "lib.rs" diff --git a/tests/rustdoc-gui/src/extend_css/extra.css b/tests/rustdoc-gui/src/extend_css/extra.css new file mode 100644 index 00000000000..ee7062d9621 --- /dev/null +++ b/tests/rustdoc-gui/src/extend_css/extra.css @@ -0,0 +1,3 @@ +.extend { + color: red !important; +} diff --git a/tests/rustdoc-gui/src/extend_css/lib.rs b/tests/rustdoc-gui/src/extend_css/lib.rs new file mode 100644 index 00000000000..3a3babf8984 --- /dev/null +++ b/tests/rustdoc-gui/src/extend_css/lib.rs @@ -0,0 +1 @@ +//! <div class="extend">text in red</div> diff --git a/tests/rustdoc-ui/c-help.rs b/tests/rustdoc-ui/c-help.rs deleted file mode 100644 index e166edf8b61..00000000000 --- a/tests/rustdoc-ui/c-help.rs +++ /dev/null @@ -1,6 +0,0 @@ -// check-pass -// compile-flags: -Chelp -// check-stdout -// regex-error-pattern: -C\s+incremental - -pub struct Foo; diff --git a/tests/rustdoc-ui/c-help.stdout b/tests/rustdoc-ui/c-help.stdout deleted file mode 100644 index 0bd2d73efee..00000000000 --- a/tests/rustdoc-ui/c-help.stdout +++ /dev/null @@ -1,51 +0,0 @@ - -C ar=val -- this option is deprecated and does nothing - -C code-model=val -- choose the code model to use (`rustc --print code-models` for details) - -C codegen-units=val -- divide crate into N units to optimize in parallel - -C control-flow-guard=val -- use Windows Control Flow Guard (default: no) - -C debug-assertions=val -- explicitly enable the `cfg(debug_assertions)` directive - -C debuginfo=val -- debug info emission level (0-2, none, line-directives-only, line-tables-only, limited, or full; default: 0) - -C default-linker-libraries=val -- allow the linker to link its default libraries (default: no) - -C embed-bitcode=val -- emit bitcode in rlibs (default: yes) - -C extra-filename=val -- extra data to put in each output filename - -C force-frame-pointers=val -- force use of the frame pointers - -C force-unwind-tables=val -- force use of unwind tables - -C incremental=val -- enable incremental compilation - -C inline-threshold=val -- set the threshold for inlining a function - -C instrument-coverage=val -- instrument the generated code to support LLVM source-based code coverage reports (note, the compiler build config must include `profiler = true`); implies `-C symbol-mangling-version=v0`. Optional values are: - `=all` (implicit value) - `=except-unused-generics` - `=except-unused-functions` - `=off` (default) - -C link-arg=val -- a single extra argument to append to the linker invocation (can be used several times) - -C link-args=val -- extra arguments to append to the linker invocation (space separated) - -C link-dead-code=val -- keep dead code at link time (useful for code coverage) (default: no) - -C link-self-contained=val -- control whether to link Rust provided C objects/libraries or rely - on C toolchain installed in the system - -C linker=val -- system linker to link outputs with - -C linker-flavor=val -- linker flavor - -C linker-plugin-lto=val -- generate build artifacts that are compatible with linker-based LTO - -C llvm-args=val -- a list of arguments to pass to LLVM (space separated) - -C lto=val -- perform LLVM link-time optimizations - -C metadata=val -- metadata to mangle symbol names with - -C no-prepopulate-passes=val -- give an empty list of passes to the pass manager - -C no-redzone=val -- disable the use of the redzone - -C no-stack-check=val -- this option is deprecated and does nothing - -C no-vectorize-loops=val -- disable loop vectorization optimization passes - -C no-vectorize-slp=val -- disable LLVM's SLP vectorization pass - -C opt-level=val -- optimization level (0-3, s, or z; default: 0) - -C overflow-checks=val -- use overflow checks for integer arithmetic - -C panic=val -- panic strategy to compile crate with - -C passes=val -- a list of extra LLVM passes to run (space separated) - -C prefer-dynamic=val -- prefer dynamic linking to static linking (default: no) - -C profile-generate=val -- compile the program with profiling instrumentation - -C profile-use=val -- use the given `.profdata` file for profile-guided optimization - -C relocation-model=val -- control generation of position-independent code (PIC) (`rustc --print relocation-models` for details) - -C remark=val -- print remarks for these optimization passes (space separated, or "all") - -C rpath=val -- set rpath values in libs/exes (default: no) - -C save-temps=val -- save all temporary output files during compilation (default: no) - -C soft-float=val -- use soft float ABI (*eabihf targets only) (default: no) - -C split-debuginfo=val -- how to handle split-debuginfo, a platform-specific option - -C strip=val -- tell the linker which information to strip (`none` (default), `debuginfo` or `symbols`) - -C symbol-mangling-version=val -- which mangling version to use for symbol names ('legacy' (default) or 'v0') - -C target-cpu=val -- select target processor (`rustc --print target-cpus` for details) - -C target-feature=val -- target specific attributes. (`rustc --print target-features` for details). This feature is unsafe. diff --git a/tests/rustdoc-ui/z-help.rs b/tests/rustdoc-ui/z-help.rs deleted file mode 100644 index c7cf841b937..00000000000 --- a/tests/rustdoc-ui/z-help.rs +++ /dev/null @@ -1,6 +0,0 @@ -// check-pass -// compile-flags: -Zhelp -// check-stdout -// regex-error-pattern: -Z\s+self-profile - -pub struct Foo; diff --git a/tests/rustdoc-ui/z-help.stdout b/tests/rustdoc-ui/z-help.stdout deleted file mode 100644 index 72f5f933d8d..00000000000 --- a/tests/rustdoc-ui/z-help.stdout +++ /dev/null @@ -1,220 +0,0 @@ - -Z allow-features=val -- only allow the listed language features to be enabled in code (comma separated) - -Z always-encode-mir=val -- encode MIR of all functions into the crate metadata (default: no) - -Z asm-comments=val -- generate comments into the assembly (may change behavior) (default: no) - -Z assert-incr-state=val -- assert that the incremental cache is in given state: either `loaded` or `not-loaded`. - -Z assume-incomplete-release=val -- make cfg(version) treat the current version as incomplete (default: no) - -Z binary-dep-depinfo=val -- include artifacts (sysroot, crate dependencies) used during compilation in dep-info (default: no) - -Z box-noalias=val -- emit noalias metadata for box (default: yes) - -Z branch-protection=val -- set options for branch target identification and pointer authentication on AArch64 - -Z cf-protection=val -- instrument control-flow architecture protection - -Z cgu-partitioning-strategy=val -- the codegen unit partitioning strategy to use - -Z codegen-backend=val -- the backend to use - -Z combine-cgu=val -- combine CGUs into a single one - -Z crate-attr=val -- inject the given attribute in the crate - -Z debug-info-for-profiling=val -- emit discriminators and other data necessary for AutoFDO - -Z debug-macros=val -- emit line numbers debug info inside macros (default: no) - -Z deduplicate-diagnostics=val -- deduplicate identical diagnostics (default: yes) - -Z dep-info-omit-d-target=val -- in dep-info output, omit targets for tracking dependencies of the dep-info files themselves (default: no) - -Z dep-tasks=val -- print tasks that execute and the color their dep node gets (requires debug build) (default: no) - -Z diagnostic-width=val -- set the current output width for diagnostic truncation - -Z dlltool=val -- import library generation tool (windows-gnu only) - -Z dont-buffer-diagnostics=val -- emit diagnostics rather than buffering (breaks NLL error downgrading, sorting) (default: no) - -Z drop-tracking=val -- enables drop tracking in generators (default: no) - -Z drop-tracking-mir=val -- enables drop tracking on MIR in generators (default: no) - -Z dual-proc-macros=val -- load proc macros for both target and host, but only link to the target (default: no) - -Z dump-dep-graph=val -- dump the dependency graph to $RUST_DEP_GRAPH (default: /tmp/dep_graph.gv) (default: no) - -Z dump-drop-tracking-cfg=val -- dump drop-tracking control-flow graph as a `.dot` file (default: no) - -Z dump-mir=val -- dump MIR state to file. - `val` is used to select which passes and functions to dump. For example: - `all` matches all passes and functions, - `foo` matches all passes for functions whose name contains 'foo', - `foo & ConstProp` only the 'ConstProp' pass for function names containing 'foo', - `foo | bar` all passes for function names containing 'foo' or 'bar'. - -Z dump-mir-dataflow=val -- in addition to `.mir` files, create graphviz `.dot` files with dataflow results (default: no) - -Z dump-mir-dir=val -- the directory the MIR is dumped into (default: `mir_dump`) - -Z dump-mir-exclude-pass-number=val -- exclude the pass number when dumping MIR (used in tests) (default: no) - -Z dump-mir-graphviz=val -- in addition to `.mir` files, create graphviz `.dot` files (and with `-Z instrument-coverage`, also create a `.dot` file for the MIR-derived coverage graph) (default: no) - -Z dump-mir-spanview=val -- in addition to `.mir` files, create `.html` files to view spans for all `statement`s (including terminators), only `terminator` spans, or computed `block` spans (one span encompassing a block's terminator and all statements). If `-Z instrument-coverage` is also enabled, create an additional `.html` file showing the computed coverage spans. - -Z dump-mono-stats=val -- output statistics about monomorphization collection - -Z dump-mono-stats-format=val -- the format to use for -Z dump-mono-stats (`markdown` (default) or `json`) - -Z dwarf-version=val -- version of DWARF debug information to emit (default: 2 or 4, depending on platform) - -Z dylib-lto=val -- enables LTO for dylib crate type - -Z emit-stack-sizes=val -- emit a section containing stack size metadata (default: no) - -Z emit-thin-lto=val -- emit the bc module with thin LTO info (default: yes) - -Z export-executable-symbols=val -- export symbols from executables, as if they were dynamic libraries - -Z extra-const-ub-checks=val -- turns on more checks to detect const UB, which can be slow (default: no) - -Z fewer-names=val -- reduce memory use by retaining fewer names within compilation artifacts (LLVM-IR) (default: no) - -Z flatten-format-args=val -- flatten nested format_args!() and literals into a simplified format_args!() call (default: no) - -Z force-unstable-if-unmarked=val -- force all crates to be `rustc_private` unstable (default: no) - -Z fuel=val -- set the optimization fuel quota for a crate - -Z function-sections=val -- whether each function should go in its own section - -Z future-incompat-test=val -- forces all lints to be future incompatible, used for internal testing (default: no) - -Z gcc-ld=val -- implementation of ld used by cc - -Z graphviz-dark-mode=val -- use dark-themed colors in graphviz output (default: no) - -Z graphviz-font=val -- use the given `fontname` in graphviz output; can be overridden by setting environment variable `RUSTC_GRAPHVIZ_FONT` (default: `Courier, monospace`) - -Z hir-stats=val -- print some statistics about AST and HIR (default: no) - -Z human-readable-cgu-names=val -- generate human-readable, predictable names for codegen units (default: no) - -Z identify-regions=val -- display unnamed regions as `'<id>`, using a non-ident unique id (default: no) - -Z incremental-ignore-spans=val -- ignore spans during ICH computation -- used for testing (default: no) - -Z incremental-info=val -- print high-level information about incremental reuse (or the lack thereof) (default: no) - -Z incremental-relative-spans=val -- hash spans relative to their parent item for incr. comp. (default: no) - -Z incremental-verify-ich=val -- verify incr. comp. hashes of green query instances (default: no) - -Z inline-in-all-cgus=val -- control whether `#[inline]` functions are in all CGUs - -Z inline-llvm=val -- enable LLVM inlining (default: yes) - -Z inline-mir=val -- enable MIR inlining (default: no) - -Z inline-mir-hint-threshold=val -- inlining threshold for functions with inline hint (default: 100) - -Z inline-mir-threshold=val -- a default MIR inlining threshold (default: 50) - -Z input-stats=val -- gather statistics about the input (default: no) - -Z instrument-coverage=val -- instrument the generated code to support LLVM source-based code coverage reports (note, the compiler build config must include `profiler = true`); implies `-C symbol-mangling-version=v0`. Optional values are: - `=all` (implicit value) - `=except-unused-generics` - `=except-unused-functions` - `=off` (default) - -Z instrument-mcount=val -- insert function instrument code for mcount-based tracing (default: no) - -Z instrument-xray=val -- insert function instrument code for XRay-based tracing (default: no) - Optional extra settings: - `=always` - `=never` - `=ignore-loops` - `=instruction-threshold=N` - `=skip-entry` - `=skip-exit` - Multiple options can be combined with commas. - -Z keep-hygiene-data=val -- keep hygiene data after analysis (default: no) - -Z layout-seed=val -- seed layout randomization - -Z link-directives=val -- honor #[link] directives in the compiled crate (default: yes) - -Z link-native-libraries=val -- link native libraries in the linker invocation (default: yes) - -Z link-only=val -- link the `.rlink` file generated by `-Z no-link` (default: no) - -Z llvm-plugins=val -- a list LLVM plugins to enable (space separated) - -Z llvm-time-trace=val -- generate JSON tracing data file from LLVM data (default: no) - -Z location-detail=val -- what location details should be tracked when using caller_location, either `none`, or a comma separated list of location details, for which valid options are `file`, `line`, and `column` (default: `file,line,column`) - -Z lower-impl-trait-in-trait-to-assoc-ty=val -- modify the lowering strategy for `impl Trait` in traits so that they are lowered to generic associated types - -Z ls=val -- list the symbols defined by a library crate (default: no) - -Z macro-backtrace=val -- show macro backtraces (default: no) - -Z maximal-hir-to-mir-coverage=val -- save as much information as possible about the correspondence between MIR and HIR as source scopes (default: no) - -Z merge-functions=val -- control the operation of the MergeFunctions LLVM pass, taking the same values as the target option of the same name - -Z meta-stats=val -- gather metadata statistics (default: no) - -Z mir-emit-retag=val -- emit Retagging MIR statements, interpreted e.g., by miri; implies -Zmir-opt-level=0 (default: no) - -Z mir-enable-passes=val -- use like `-Zmir-enable-passes=+DestProp,-InstCombine`. Forces the specified passes to be enabled, overriding all other checks. Passes that are not specified are enabled or disabled by other flags as usual. - -Z mir-opt-level=val -- MIR optimization level (0-4; default: 1 in non optimized builds and 2 in optimized builds) - -Z mir-pretty-relative-line-numbers=val -- use line numbers relative to the function in mir pretty printing - -Z move-size-limit=val -- the size at which the `large_assignments` lint starts to be emitted - -Z mutable-noalias=val -- emit noalias metadata for mutable references (default: yes) - -Z nll-facts=val -- dump facts from NLL analysis into side files (default: no) - -Z nll-facts-dir=val -- the directory the NLL facts are dumped into (default: `nll-facts`) - -Z no-analysis=val -- parse and expand the source, but run no analysis - -Z no-codegen=val -- run all passes except codegen; no output - -Z no-generate-arange-section=val -- omit DWARF address ranges that give faster lookups - -Z no-jump-tables=val -- disable the jump tables and lookup tables that can be generated from a switch case lowering - -Z no-leak-check=val -- disable the 'leak check' for subtyping; unsound, but useful for tests - -Z no-link=val -- compile without linking - -Z no-parallel-llvm=val -- run LLVM in non-parallel mode (while keeping codegen-units and ThinLTO) - -Z no-profiler-runtime=val -- prevent automatic injection of the profiler_builtins crate - -Z no-unique-section-names=val -- do not use unique names for text and data sections when -Z function-sections is used - -Z normalize-docs=val -- normalize associated items in rustdoc when generating documentation - -Z oom=val -- panic strategy for out-of-memory handling - -Z osx-rpath-install-name=val -- pass `-install_name @rpath/...` to the macOS linker (default: no) - -Z packed-bundled-libs=val -- change rlib format to store native libraries as archives - -Z panic-abort-tests=val -- support compiling tests with panic=abort (default: no) - -Z panic-in-drop=val -- panic strategy for panics in drops - -Z parse-only=val -- parse only; do not compile, assemble, or link (default: no) - -Z perf-stats=val -- print some performance-related statistics (default: no) - -Z plt=val -- whether to use the PLT when calling into shared libraries; - only has effect for PIC code on systems with ELF binaries - (default: PLT is disabled if full relro is enabled) - -Z polonius=val -- enable polonius-based borrow-checker (default: no) - -Z polymorphize=val -- perform polymorphization analysis - -Z pre-link-arg=val -- a single extra argument to prepend the linker invocation (can be used several times) - -Z pre-link-args=val -- extra arguments to prepend to the linker invocation (space separated) - -Z precise-enum-drop-elaboration=val -- use a more precise version of drop elaboration for matches on enums (default: yes). This results in better codegen, but has caused miscompilations on some tier 2 platforms. See #77382 and #74551. - -Z print-fuel=val -- make rustc print the total optimization fuel used by a crate - -Z print-llvm-passes=val -- print the LLVM optimization passes being run (default: no) - -Z print-mono-items=val -- print the result of the monomorphization collection pass - -Z print-type-sizes=val -- print layout information for each type encountered (default: no) - -Z proc-macro-backtrace=val -- show backtraces for panics during proc-macro execution (default: no) - -Z proc-macro-execution-strategy=val -- how to run proc-macro code (default: same-thread) - -Z profile=val -- insert profiling code (default: no) - -Z profile-closures=val -- profile size of closures - -Z profile-emit=val -- file path to emit profiling data at runtime when using 'profile' (default based on relative source path) - -Z profile-sample-use=val -- use the given `.prof` file for sampled profile-guided optimization (also known as AutoFDO) - -Z profiler-runtime=val -- name of the profiler runtime crate to automatically inject (default: `profiler_builtins`) - -Z query-dep-graph=val -- enable queries of the dependency graph for regression testing (default: no) - -Z randomize-layout=val -- randomize the layout of types (default: no) - -Z relax-elf-relocations=val -- whether ELF relocations can be relaxed - -Z relro-level=val -- choose which RELRO level to use - -Z remap-cwd-prefix=val -- remap paths under the current working directory to this path prefix - -Z report-delayed-bugs=val -- immediately print bugs registered with `delay_span_bug` (default: no) - -Z sanitizer=val -- use a sanitizer - -Z sanitizer-memory-track-origins=val -- enable origins tracking in MemorySanitizer - -Z sanitizer-recover=val -- enable recovery for selected sanitizers - -Z saturating-float-casts=val -- make float->int casts UB-free: numbers outside the integer type's range are clipped to the max/min integer respectively, and NaN is mapped to 0 (default: yes) - -Z self-profile=val -- run the self profiler and output the raw event data - -Z self-profile-counter=val -- counter used by the self profiler (default: `wall-time`), one of: - `wall-time` (monotonic clock, i.e. `std::time::Instant`) - `instructions:u` (retired instructions, userspace-only) - `instructions-minus-irqs:u` (subtracting hardware interrupt counts for extra accuracy) - -Z self-profile-events=val -- specify the events recorded by the self profiler; - for example: `-Z self-profile-events=default,query-keys` - all options: none, all, default, generic-activity, query-provider, query-cache-hit - query-blocked, incr-cache-load, incr-result-hashing, query-keys, function-args, args, llvm, artifact-sizes - -Z share-generics=val -- make the current crate share its generic instantiations - -Z show-span=val -- show spans for compiler debugging (expr|pat|ty) - -Z simulate-remapped-rust-src-base=val -- simulate the effect of remap-debuginfo = true at bootstrapping by remapping path to rust's source base directory. only meant for testing purposes - -Z span-debug=val -- forward proc_macro::Span's `Debug` impl to `Span` - -Z span-free-formats=val -- exclude spans when debug-printing compiler state (default: no) - -Z split-dwarf-inlining=val -- provide minimal debug info in the object/executable to facilitate online symbolication/stack traces in the absence of .dwo/.dwp files when using Split DWARF - -Z split-dwarf-kind=val -- split dwarf variant (only if -Csplit-debuginfo is enabled and on relevant platform) - (default: `split`) - - `split`: sections which do not require relocation are written into a DWARF object (`.dwo`) - file which is ignored by the linker - `single`: sections which do not require relocation are written into object file but ignored - by the linker - -Z src-hash-algorithm=val -- hash algorithm of source files in debug info (`md5`, `sha1`, or `sha256`) - -Z stack-protector=val -- control stack smash protection strategy (`rustc --print stack-protector-strategies` for details) - -Z strict-init-checks=val -- control if mem::uninitialized and mem::zeroed panic on more UB - -Z strip=val -- tell the linker which information to strip (`none` (default), `debuginfo` or `symbols`) - -Z symbol-mangling-version=val -- which mangling version to use for symbol names ('legacy' (default) or 'v0') - -Z teach=val -- show extended diagnostic help (default: no) - -Z temps-dir=val -- the directory the intermediate files are written to - -Z terminal-urls=val -- use the OSC 8 hyperlink terminal specification to print hyperlinks in the compiler output - -Z thinlto=val -- enable ThinLTO when possible - -Z thir-unsafeck=val -- use the THIR unsafety checker (default: no) - -Z threads=val -- use a thread pool with N threads - -Z time-llvm-passes=val -- measure time of each LLVM pass (default: no) - -Z time-passes=val -- measure time of each rustc pass (default: no) - -Z time-passes-format=val -- the format to use for -Z time-passes (`text` (default) or `json`) - -Z tiny-const-eval-limit=val -- sets a tiny, non-configurable limit for const eval; useful for compiler tests - -Z tls-model=val -- choose the TLS model to use (`rustc --print tls-models` for details) - -Z trace-macros=val -- for every macro invocation, print its name and arguments (default: no) - -Z track-diagnostics=val -- tracks where in rustc a diagnostic was emitted - -Z trait-solver=val -- specify the trait solver mode used by rustc (default: classic) - -Z translate-additional-ftl=val -- additional fluent translation to preferentially use (for testing translation) - -Z translate-directionality-markers=val -- emit directionality isolation markers in translated diagnostics - -Z translate-lang=val -- language identifier for diagnostic output - -Z translate-remapped-path-to-local-path=val -- translate remapped paths into local paths when possible (default: yes) - -Z trap-unreachable=val -- generate trap instructions for unreachable intrinsics (default: use target setting, usually yes) - -Z treat-err-as-bug=val -- treat error number `val` that occurs as bug - -Z trim-diagnostic-paths=val -- in diagnostics, use heuristics to shorten paths referring to items - -Z tune-cpu=val -- select processor to schedule for (`rustc --print target-cpus` for details) - -Z ui-testing=val -- emit compiler diagnostics in a form suitable for UI testing (default: no) - -Z uninit-const-chunk-threshold=val -- allow generating const initializers with mixed init/uninit chunks, and set the maximum number of chunks for which this is allowed (default: 16) - -Z unleash-the-miri-inside-of-you=val -- take the brakes off const evaluation. NOTE: this is unsound (default: no) - -Z unpretty=val -- present the input source, unstable (and less-pretty) variants; - `normal`, `identified`, - `expanded`, `expanded,identified`, - `expanded,hygiene` (with internal representations), - `ast-tree` (raw AST before expansion), - `ast-tree,expanded` (raw AST after expansion), - `hir` (the HIR), `hir,identified`, - `hir,typed` (HIR with types for each node), - `hir-tree` (dump the raw HIR), - `mir` (the MIR), or `mir-cfg` (graphviz formatted MIR) - -Z unsound-mir-opts=val -- enable unsound and buggy MIR optimizations (default: no) - -Z unstable-options=val -- adds unstable command line options to rustc interface (default: no) - -Z use-ctors-section=val -- use legacy .ctors section for initializers rather than .init_array - -Z validate-mir=val -- validate MIR after each transformation - -Z verbose=val -- in general, enable more debug printouts (default: no) - -Z verify-llvm-ir=val -- verify LLVM IR (default: no) - -Z virtual-function-elimination=val -- enables dead virtual function elimination optimization. Requires `-Clto[=[fat,yes]]` - -Z wasi-exec-model=val -- whether to build a wasi command or reactor diff --git a/tests/rustdoc/auxiliary/issue-73061.rs b/tests/rustdoc/auxiliary/issue-73061.rs index e05a3bc6d91..01e9a984d44 100644 --- a/tests/rustdoc/auxiliary/issue-73061.rs +++ b/tests/rustdoc/auxiliary/issue-73061.rs @@ -1,6 +1,6 @@ //edition:2018 -#![feature(type_alias_impl_trait)] +#![feature(impl_trait_in_assoc_type)] pub trait Foo { type X: std::future::Future<Output = ()>; diff --git a/tests/ui/array-slice-vec/repeat_empty_ok.stderr b/tests/ui/array-slice-vec/repeat_empty_ok.stderr index 724bdcd920a..e8bac04ac45 100644 --- a/tests/ui/array-slice-vec/repeat_empty_ok.stderr +++ b/tests/ui/array-slice-vec/repeat_empty_ok.stderr @@ -7,7 +7,8 @@ LL | let headers = [Header{value: &[]}; 128]; = note: the `Copy` trait is required because this value will be copied for each element of the array help: consider annotating `Header<'_>` with `#[derive(Copy)]` | -LL | #[derive(Copy)] +LL + #[derive(Copy)] +LL | pub struct Header<'a> { | error[E0277]: the trait bound `Header<'_>: Copy` is not satisfied @@ -19,7 +20,8 @@ LL | let headers = [Header{value: &[0]}; 128]; = note: the `Copy` trait is required because this value will be copied for each element of the array help: consider annotating `Header<'_>` with `#[derive(Copy)]` | -LL | #[derive(Copy)] +LL + #[derive(Copy)] +LL | pub struct Header<'a> { | error: aborting due to 2 previous errors diff --git a/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.rs b/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.rs index 2f9a1d1c76e..79cee55177b 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.rs +++ b/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.rs @@ -12,11 +12,11 @@ fn foo<T: Trait<method(i32): Send>>() {} //~^ ERROR argument types not allowed with return type notation //~| ERROR associated type bounds are unstable -fn bar<T: Trait<method(..) -> (): Send>>() {} +fn bar<T: Trait<method() -> (): Send>>() {} //~^ ERROR return type not allowed with return type notation - -fn baz<T: Trait<method(): Send>>() {} -//~^ ERROR return type notation arguments must be elided with `..` //~| ERROR associated type bounds are unstable +fn baz<T: Trait<method(..): Send>>() {} +//~^ ERROR return type notation uses `()` instead of `(..)` for elided arguments + fn main() {} diff --git a/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.stderr b/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.stderr index b354a6805d6..b23e0f791ea 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.stderr +++ b/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.stderr @@ -1,8 +1,8 @@ -error: return type not allowed with return type notation - --> $DIR/bad-inputs-and-output.rs:15:28 +error: return type notation uses `()` instead of `(..)` for elided arguments + --> $DIR/bad-inputs-and-output.rs:19:24 | -LL | fn bar<T: Trait<method(..) -> (): Send>>() {} - | ^^^^^ help: remove the return type +LL | fn baz<T: Trait<method(..): Send>>() {} + | ^^ help: remove the `..` error[E0658]: associated type bounds are unstable --> $DIR/bad-inputs-and-output.rs:11:17 @@ -14,10 +14,10 @@ LL | fn foo<T: Trait<method(i32): Send>>() {} = help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable error[E0658]: associated type bounds are unstable - --> $DIR/bad-inputs-and-output.rs:18:17 + --> $DIR/bad-inputs-and-output.rs:15:17 | -LL | fn baz<T: Trait<method(): Send>>() {} - | ^^^^^^^^^^^^^^ +LL | fn bar<T: Trait<method() -> (): Send>>() {} + | ^^^^^^^^^^^^^^^^^^^^ | = note: see issue #52662 <https://github.com/rust-lang/rust/issues/52662> for more information = help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable @@ -43,13 +43,13 @@ error: argument types not allowed with return type notation --> $DIR/bad-inputs-and-output.rs:11:23 | LL | fn foo<T: Trait<method(i32): Send>>() {} - | ^^^^^ help: remove the input types: `(..)` + | ^^^^^ help: remove the input types: `()` -error: return type notation arguments must be elided with `..` - --> $DIR/bad-inputs-and-output.rs:18:23 +error: return type not allowed with return type notation + --> $DIR/bad-inputs-and-output.rs:15:25 | -LL | fn baz<T: Trait<method(): Send>>() {} - | ^^ help: add `..`: `(..)` +LL | fn bar<T: Trait<method() -> (): Send>>() {} + | ^^^^^^ help: remove the return type error: aborting due to 5 previous errors; 2 warnings emitted diff --git a/tests/ui/associated-type-bounds/return-type-notation/basic.rs b/tests/ui/associated-type-bounds/return-type-notation/basic.rs index 75d1dc745d1..0b7530b65d7 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/basic.rs +++ b/tests/ui/associated-type-bounds/return-type-notation/basic.rs @@ -18,7 +18,7 @@ async fn foo<T: Foo>() -> Result<(), ()> { fn is_send(_: impl Send) {} fn test< - #[cfg(with)] T: Foo<method(..): Send>, + #[cfg(with)] T: Foo<method(): Send>, #[cfg(without)] T: Foo, >() { is_send(foo::<T>()); diff --git a/tests/ui/associated-type-bounds/return-type-notation/equality.rs b/tests/ui/associated-type-bounds/return-type-notation/equality.rs index c8fc980974e..75f757e9025 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/equality.rs +++ b/tests/ui/associated-type-bounds/return-type-notation/equality.rs @@ -10,7 +10,7 @@ trait Trait { async fn method() {} } -fn test<T: Trait<method(..) = Box<dyn Future<Output = ()>>>>() {} +fn test<T: Trait<method() = Box<dyn Future<Output = ()>>>>() {} //~^ ERROR return type notation is not allowed to use type equality fn main() {} diff --git a/tests/ui/associated-type-bounds/return-type-notation/equality.stderr b/tests/ui/associated-type-bounds/return-type-notation/equality.stderr index cd50ff38694..c5b2e5710d4 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/equality.stderr +++ b/tests/ui/associated-type-bounds/return-type-notation/equality.stderr @@ -18,8 +18,8 @@ LL | #![feature(return_type_notation, async_fn_in_trait)] error: return type notation is not allowed to use type equality --> $DIR/equality.rs:13:18 | -LL | fn test<T: Trait<method(..) = Box<dyn Future<Output = ()>>>>() {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | fn test<T: Trait<method() = Box<dyn Future<Output = ()>>>>() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error; 2 warnings emitted diff --git a/tests/ui/associated-type-bounds/return-type-notation/missing.rs b/tests/ui/associated-type-bounds/return-type-notation/missing.rs index 1263cae4477..7b98a5cdafd 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/missing.rs +++ b/tests/ui/associated-type-bounds/return-type-notation/missing.rs @@ -8,7 +8,7 @@ trait Trait { async fn method() {} } -fn bar<T: Trait<methid(..): Send>>() {} +fn bar<T: Trait<methid(): Send>>() {} //~^ ERROR cannot find associated function `methid` in trait `Trait` fn main() {} diff --git a/tests/ui/associated-type-bounds/return-type-notation/missing.stderr b/tests/ui/associated-type-bounds/return-type-notation/missing.stderr index 93111b5c36b..34f5bda884d 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/missing.stderr +++ b/tests/ui/associated-type-bounds/return-type-notation/missing.stderr @@ -18,8 +18,8 @@ LL | #![feature(return_type_notation, async_fn_in_trait)] error: cannot find associated function `methid` in trait `Trait` --> $DIR/missing.rs:11:17 | -LL | fn bar<T: Trait<methid(..): Send>>() {} - | ^^^^^^^^^^^^^^^^ +LL | fn bar<T: Trait<methid(): Send>>() {} + | ^^^^^^^^^^^^^^ error: aborting due to previous error; 2 warnings emitted diff --git a/tests/ui/associated-type-bounds/return-type-notation/non-rpitit.rs b/tests/ui/associated-type-bounds/return-type-notation/non-rpitit.rs index d283c6eab37..db5f6fe389e 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/non-rpitit.rs +++ b/tests/ui/associated-type-bounds/return-type-notation/non-rpitit.rs @@ -5,7 +5,7 @@ trait Trait { fn method() {} } -fn test<T: Trait<method(..): Send>>() {} +fn test<T: Trait<method(): Send>>() {} //~^ ERROR return type notation used on function that is not `async` and does not return `impl Trait` fn main() {} diff --git a/tests/ui/associated-type-bounds/return-type-notation/non-rpitit.stderr b/tests/ui/associated-type-bounds/return-type-notation/non-rpitit.stderr index 38c498bc2fb..31b793995f8 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/non-rpitit.stderr +++ b/tests/ui/associated-type-bounds/return-type-notation/non-rpitit.stderr @@ -13,8 +13,8 @@ error: return type notation used on function that is not `async` and does not re LL | fn method() {} | ----------- this function must be `async` or return `impl Trait` ... -LL | fn test<T: Trait<method(..): Send>>() {} - | ^^^^^^^^^^^^^^^^ +LL | fn test<T: Trait<method(): Send>>() {} + | ^^^^^^^^^^^^^^ | = note: function returns `()`, which is not compatible with associated type return bounds diff --git a/tests/ui/associated-types/defaults-suitability.stderr b/tests/ui/associated-types/defaults-suitability.stderr index 2485758757b..4b2094691f8 100644 --- a/tests/ui/associated-types/defaults-suitability.stderr +++ b/tests/ui/associated-types/defaults-suitability.stderr @@ -11,7 +11,8 @@ LL | type Ty: Clone = NotClone; | ^^^^^ required by this bound in `Tr::Ty` help: consider annotating `NotClone` with `#[derive(Clone)]` | -LL | #[derive(Clone)] +LL + #[derive(Clone)] +LL | struct NotClone; | error[E0277]: the trait bound `NotClone: Clone` is not satisfied @@ -30,7 +31,8 @@ LL | type Ty = NotClone; | -- required by a bound in this associated type help: consider annotating `NotClone` with `#[derive(Clone)]` | -LL | #[derive(Clone)] +LL + #[derive(Clone)] +LL | struct NotClone; | error[E0277]: the trait bound `T: Clone` is not satisfied diff --git a/tests/ui/associated-types/issue-63591.rs b/tests/ui/associated-types/issue-63591.rs index 4d2e39f4da6..d07c1234998 100644 --- a/tests/ui/associated-types/issue-63591.rs +++ b/tests/ui/associated-types/issue-63591.rs @@ -1,11 +1,13 @@ // check-pass #![feature(associated_type_bounds)] -#![feature(type_alias_impl_trait)] +#![feature(impl_trait_in_assoc_type)] fn main() {} -trait Bar { type Assoc; } +trait Bar { + type Assoc; +} trait Thing { type Out; @@ -13,7 +15,9 @@ trait Thing { } struct AssocIsCopy; -impl Bar for AssocIsCopy { type Assoc = u8; } +impl Bar for AssocIsCopy { + type Assoc = u8; +} impl Thing for AssocIsCopy { type Out = impl Bar<Assoc: Copy>; diff --git a/tests/ui/async-await/in-trait/async-associated-types2.rs b/tests/ui/async-await/in-trait/async-associated-types2.rs index cdecb02bfad..b889f616a03 100644 --- a/tests/ui/async-await/in-trait/async-associated-types2.rs +++ b/tests/ui/async-await/in-trait/async-associated-types2.rs @@ -4,7 +4,7 @@ // revisions: current next #![feature(async_fn_in_trait)] -#![feature(type_alias_impl_trait)] +#![feature(impl_trait_in_assoc_type)] #![allow(incomplete_features)] use std::future::Future; @@ -23,9 +23,7 @@ impl MyTrait for i32 { Self: 'a; fn foo<'a>(&'a self) -> Self::Fut<'a> { - async { - *self - } + async { *self } } } diff --git a/tests/ui/async-await/task-context-arg.rs b/tests/ui/async-await/task-context-arg.rs new file mode 100644 index 00000000000..937723ca743 --- /dev/null +++ b/tests/ui/async-await/task-context-arg.rs @@ -0,0 +1,25 @@ +// Checks that we don't get conflicting arguments in our debug info with a particular async function +// structure. + +// edition:2021 +// compile-flags: -Cdebuginfo=2 +// build-pass + +#![crate_type = "lib"] + +use std::future::Future; + +// The compiler produces a closure as part of this function. That closure initially takes an +// argument _task_context. Later, when the MIR for that closure is transformed into a generator +// state machine, _task_context is demoted to not be an argument, but just part of an unnamed +// argument. If we emit debug info saying that both _task_context and the unnamed argument are both +// argument number 2, then LLVM will fail with "conflicting debug info for argument". See +// https://github.com/rust-lang/rust/pull/109466#issuecomment-1500879195 for details. +async fn recv_unit() { + std::future::ready(()).await; +} + +pub fn poll_recv() { + // This box is necessary in order to reproduce the problem. + let _: Box<dyn Future<Output = ()>> = Box::new(recv_unit()); +} diff --git a/tests/ui/binop/issue-28837.stderr b/tests/ui/binop/issue-28837.stderr index cca1da3b6ac..bb9f3b8af0f 100644 --- a/tests/ui/binop/issue-28837.stderr +++ b/tests/ui/binop/issue-28837.stderr @@ -157,7 +157,8 @@ LL | struct A; | ^^^^^^^^ must implement `PartialEq<_>` help: consider annotating `A` with `#[derive(PartialEq)]` | -LL | #[derive(PartialEq)] +LL + #[derive(PartialEq)] +LL | struct A; | error[E0369]: binary operation `!=` cannot be applied to type `A` @@ -175,7 +176,8 @@ LL | struct A; | ^^^^^^^^ must implement `PartialEq<_>` help: consider annotating `A` with `#[derive(PartialEq)]` | -LL | #[derive(PartialEq)] +LL + #[derive(PartialEq)] +LL | struct A; | error[E0369]: binary operation `<` cannot be applied to type `A` @@ -193,7 +195,8 @@ LL | struct A; | ^^^^^^^^ must implement `PartialOrd<_>` help: consider annotating `A` with `#[derive(PartialEq, PartialOrd)]` | -LL | #[derive(PartialEq, PartialOrd)] +LL + #[derive(PartialEq, PartialOrd)] +LL | struct A; | error[E0369]: binary operation `<=` cannot be applied to type `A` @@ -211,7 +214,8 @@ LL | struct A; | ^^^^^^^^ must implement `PartialOrd<_>` help: consider annotating `A` with `#[derive(PartialEq, PartialOrd)]` | -LL | #[derive(PartialEq, PartialOrd)] +LL + #[derive(PartialEq, PartialOrd)] +LL | struct A; | error[E0369]: binary operation `>` cannot be applied to type `A` @@ -229,7 +233,8 @@ LL | struct A; | ^^^^^^^^ must implement `PartialOrd<_>` help: consider annotating `A` with `#[derive(PartialEq, PartialOrd)]` | -LL | #[derive(PartialEq, PartialOrd)] +LL + #[derive(PartialEq, PartialOrd)] +LL | struct A; | error[E0369]: binary operation `>=` cannot be applied to type `A` @@ -247,7 +252,8 @@ LL | struct A; | ^^^^^^^^ must implement `PartialOrd<_>` help: consider annotating `A` with `#[derive(PartialEq, PartialOrd)]` | -LL | #[derive(PartialEq, PartialOrd)] +LL + #[derive(PartialEq, PartialOrd)] +LL | struct A; | error: aborting due to 15 previous errors diff --git a/tests/ui/box/unit/unique-pinned-nocopy.stderr b/tests/ui/box/unit/unique-pinned-nocopy.stderr index de6611324ca..2fd5b0d82e8 100644 --- a/tests/ui/box/unit/unique-pinned-nocopy.stderr +++ b/tests/ui/box/unit/unique-pinned-nocopy.stderr @@ -19,7 +19,8 @@ LL | let _j = i.clone(); candidate #1: `Clone` help: consider annotating `R` with `#[derive(Clone)]` | -LL | #[derive(Clone)] +LL + #[derive(Clone)] +LL | struct R { | error: aborting due to previous error diff --git a/tests/ui/coherence/coherence_inherent.stderr b/tests/ui/coherence/coherence_inherent.stderr index 46b128c08fe..b381b068073 100644 --- a/tests/ui/coherence/coherence_inherent.stderr +++ b/tests/ui/coherence/coherence_inherent.stderr @@ -7,7 +7,7 @@ LL | s.the_fn(); = help: items from traits can only be used if the trait is in scope help: the following trait is implemented but not in scope; perhaps add a `use` for it: | -LL | use Lib::TheTrait; +LL + use Lib::TheTrait; | error: aborting due to previous error diff --git a/tests/ui/coherence/coherence_inherent_cc.stderr b/tests/ui/coherence/coherence_inherent_cc.stderr index af0ef3b6932..7b6cb7d4390 100644 --- a/tests/ui/coherence/coherence_inherent_cc.stderr +++ b/tests/ui/coherence/coherence_inherent_cc.stderr @@ -7,7 +7,7 @@ LL | s.the_fn(); = help: items from traits can only be used if the trait is in scope help: the following trait is implemented but not in scope; perhaps add a `use` for it: | -LL | use coherence_inherent_cc_lib::TheTrait; +LL + use coherence_inherent_cc_lib::TheTrait; | error: aborting due to previous error diff --git a/tests/ui/const-generics/generic_const_exprs/issue-94287.stderr b/tests/ui/const-generics/generic_const_exprs/issue-94287.stderr index 7390a007742..dc7d0c54fcc 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-94287.stderr +++ b/tests/ui/const-generics/generic_const_exprs/issue-94287.stderr @@ -8,7 +8,7 @@ LL | If<{ FRAC <= 32 }>: True, help: consider enabling this feature --> $DIR/issue-94287.rs:1:1 | -LL | #![feature(generic_const_exprs)] +LL + #![feature(generic_const_exprs)] | error: aborting due to previous error diff --git a/tests/ui/const-generics/issues/issue-82956.stderr b/tests/ui/const-generics/issues/issue-82956.stderr index d2320293e85..d70c8d0bfbf 100644 --- a/tests/ui/const-generics/issues/issue-82956.stderr +++ b/tests/ui/const-generics/issues/issue-82956.stderr @@ -6,13 +6,13 @@ LL | let mut iter = IntoIter::new(self); | help: consider importing one of these items | -LL | use std::array::IntoIter; +LL + use std::array::IntoIter; | -LL | use std::collections::binary_heap::IntoIter; +LL + use std::collections::binary_heap::IntoIter; | -LL | use std::collections::btree_map::IntoIter; +LL + use std::collections::btree_map::IntoIter; | -LL | use std::collections::btree_set::IntoIter; +LL + use std::collections::btree_set::IntoIter; | and 8 other candidates diff --git a/tests/ui/consts/const-blocks/fn-call-in-non-const.stderr b/tests/ui/consts/const-blocks/fn-call-in-non-const.stderr index ee352700c30..174103eeba4 100644 --- a/tests/ui/consts/const-blocks/fn-call-in-non-const.stderr +++ b/tests/ui/consts/const-blocks/fn-call-in-non-const.stderr @@ -10,7 +10,8 @@ LL | let _: [Option<Bar>; 2] = [no_copy(); 2]; = help: create an inline `const` block, see RFC #2920 <https://github.com/rust-lang/rfcs/pull/2920> for more information help: consider annotating `Bar` with `#[derive(Copy)]` | -LL | #[derive(Copy)] +LL + #[derive(Copy)] +LL | struct Bar; | error: aborting due to previous error diff --git a/tests/ui/consts/const-blocks/migrate-fail.stderr b/tests/ui/consts/const-blocks/migrate-fail.stderr index 928ffd0839d..d1896f755d5 100644 --- a/tests/ui/consts/const-blocks/migrate-fail.stderr +++ b/tests/ui/consts/const-blocks/migrate-fail.stderr @@ -8,7 +8,8 @@ LL | let arr: [Option<Bar>; 2] = [x; 2]; = note: the `Copy` trait is required because this value will be copied for each element of the array help: consider annotating `Bar` with `#[derive(Copy)]` | -LL | #[derive(Copy)] +LL + #[derive(Copy)] +LL | struct Bar; | error[E0277]: the trait bound `Bar: Copy` is not satisfied @@ -21,7 +22,8 @@ LL | let arr: [Option<Bar>; 2] = [x; 2]; = note: the `Copy` trait is required because this value will be copied for each element of the array help: consider annotating `Bar` with `#[derive(Copy)]` | -LL | #[derive(Copy)] +LL + #[derive(Copy)] +LL | struct Bar; | error: aborting due to 2 previous errors diff --git a/tests/ui/consts/const-blocks/nll-fail.stderr b/tests/ui/consts/const-blocks/nll-fail.stderr index fede0084547..807c964a51d 100644 --- a/tests/ui/consts/const-blocks/nll-fail.stderr +++ b/tests/ui/consts/const-blocks/nll-fail.stderr @@ -8,7 +8,8 @@ LL | let arr: [Option<Bar>; 2] = [x; 2]; = note: the `Copy` trait is required because this value will be copied for each element of the array help: consider annotating `Bar` with `#[derive(Copy)]` | -LL | #[derive(Copy)] +LL + #[derive(Copy)] +LL | struct Bar; | error[E0277]: the trait bound `Bar: Copy` is not satisfied @@ -21,7 +22,8 @@ LL | let arr: [Option<Bar>; 2] = [x; 2]; = note: the `Copy` trait is required because this value will be copied for each element of the array help: consider annotating `Bar` with `#[derive(Copy)]` | -LL | #[derive(Copy)] +LL + #[derive(Copy)] +LL | struct Bar; | error: aborting due to 2 previous errors diff --git a/tests/ui/consts/min_const_fn/min_const_fn_libstd_stability.stderr b/tests/ui/consts/min_const_fn/min_const_fn_libstd_stability.stderr index 778b0e55f66..7ec2508ca93 100644 --- a/tests/ui/consts/min_const_fn/min_const_fn_libstd_stability.stderr +++ b/tests/ui/consts/min_const_fn/min_const_fn_libstd_stability.stderr @@ -22,11 +22,13 @@ LL | const fn bar3() -> u32 { (5f32 + 6f32) as u32 } | help: if it is not part of the public API, make this function unstably const | -LL | #[rustc_const_unstable(feature = "...", issue = "...")] +LL + #[rustc_const_unstable(feature = "...", issue = "...")] +LL | const fn bar3() -> u32 { (5f32 + 6f32) as u32 } | help: otherwise `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks | -LL | #[rustc_allow_const_fn_unstable(const_fn_floating_point_arithmetic)] +LL + #[rustc_allow_const_fn_unstable(const_fn_floating_point_arithmetic)] +LL | const fn bar3() -> u32 { (5f32 + 6f32) as u32 } | error: `foo2_gated` is not yet stable as a const fn diff --git a/tests/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.stderr b/tests/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.stderr index 0174cb77f33..72c1f175d1d 100644 --- a/tests/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.stderr +++ b/tests/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.stderr @@ -22,11 +22,13 @@ LL | const unsafe fn bar3() -> u32 { (5f32 + 6f32) as u32 } | help: if it is not part of the public API, make this function unstably const | -LL | #[rustc_const_unstable(feature = "...", issue = "...")] +LL + #[rustc_const_unstable(feature = "...", issue = "...")] +LL | const unsafe fn bar3() -> u32 { (5f32 + 6f32) as u32 } | help: otherwise `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks | -LL | #[rustc_allow_const_fn_unstable(const_fn_floating_point_arithmetic)] +LL + #[rustc_allow_const_fn_unstable(const_fn_floating_point_arithmetic)] +LL | const unsafe fn bar3() -> u32 { (5f32 + 6f32) as u32 } | error: `foo2_gated` is not yet stable as a const fn diff --git a/tests/ui/derived-errors/issue-31997-1.stderr b/tests/ui/derived-errors/issue-31997-1.stderr index 2f4aabf8453..a0262f4c1e5 100644 --- a/tests/ui/derived-errors/issue-31997-1.stderr +++ b/tests/ui/derived-errors/issue-31997-1.stderr @@ -6,7 +6,7 @@ LL | let mut map = HashMap::new(); | help: consider importing this struct | -LL | use std::collections::HashMap; +LL + use std::collections::HashMap; | error: aborting due to previous error diff --git a/tests/ui/derives/derive-assoc-type-not-impl.stderr b/tests/ui/derives/derive-assoc-type-not-impl.stderr index 91b334b412b..9f17c76c2ec 100644 --- a/tests/ui/derives/derive-assoc-type-not-impl.stderr +++ b/tests/ui/derives/derive-assoc-type-not-impl.stderr @@ -23,7 +23,8 @@ LL | #[derive(Clone)] candidate #1: `Clone` help: consider annotating `NotClone` with `#[derive(Clone)]` | -LL | #[derive(Clone)] +LL + #[derive(Clone)] +LL | struct NotClone; | error: aborting due to previous error diff --git a/tests/ui/derives/derives-span-Clone-enum-struct-variant.stderr b/tests/ui/derives/derives-span-Clone-enum-struct-variant.stderr index 7326324b03c..31ab589cf38 100644 --- a/tests/ui/derives/derives-span-Clone-enum-struct-variant.stderr +++ b/tests/ui/derives/derives-span-Clone-enum-struct-variant.stderr @@ -10,7 +10,8 @@ LL | x: Error = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider annotating `Error` with `#[derive(Clone)]` | -LL | #[derive(Clone)] +LL + #[derive(Clone)] +LL | struct Error; | error: aborting due to previous error diff --git a/tests/ui/derives/derives-span-Clone-enum.stderr b/tests/ui/derives/derives-span-Clone-enum.stderr index 229a4f7d9ff..b5580c02f38 100644 --- a/tests/ui/derives/derives-span-Clone-enum.stderr +++ b/tests/ui/derives/derives-span-Clone-enum.stderr @@ -10,7 +10,8 @@ LL | Error = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider annotating `Error` with `#[derive(Clone)]` | -LL | #[derive(Clone)] +LL + #[derive(Clone)] +LL | struct Error; | error: aborting due to previous error diff --git a/tests/ui/derives/derives-span-Clone-struct.stderr b/tests/ui/derives/derives-span-Clone-struct.stderr index 96bad9edad9..fbe7e3f8479 100644 --- a/tests/ui/derives/derives-span-Clone-struct.stderr +++ b/tests/ui/derives/derives-span-Clone-struct.stderr @@ -10,7 +10,8 @@ LL | x: Error = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider annotating `Error` with `#[derive(Clone)]` | -LL | #[derive(Clone)] +LL + #[derive(Clone)] +LL | struct Error; | error: aborting due to previous error diff --git a/tests/ui/derives/derives-span-Clone-tuple-struct.stderr b/tests/ui/derives/derives-span-Clone-tuple-struct.stderr index b61341e57e6..639f4d54254 100644 --- a/tests/ui/derives/derives-span-Clone-tuple-struct.stderr +++ b/tests/ui/derives/derives-span-Clone-tuple-struct.stderr @@ -10,7 +10,8 @@ LL | Error = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider annotating `Error` with `#[derive(Clone)]` | -LL | #[derive(Clone)] +LL + #[derive(Clone)] +LL | struct Error; | error: aborting due to previous error diff --git a/tests/ui/derives/derives-span-Debug-enum-struct-variant.stderr b/tests/ui/derives/derives-span-Debug-enum-struct-variant.stderr index 58a64a4f53b..7ff6851f655 100644 --- a/tests/ui/derives/derives-span-Debug-enum-struct-variant.stderr +++ b/tests/ui/derives/derives-span-Debug-enum-struct-variant.stderr @@ -12,7 +12,8 @@ LL | x: Error = note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider annotating `Error` with `#[derive(Debug)]` | -LL | #[derive(Debug)] +LL + #[derive(Debug)] +LL | struct Error; | error: aborting due to previous error diff --git a/tests/ui/derives/derives-span-Debug-enum.stderr b/tests/ui/derives/derives-span-Debug-enum.stderr index e9bb5f960b0..346cbec90a9 100644 --- a/tests/ui/derives/derives-span-Debug-enum.stderr +++ b/tests/ui/derives/derives-span-Debug-enum.stderr @@ -12,7 +12,8 @@ LL | Error = note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider annotating `Error` with `#[derive(Debug)]` | -LL | #[derive(Debug)] +LL + #[derive(Debug)] +LL | struct Error; | error: aborting due to previous error diff --git a/tests/ui/derives/derives-span-Debug-struct.stderr b/tests/ui/derives/derives-span-Debug-struct.stderr index 0a117c060ff..4b39eeb09ee 100644 --- a/tests/ui/derives/derives-span-Debug-struct.stderr +++ b/tests/ui/derives/derives-span-Debug-struct.stderr @@ -12,7 +12,8 @@ LL | x: Error = note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider annotating `Error` with `#[derive(Debug)]` | -LL | #[derive(Debug)] +LL + #[derive(Debug)] +LL | struct Error; | error: aborting due to previous error diff --git a/tests/ui/derives/derives-span-Debug-tuple-struct.stderr b/tests/ui/derives/derives-span-Debug-tuple-struct.stderr index f2e90a41845..f3043abcadd 100644 --- a/tests/ui/derives/derives-span-Debug-tuple-struct.stderr +++ b/tests/ui/derives/derives-span-Debug-tuple-struct.stderr @@ -12,7 +12,8 @@ LL | Error = note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider annotating `Error` with `#[derive(Debug)]` | -LL | #[derive(Debug)] +LL + #[derive(Debug)] +LL | struct Error; | error: aborting due to previous error diff --git a/tests/ui/derives/derives-span-Default-struct.stderr b/tests/ui/derives/derives-span-Default-struct.stderr index d4affd535ee..4844b635924 100644 --- a/tests/ui/derives/derives-span-Default-struct.stderr +++ b/tests/ui/derives/derives-span-Default-struct.stderr @@ -10,7 +10,8 @@ LL | x: Error = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider annotating `Error` with `#[derive(Default)]` | -LL | #[derive(Default)] +LL + #[derive(Default)] +LL | struct Error; | error: aborting due to previous error diff --git a/tests/ui/derives/derives-span-Default-tuple-struct.stderr b/tests/ui/derives/derives-span-Default-tuple-struct.stderr index 129351f5998..9cac7f10780 100644 --- a/tests/ui/derives/derives-span-Default-tuple-struct.stderr +++ b/tests/ui/derives/derives-span-Default-tuple-struct.stderr @@ -10,7 +10,8 @@ LL | Error = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider annotating `Error` with `#[derive(Default)]` | -LL | #[derive(Default)] +LL + #[derive(Default)] +LL | struct Error; | error: aborting due to previous error diff --git a/tests/ui/derives/derives-span-Eq-enum-struct-variant.stderr b/tests/ui/derives/derives-span-Eq-enum-struct-variant.stderr index 2be69a30b1c..1a9ff983255 100644 --- a/tests/ui/derives/derives-span-Eq-enum-struct-variant.stderr +++ b/tests/ui/derives/derives-span-Eq-enum-struct-variant.stderr @@ -12,7 +12,8 @@ note: required by a bound in `AssertParamIsEq` = note: this error originates in the derive macro `Eq` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider annotating `Error` with `#[derive(Eq)]` | -LL | #[derive(Eq)] +LL + #[derive(Eq)] +LL | struct Error; | error: aborting due to previous error diff --git a/tests/ui/derives/derives-span-Eq-enum.stderr b/tests/ui/derives/derives-span-Eq-enum.stderr index 4f4f821cca3..8205657bb71 100644 --- a/tests/ui/derives/derives-span-Eq-enum.stderr +++ b/tests/ui/derives/derives-span-Eq-enum.stderr @@ -12,7 +12,8 @@ note: required by a bound in `AssertParamIsEq` = note: this error originates in the derive macro `Eq` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider annotating `Error` with `#[derive(Eq)]` | -LL | #[derive(Eq)] +LL + #[derive(Eq)] +LL | struct Error; | error: aborting due to previous error diff --git a/tests/ui/derives/derives-span-Eq-struct.stderr b/tests/ui/derives/derives-span-Eq-struct.stderr index f15659c3e16..af510181df7 100644 --- a/tests/ui/derives/derives-span-Eq-struct.stderr +++ b/tests/ui/derives/derives-span-Eq-struct.stderr @@ -12,7 +12,8 @@ note: required by a bound in `AssertParamIsEq` = note: this error originates in the derive macro `Eq` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider annotating `Error` with `#[derive(Eq)]` | -LL | #[derive(Eq)] +LL + #[derive(Eq)] +LL | struct Error; | error: aborting due to previous error diff --git a/tests/ui/derives/derives-span-Eq-tuple-struct.stderr b/tests/ui/derives/derives-span-Eq-tuple-struct.stderr index 4e5659b35f4..f7c371d7d05 100644 --- a/tests/ui/derives/derives-span-Eq-tuple-struct.stderr +++ b/tests/ui/derives/derives-span-Eq-tuple-struct.stderr @@ -12,7 +12,8 @@ note: required by a bound in `AssertParamIsEq` = note: this error originates in the derive macro `Eq` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider annotating `Error` with `#[derive(Eq)]` | -LL | #[derive(Eq)] +LL + #[derive(Eq)] +LL | struct Error; | error: aborting due to previous error diff --git a/tests/ui/derives/derives-span-Hash-enum-struct-variant.stderr b/tests/ui/derives/derives-span-Hash-enum-struct-variant.stderr index fe5e0e96ac7..311edade0f3 100644 --- a/tests/ui/derives/derives-span-Hash-enum-struct-variant.stderr +++ b/tests/ui/derives/derives-span-Hash-enum-struct-variant.stderr @@ -10,7 +10,8 @@ LL | x: Error = note: this error originates in the derive macro `Hash` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider annotating `Error` with `#[derive(Hash)]` | -LL | #[derive(Hash)] +LL + #[derive(Hash)] +LL | struct Error; | error: aborting due to previous error diff --git a/tests/ui/derives/derives-span-Hash-enum.stderr b/tests/ui/derives/derives-span-Hash-enum.stderr index 99785b87ca8..043aa954bfa 100644 --- a/tests/ui/derives/derives-span-Hash-enum.stderr +++ b/tests/ui/derives/derives-span-Hash-enum.stderr @@ -10,7 +10,8 @@ LL | Error = note: this error originates in the derive macro `Hash` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider annotating `Error` with `#[derive(Hash)]` | -LL | #[derive(Hash)] +LL + #[derive(Hash)] +LL | struct Error; | error: aborting due to previous error diff --git a/tests/ui/derives/derives-span-Hash-struct.stderr b/tests/ui/derives/derives-span-Hash-struct.stderr index 4db83dd1300..26d31b6613f 100644 --- a/tests/ui/derives/derives-span-Hash-struct.stderr +++ b/tests/ui/derives/derives-span-Hash-struct.stderr @@ -10,7 +10,8 @@ LL | x: Error = note: this error originates in the derive macro `Hash` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider annotating `Error` with `#[derive(Hash)]` | -LL | #[derive(Hash)] +LL + #[derive(Hash)] +LL | struct Error; | error: aborting due to previous error diff --git a/tests/ui/derives/derives-span-Hash-tuple-struct.stderr b/tests/ui/derives/derives-span-Hash-tuple-struct.stderr index 8660c97e69e..3155a023ce8 100644 --- a/tests/ui/derives/derives-span-Hash-tuple-struct.stderr +++ b/tests/ui/derives/derives-span-Hash-tuple-struct.stderr @@ -10,7 +10,8 @@ LL | Error = note: this error originates in the derive macro `Hash` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider annotating `Error` with `#[derive(Hash)]` | -LL | #[derive(Hash)] +LL + #[derive(Hash)] +LL | struct Error; | error: aborting due to previous error diff --git a/tests/ui/derives/derives-span-Ord-enum-struct-variant.stderr b/tests/ui/derives/derives-span-Ord-enum-struct-variant.stderr index 6e48332c250..1a06aee5235 100644 --- a/tests/ui/derives/derives-span-Ord-enum-struct-variant.stderr +++ b/tests/ui/derives/derives-span-Ord-enum-struct-variant.stderr @@ -10,7 +10,8 @@ LL | x: Error = note: this error originates in the derive macro `Ord` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider annotating `Error` with `#[derive(Ord)]` | -LL | #[derive(Ord)] +LL + #[derive(Ord)] +LL | struct Error; | error: aborting due to previous error diff --git a/tests/ui/derives/derives-span-Ord-enum.stderr b/tests/ui/derives/derives-span-Ord-enum.stderr index b05cf0a057b..377728e8a7f 100644 --- a/tests/ui/derives/derives-span-Ord-enum.stderr +++ b/tests/ui/derives/derives-span-Ord-enum.stderr @@ -10,7 +10,8 @@ LL | Error = note: this error originates in the derive macro `Ord` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider annotating `Error` with `#[derive(Ord)]` | -LL | #[derive(Ord)] +LL + #[derive(Ord)] +LL | struct Error; | error: aborting due to previous error diff --git a/tests/ui/derives/derives-span-Ord-struct.stderr b/tests/ui/derives/derives-span-Ord-struct.stderr index c4def34a83d..e00e990da2a 100644 --- a/tests/ui/derives/derives-span-Ord-struct.stderr +++ b/tests/ui/derives/derives-span-Ord-struct.stderr @@ -10,7 +10,8 @@ LL | x: Error = note: this error originates in the derive macro `Ord` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider annotating `Error` with `#[derive(Ord)]` | -LL | #[derive(Ord)] +LL + #[derive(Ord)] +LL | struct Error; | error: aborting due to previous error diff --git a/tests/ui/derives/derives-span-Ord-tuple-struct.stderr b/tests/ui/derives/derives-span-Ord-tuple-struct.stderr index a3b288d0fb9..959d0b96404 100644 --- a/tests/ui/derives/derives-span-Ord-tuple-struct.stderr +++ b/tests/ui/derives/derives-span-Ord-tuple-struct.stderr @@ -10,7 +10,8 @@ LL | Error = note: this error originates in the derive macro `Ord` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider annotating `Error` with `#[derive(Ord)]` | -LL | #[derive(Ord)] +LL + #[derive(Ord)] +LL | struct Error; | error: aborting due to previous error diff --git a/tests/ui/derives/derives-span-PartialEq-enum-struct-variant.stderr b/tests/ui/derives/derives-span-PartialEq-enum-struct-variant.stderr index 9953154fd4b..9fc25f2ade4 100644 --- a/tests/ui/derives/derives-span-PartialEq-enum-struct-variant.stderr +++ b/tests/ui/derives/derives-span-PartialEq-enum-struct-variant.stderr @@ -15,7 +15,8 @@ LL | struct Error; = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider annotating `Error` with `#[derive(PartialEq)]` | -LL | #[derive(PartialEq)] +LL + #[derive(PartialEq)] +LL | struct Error; | error: aborting due to previous error diff --git a/tests/ui/derives/derives-span-PartialEq-enum.stderr b/tests/ui/derives/derives-span-PartialEq-enum.stderr index 7c130452301..f56e784478d 100644 --- a/tests/ui/derives/derives-span-PartialEq-enum.stderr +++ b/tests/ui/derives/derives-span-PartialEq-enum.stderr @@ -15,7 +15,8 @@ LL | struct Error; = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider annotating `Error` with `#[derive(PartialEq)]` | -LL | #[derive(PartialEq)] +LL + #[derive(PartialEq)] +LL | struct Error; | error: aborting due to previous error diff --git a/tests/ui/derives/derives-span-PartialEq-struct.stderr b/tests/ui/derives/derives-span-PartialEq-struct.stderr index ba3d6ced3f4..76c0b0104af 100644 --- a/tests/ui/derives/derives-span-PartialEq-struct.stderr +++ b/tests/ui/derives/derives-span-PartialEq-struct.stderr @@ -15,7 +15,8 @@ LL | struct Error; = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider annotating `Error` with `#[derive(PartialEq)]` | -LL | #[derive(PartialEq)] +LL + #[derive(PartialEq)] +LL | struct Error; | error: aborting due to previous error diff --git a/tests/ui/derives/derives-span-PartialEq-tuple-struct.stderr b/tests/ui/derives/derives-span-PartialEq-tuple-struct.stderr index ab0b56a9eef..7dae01dbb99 100644 --- a/tests/ui/derives/derives-span-PartialEq-tuple-struct.stderr +++ b/tests/ui/derives/derives-span-PartialEq-tuple-struct.stderr @@ -15,7 +15,8 @@ LL | struct Error; = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider annotating `Error` with `#[derive(PartialEq)]` | -LL | #[derive(PartialEq)] +LL + #[derive(PartialEq)] +LL | struct Error; | error: aborting due to previous error diff --git a/tests/ui/derives/derives-span-PartialOrd-enum-struct-variant.stderr b/tests/ui/derives/derives-span-PartialOrd-enum-struct-variant.stderr index 2d19aaf68af..746c1d5d21f 100644 --- a/tests/ui/derives/derives-span-PartialOrd-enum-struct-variant.stderr +++ b/tests/ui/derives/derives-span-PartialOrd-enum-struct-variant.stderr @@ -11,7 +11,8 @@ LL | x: Error = note: this error originates in the derive macro `PartialOrd` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider annotating `Error` with `#[derive(PartialOrd)]` | -LL | #[derive(PartialOrd)] +LL + #[derive(PartialOrd)] +LL | struct Error; | error: aborting due to previous error diff --git a/tests/ui/derives/derives-span-PartialOrd-enum.stderr b/tests/ui/derives/derives-span-PartialOrd-enum.stderr index dfbb8060ffa..8af1776dac8 100644 --- a/tests/ui/derives/derives-span-PartialOrd-enum.stderr +++ b/tests/ui/derives/derives-span-PartialOrd-enum.stderr @@ -11,7 +11,8 @@ LL | Error = note: this error originates in the derive macro `PartialOrd` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider annotating `Error` with `#[derive(PartialOrd)]` | -LL | #[derive(PartialOrd)] +LL + #[derive(PartialOrd)] +LL | struct Error; | error: aborting due to previous error diff --git a/tests/ui/derives/derives-span-PartialOrd-struct.stderr b/tests/ui/derives/derives-span-PartialOrd-struct.stderr index ba63d86e8e4..11ea7f9dc31 100644 --- a/tests/ui/derives/derives-span-PartialOrd-struct.stderr +++ b/tests/ui/derives/derives-span-PartialOrd-struct.stderr @@ -11,7 +11,8 @@ LL | x: Error = note: this error originates in the derive macro `PartialOrd` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider annotating `Error` with `#[derive(PartialOrd)]` | -LL | #[derive(PartialOrd)] +LL + #[derive(PartialOrd)] +LL | struct Error; | error: aborting due to previous error diff --git a/tests/ui/derives/derives-span-PartialOrd-tuple-struct.stderr b/tests/ui/derives/derives-span-PartialOrd-tuple-struct.stderr index 7686ed8064e..0a41a3db31e 100644 --- a/tests/ui/derives/derives-span-PartialOrd-tuple-struct.stderr +++ b/tests/ui/derives/derives-span-PartialOrd-tuple-struct.stderr @@ -11,7 +11,8 @@ LL | Error = note: this error originates in the derive macro `PartialOrd` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider annotating `Error` with `#[derive(PartialOrd)]` | -LL | #[derive(PartialOrd)] +LL + #[derive(PartialOrd)] +LL | struct Error; | error: aborting due to previous error diff --git a/tests/ui/derives/deriving-no-inner-impl-error-message.stderr b/tests/ui/derives/deriving-no-inner-impl-error-message.stderr index ef8c44caacf..10af5d36ed9 100644 --- a/tests/ui/derives/deriving-no-inner-impl-error-message.stderr +++ b/tests/ui/derives/deriving-no-inner-impl-error-message.stderr @@ -15,7 +15,8 @@ LL | struct NoCloneOrEq; = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider annotating `NoCloneOrEq` with `#[derive(PartialEq)]` | -LL | #[derive(PartialEq)] +LL + #[derive(PartialEq)] +LL | struct NoCloneOrEq; | error[E0277]: the trait bound `NoCloneOrEq: Clone` is not satisfied @@ -30,7 +31,8 @@ LL | x: NoCloneOrEq = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider annotating `NoCloneOrEq` with `#[derive(Clone)]` | -LL | #[derive(Clone)] +LL + #[derive(Clone)] +LL | struct NoCloneOrEq; | error: aborting due to 2 previous errors diff --git a/tests/ui/derives/deriving-with-repr-packed-2.stderr b/tests/ui/derives/deriving-with-repr-packed-2.stderr index ab3646057a5..afeca9fec2b 100644 --- a/tests/ui/derives/deriving-with-repr-packed-2.stderr +++ b/tests/ui/derives/deriving-with-repr-packed-2.stderr @@ -25,7 +25,8 @@ LL | #[derive(Copy, Clone, Default, PartialEq, Eq)] | ^^^^^ unsatisfied trait bound introduced in this `derive` macro help: consider annotating `NonCopy` with `#[derive(Clone, Copy)]` | -LL | #[derive(Clone, Copy)] +LL + #[derive(Clone, Copy)] +LL | struct NonCopy; | error: aborting due to previous error diff --git a/tests/ui/derives/issue-91492.stderr b/tests/ui/derives/issue-91492.stderr index cee30ac50a6..fc64828b153 100644 --- a/tests/ui/derives/issue-91492.stderr +++ b/tests/ui/derives/issue-91492.stderr @@ -11,7 +11,8 @@ LL | foo.extend_from_slice(bar); `NoDerives: Clone` help: consider annotating `NoDerives` with `#[derive(Clone)]` | -LL | #[derive(Clone)] +LL + #[derive(Clone)] +LL | pub struct NoDerives; | error[E0599]: the method `extend_from_slice` exists for mutable reference `&mut Vec<SomeDerives>`, but its trait bounds were not satisfied @@ -27,7 +28,8 @@ LL | foo.extend_from_slice(bar); `SomeDerives: Clone` help: consider annotating `SomeDerives` with `#[derive(Clone)]` | -LL | #[derive(Clone)] +LL + #[derive(Clone)] +LL | pub struct SomeDerives; | error[E0599]: the method `use_clone` exists for struct `Object<NoDerives, SomeDerives>`, but its trait bounds were not satisfied @@ -51,7 +53,8 @@ LL | impl<T: Clone, A: Default> Object<T, A> { | unsatisfied trait bound introduced here help: consider annotating `NoDerives` with `#[derive(Clone)]` | -LL | #[derive(Clone)] +LL + #[derive(Clone)] +LL | pub struct NoDerives; | error: aborting due to 3 previous errors diff --git a/tests/ui/derives/issue-91550.stderr b/tests/ui/derives/issue-91550.stderr index af03f0e5e5f..1324b80b5fc 100644 --- a/tests/ui/derives/issue-91550.stderr +++ b/tests/ui/derives/issue-91550.stderr @@ -18,7 +18,8 @@ LL | hs.insert(Value(0)); `Value: Hash` help: consider annotating `Value` with `#[derive(Eq, Hash, PartialEq)]` | -LL | #[derive(Eq, Hash, PartialEq)] +LL + #[derive(Eq, Hash, PartialEq)] +LL | struct Value(u32); | error[E0599]: the method `use_eq` exists for struct `Object<NoDerives>`, but its trait bounds were not satisfied @@ -48,7 +49,8 @@ LL | impl<T: Eq> Object<T> { which is required by `NoDerives: Eq` help: consider annotating `NoDerives` with `#[derive(Eq, PartialEq)]` | -LL | #[derive(Eq, PartialEq)] +LL + #[derive(Eq, PartialEq)] +LL | pub struct NoDerives; | error[E0599]: the method `use_ord` exists for struct `Object<NoDerives>`, but its trait bounds were not satisfied @@ -84,7 +86,8 @@ LL | impl<T: Ord> Object<T> { which is required by `NoDerives: Ord` help: consider annotating `NoDerives` with `#[derive(Eq, Ord, PartialEq, PartialOrd)]` | -LL | #[derive(Eq, Ord, PartialEq, PartialOrd)] +LL + #[derive(Eq, Ord, PartialEq, PartialOrd)] +LL | pub struct NoDerives; | error[E0599]: the method `use_ord_and_partial_ord` exists for struct `Object<NoDerives>`, but its trait bounds were not satisfied @@ -123,7 +126,8 @@ LL | impl<T: Ord + PartialOrd> Object<T> { which is required by `NoDerives: PartialOrd` help: consider annotating `NoDerives` with `#[derive(Eq, Ord, PartialEq, PartialOrd)]` | -LL | #[derive(Eq, Ord, PartialEq, PartialOrd)] +LL + #[derive(Eq, Ord, PartialEq, PartialOrd)] +LL | pub struct NoDerives; | error: aborting due to 4 previous errors diff --git a/tests/ui/did_you_mean/issue-56028-there-is-an-enum-variant.stderr b/tests/ui/did_you_mean/issue-56028-there-is-an-enum-variant.stderr index abc040c0546..5c610f36322 100644 --- a/tests/ui/did_you_mean/issue-56028-there-is-an-enum-variant.stderr +++ b/tests/ui/did_you_mean/issue-56028-there-is-an-enum-variant.stderr @@ -24,13 +24,13 @@ LL | fn setup() -> Set { Set } | help: consider importing one of these items | -LL | use AffixHeart::Set; +LL + use AffixHeart::Set; | -LL | use CauseToBe::Set; +LL + use CauseToBe::Set; | -LL | use Determine::Set; +LL + use Determine::Set; | -LL | use PutDown::Set; +LL + use PutDown::Set; | and 3 other candidates diff --git a/tests/ui/error-codes/E0277-3.stderr b/tests/ui/error-codes/E0277-3.stderr index 0127e1ccc81..0d4782935df 100644 --- a/tests/ui/error-codes/E0277-3.stderr +++ b/tests/ui/error-codes/E0277-3.stderr @@ -14,7 +14,8 @@ LL | fn foo<T: PartialEq>(_: T) {} | ^^^^^^^^^ required by this bound in `foo` help: consider annotating `S` with `#[derive(PartialEq)]` | -LL | #[derive(PartialEq)] +LL + #[derive(PartialEq)] +LL | struct S; | error: aborting due to previous error diff --git a/tests/ui/feature-gates/feature-gate-impl_trait_in_assoc_type.rs b/tests/ui/feature-gates/feature-gate-impl_trait_in_assoc_type.rs new file mode 100644 index 00000000000..de0487cdb20 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-impl_trait_in_assoc_type.rs @@ -0,0 +1,18 @@ +trait Foo { + type Bar; +} + +impl Foo for () { + type Bar = impl std::fmt::Debug; + //~^ ERROR: `impl Trait` in associated types is unstable +} + +struct Mop; + +impl Mop { + type Bop = impl std::fmt::Debug; + //~^ ERROR: `impl Trait` in associated types is unstable + //~| ERROR: inherent associated types are unstable +} + +fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-impl_trait_in_assoc_type.stderr b/tests/ui/feature-gates/feature-gate-impl_trait_in_assoc_type.stderr new file mode 100644 index 00000000000..9a1ded96822 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-impl_trait_in_assoc_type.stderr @@ -0,0 +1,30 @@ +error[E0658]: `impl Trait` in associated types is unstable + --> $DIR/feature-gate-impl_trait_in_assoc_type.rs:6:16 + | +LL | type Bar = impl std::fmt::Debug; + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information + = help: add `#![feature(impl_trait_in_assoc_type)]` to the crate attributes to enable + +error[E0658]: `impl Trait` in associated types is unstable + --> $DIR/feature-gate-impl_trait_in_assoc_type.rs:13:16 + | +LL | type Bop = impl std::fmt::Debug; + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information + = help: add `#![feature(impl_trait_in_assoc_type)]` to the crate attributes to enable + +error[E0658]: inherent associated types are unstable + --> $DIR/feature-gate-impl_trait_in_assoc_type.rs:13:5 + | +LL | type Bop = impl std::fmt::Debug; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #8995 <https://github.com/rust-lang/rust/issues/8995> for more information + = help: add `#![feature(inherent_associated_types)]` to the crate attributes to enable + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/feature-gates/feature-gate-return_type_notation.cfg.stderr b/tests/ui/feature-gates/feature-gate-return_type_notation.cfg.stderr index 85728f8e1ad..c3a371e25e8 100644 --- a/tests/ui/feature-gates/feature-gate-return_type_notation.cfg.stderr +++ b/tests/ui/feature-gates/feature-gate-return_type_notation.cfg.stderr @@ -1,14 +1,14 @@ error[E0658]: return type notation is experimental - --> $DIR/feature-gate-return_type_notation.rs:12:18 + --> $DIR/feature-gate-return_type_notation.rs:15:17 | -LL | fn foo<T: Trait<m(..): Send>>() {} - | ^^^^ +LL | fn foo<T: Trait<m(): Send>>() {} + | ^^^^^^^^^ | = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information = help: add `#![feature(return_type_notation)]` to the crate attributes to enable warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/feature-gate-return_type_notation.rs:4:12 + --> $DIR/feature-gate-return_type_notation.rs:7:12 | LL | #![feature(async_fn_in_trait)] | ^^^^^^^^^^^^^^^^^ @@ -16,6 +16,21 @@ LL | #![feature(async_fn_in_trait)] = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information = note: `#[warn(incomplete_features)]` on by default -error: aborting due to previous error; 1 warning emitted +error: parenthesized generic arguments cannot be used in associated type constraints + --> $DIR/feature-gate-return_type_notation.rs:15:17 + | +LL | fn foo<T: Trait<m(): Send>>() {} + | ^-- + | | + | help: remove these parentheses + +error[E0220]: associated type `m` not found for `Trait` + --> $DIR/feature-gate-return_type_notation.rs:15:17 + | +LL | fn foo<T: Trait<m(): Send>>() {} + | ^ associated type `m` not found + +error: aborting due to 3 previous errors; 1 warning emitted -For more information about this error, try `rustc --explain E0658`. +Some errors have detailed explanations: E0220, E0658. +For more information about an error, try `rustc --explain E0220`. diff --git a/tests/ui/feature-gates/feature-gate-return_type_notation.no.stderr b/tests/ui/feature-gates/feature-gate-return_type_notation.no.stderr index 85728f8e1ad..52c90c1565c 100644 --- a/tests/ui/feature-gates/feature-gate-return_type_notation.no.stderr +++ b/tests/ui/feature-gates/feature-gate-return_type_notation.no.stderr @@ -1,14 +1,5 @@ -error[E0658]: return type notation is experimental - --> $DIR/feature-gate-return_type_notation.rs:12:18 - | -LL | fn foo<T: Trait<m(..): Send>>() {} - | ^^^^ - | - = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information - = help: add `#![feature(return_type_notation)]` to the crate attributes to enable - warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/feature-gate-return_type_notation.rs:4:12 + --> $DIR/feature-gate-return_type_notation.rs:7:12 | LL | #![feature(async_fn_in_trait)] | ^^^^^^^^^^^^^^^^^ @@ -16,6 +7,16 @@ LL | #![feature(async_fn_in_trait)] = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information = note: `#[warn(incomplete_features)]` on by default -error: aborting due to previous error; 1 warning emitted +warning: return type notation is experimental + --> $DIR/feature-gate-return_type_notation.rs:15:17 + | +LL | fn foo<T: Trait<m(): Send>>() {} + | ^^^^^^^^^ + | + = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information + = help: add `#![feature(return_type_notation)]` to the crate attributes to enable + = warning: unstable syntax can change at any point in the future, causing a hard error! + = note: for more information, see issue #65860 <https://github.com/rust-lang/rust/issues/65860> + +warning: 2 warnings emitted -For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/feature-gates/feature-gate-return_type_notation.rs b/tests/ui/feature-gates/feature-gate-return_type_notation.rs index b75feb130a6..5028b9ec9e3 100644 --- a/tests/ui/feature-gates/feature-gate-return_type_notation.rs +++ b/tests/ui/feature-gates/feature-gate-return_type_notation.rs @@ -1,6 +1,9 @@ // edition: 2021 // revisions: cfg no +//[no] check-pass +// Since we're not adding new syntax, `cfg`'d out RTN must pass. + #![feature(async_fn_in_trait)] //~^ WARN the feature `async_fn_in_trait` is incomplete @@ -9,7 +12,11 @@ trait Trait { } #[cfg(cfg)] -fn foo<T: Trait<m(..): Send>>() {} -//~^ ERROR return type notation is experimental +fn foo<T: Trait<m(): Send>>() {} +//[cfg]~^ ERROR return type notation is experimental +//[cfg]~| ERROR parenthesized generic arguments cannot be used in associated type constraints +//[cfg]~| ERROR associated type `m` not found for `Trait` +//[no]~^^^^ WARN return type notation is experimental +//[no]~| WARN unstable syntax can change at any point in the future, causing a hard error! fn main() {} diff --git a/tests/ui/fmt/format-args-argument-span.stderr b/tests/ui/fmt/format-args-argument-span.stderr index b060b2cd339..4e2702383d6 100644 --- a/tests/ui/fmt/format-args-argument-span.stderr +++ b/tests/ui/fmt/format-args-argument-span.stderr @@ -29,7 +29,8 @@ LL | println!("{x} {x:?} {x}"); = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider annotating `DisplayOnly` with `#[derive(Debug)]` | -LL | #[derive(Debug)] +LL + #[derive(Debug)] +LL | struct DisplayOnly; | error[E0277]: `DisplayOnly` doesn't implement `Debug` @@ -43,7 +44,8 @@ LL | println!("{x} {x:?} {x}", x = DisplayOnly); = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider annotating `DisplayOnly` with `#[derive(Debug)]` | -LL | #[derive(Debug)] +LL + #[derive(Debug)] +LL | struct DisplayOnly; | error: aborting due to 4 previous errors diff --git a/tests/ui/generator/clone-impl.stderr b/tests/ui/generator/clone-impl.stderr index a92646b198c..64eb47c1a5a 100644 --- a/tests/ui/generator/clone-impl.stderr +++ b/tests/ui/generator/clone-impl.stderr @@ -110,7 +110,8 @@ LL | fn check_copy<T: Copy>(_x: &T) {} | ^^^^ required by this bound in `check_copy` help: consider annotating `NonClone` with `#[derive(Copy)]` | -LL | #[derive(Copy)] +LL + #[derive(Copy)] +LL | struct NonClone; | error[E0277]: the trait bound `NonClone: Clone` is not satisfied in `[generator@$DIR/clone-impl.rs:62:25: 62:32]` @@ -134,7 +135,8 @@ LL | fn check_clone<T: Clone>(_x: &T) {} | ^^^^^ required by this bound in `check_clone` help: consider annotating `NonClone` with `#[derive(Clone)]` | -LL | #[derive(Clone)] +LL + #[derive(Clone)] +LL | struct NonClone; | error: aborting due to 6 previous errors diff --git a/tests/ui/generator/issue-87142.rs b/tests/ui/generator/issue-87142.rs index fc10d04d46c..7f670919ed6 100644 --- a/tests/ui/generator/issue-87142.rs +++ b/tests/ui/generator/issue-87142.rs @@ -4,7 +4,7 @@ // Regression test for #87142 // This test needs the above flags and the "lib" crate type. -#![feature(type_alias_impl_trait, generator_trait, generators)] +#![feature(impl_trait_in_assoc_type, generator_trait, generators)] #![crate_type = "lib"] use std::ops::Generator; diff --git a/tests/ui/generic-associated-types/issue-86218-2.rs b/tests/ui/generic-associated-types/issue-86218-2.rs index 63c839ea871..8a5e4a0f3cc 100644 --- a/tests/ui/generic-associated-types/issue-86218-2.rs +++ b/tests/ui/generic-associated-types/issue-86218-2.rs @@ -1,6 +1,6 @@ // check-pass -#![feature(type_alias_impl_trait)] +#![feature(impl_trait_in_assoc_type)] pub trait Stream { type Item; @@ -17,7 +17,9 @@ trait Yay<AdditionalValue> { impl<T> Yay<T> for () { type InnerStream<'s> = impl Stream<Item = i32> + 's; - fn foo<'s>() -> Self::InnerStream<'s> { () } + fn foo<'s>() -> Self::InnerStream<'s> { + () + } } fn main() {} diff --git a/tests/ui/generic-associated-types/issue-86218.rs b/tests/ui/generic-associated-types/issue-86218.rs index b2c3071f06b..61cfdd35a89 100644 --- a/tests/ui/generic-associated-types/issue-86218.rs +++ b/tests/ui/generic-associated-types/issue-86218.rs @@ -1,6 +1,6 @@ // check-pass -#![feature(type_alias_impl_trait)] +#![feature(impl_trait_in_assoc_type)] pub trait Stream { type Item; @@ -18,7 +18,9 @@ trait Yay<AdditionalValue> { impl<'a> Yay<&'a ()> for () { type InnerStream<'s> = impl Stream<Item = i32> + 's; //^ ERROR does not fulfill the required lifetime - fn foo<'s>() -> Self::InnerStream<'s> { () } + fn foo<'s>() -> Self::InnerStream<'s> { + () + } } fn main() {} diff --git a/tests/ui/generic-associated-types/issue-87258_a.rs b/tests/ui/generic-associated-types/issue-87258_a.rs index 9ab683d3dc9..6f737b21f53 100644 --- a/tests/ui/generic-associated-types/issue-87258_a.rs +++ b/tests/ui/generic-associated-types/issue-87258_a.rs @@ -1,4 +1,4 @@ -#![feature(type_alias_impl_trait)] +#![feature(impl_trait_in_assoc_type)] // See https://github.com/rust-lang/rust/issues/87258#issuecomment-883293367 diff --git a/tests/ui/generic-associated-types/issue-87429-associated-type-default.stderr b/tests/ui/generic-associated-types/issue-87429-associated-type-default.stderr index b1abe012be2..a44bb6993d4 100644 --- a/tests/ui/generic-associated-types/issue-87429-associated-type-default.stderr +++ b/tests/ui/generic-associated-types/issue-87429-associated-type-default.stderr @@ -12,7 +12,8 @@ LL | type Member<'a>: for<'b> PartialEq<Self::Member<'b>> = Foo; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Family2::Member` help: consider annotating `Foo` with `#[derive(PartialEq)]` | -LL | #[derive(PartialEq)] +LL + #[derive(PartialEq)] +LL | struct Foo; | error: aborting due to previous error diff --git a/tests/ui/generic-associated-types/issue-87429-specialization.stderr b/tests/ui/generic-associated-types/issue-87429-specialization.stderr index 11c4ebf604e..c259c89a712 100644 --- a/tests/ui/generic-associated-types/issue-87429-specialization.stderr +++ b/tests/ui/generic-associated-types/issue-87429-specialization.stderr @@ -22,7 +22,8 @@ LL | type Member<'a>: for<'b> PartialEq<Self::Member<'b>>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Family::Member` help: consider annotating `Foo` with `#[derive(PartialEq)]` | -LL | #[derive(PartialEq)] +LL + #[derive(PartialEq)] +LL | struct Foo; | error: aborting due to previous error; 1 warning emitted diff --git a/tests/ui/generic-associated-types/issue-88595.rs b/tests/ui/generic-associated-types/issue-88595.rs index 24641ee1f78..5a40a612972 100644 --- a/tests/ui/generic-associated-types/issue-88595.rs +++ b/tests/ui/generic-associated-types/issue-88595.rs @@ -1,7 +1,8 @@ -#![feature(type_alias_impl_trait)] +#![feature(impl_trait_in_assoc_type)] fn main() {} +#[rustfmt::skip] trait A<'a> { type B<'b>: Clone // FIXME(generic_associated_types): Remove one of the below bounds diff --git a/tests/ui/generic-associated-types/issue-88595.stderr b/tests/ui/generic-associated-types/issue-88595.stderr index bcefc806685..79d3479af8c 100644 --- a/tests/ui/generic-associated-types/issue-88595.stderr +++ b/tests/ui/generic-associated-types/issue-88595.stderr @@ -1,11 +1,11 @@ error: non-defining opaque type use in defining scope - --> $DIR/issue-88595.rs:20:35 + --> $DIR/issue-88595.rs:21:35 | LL | fn a(&'a self) -> Self::B<'a> {} | ^^ | note: lifetime used multiple times - --> $DIR/issue-88595.rs:17:6 + --> $DIR/issue-88595.rs:18:6 | LL | impl<'a> A<'a> for C { | ^^ diff --git a/tests/ui/generic-associated-types/issue-89008.rs b/tests/ui/generic-associated-types/issue-89008.rs index 669dbafb5d5..94b07e674e8 100644 --- a/tests/ui/generic-associated-types/issue-89008.rs +++ b/tests/ui/generic-associated-types/issue-89008.rs @@ -1,7 +1,7 @@ // check-pass // edition:2021 -#![feature(type_alias_impl_trait)] +#![feature(impl_trait_in_assoc_type)] use std::future::Future; use std::marker::PhantomData; diff --git a/tests/ui/generic-associated-types/issue-90014.rs b/tests/ui/generic-associated-types/issue-90014.rs index 55db95a6d81..c4d762796e2 100644 --- a/tests/ui/generic-associated-types/issue-90014.rs +++ b/tests/ui/generic-associated-types/issue-90014.rs @@ -1,11 +1,13 @@ // edition:2018 -#![feature(type_alias_impl_trait)] +#![feature(impl_trait_in_assoc_type)] use std::future::Future; trait MakeFut { - type Fut<'a> where Self: 'a; + type Fut<'a> + where + Self: 'a; fn make_fut<'a>(&'a self) -> Self::Fut<'a>; } diff --git a/tests/ui/generic-associated-types/issue-90014.stderr b/tests/ui/generic-associated-types/issue-90014.stderr index b4b1bc7da7f..0d49398cac9 100644 --- a/tests/ui/generic-associated-types/issue-90014.stderr +++ b/tests/ui/generic-associated-types/issue-90014.stderr @@ -1,14 +1,14 @@ error[E0477]: the type `&mut ()` does not fulfill the required lifetime - --> $DIR/issue-90014.rs:13:20 + --> $DIR/issue-90014.rs:15:20 | -LL | type Fut<'a> where Self: 'a; +LL | type Fut<'a> | ------------ definition of `Fut` from trait ... LL | type Fut<'a> = impl Future<Output = ()>; | ^^^^^^^^^^^^^^^^^^^^^^^^ | note: type must outlive the lifetime `'a` as defined here - --> $DIR/issue-90014.rs:13:14 + --> $DIR/issue-90014.rs:15:14 | LL | type Fut<'a> = impl Future<Output = ()>; | ^^ diff --git a/tests/ui/higher-rank-trait-bounds/issue-95230.new.stderr b/tests/ui/higher-rank-trait-bounds/issue-95230.new.stderr index bcb201bf0c3..d4bc5b67220 100644 --- a/tests/ui/higher-rank-trait-bounds/issue-95230.new.stderr +++ b/tests/ui/higher-rank-trait-bounds/issue-95230.new.stderr @@ -1,9 +1,10 @@ -error[E0282]: type annotations needed +error[E0275]: overflow evaluating the requirement `for<'a> &'a mut Bar well-formed` --> $DIR/issue-95230.rs:9:13 | LL | for<'a> &'a mut Self:; - | ^^^^^^^^^^^^ cannot infer type for mutable reference `&'a mut Bar` + | ^^^^^^^^^^^^ | + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_95230`) note: required by a bound in `Bar` --> $DIR/issue-95230.rs:9:13 | @@ -15,4 +16,4 @@ LL | for<'a> &'a mut Self:; error: aborting due to previous error -For more information about this error, try `rustc --explain E0282`. +For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/hygiene/globs.stderr b/tests/ui/hygiene/globs.stderr index c01901be5fe..18017264440 100644 --- a/tests/ui/hygiene/globs.stderr +++ b/tests/ui/hygiene/globs.stderr @@ -13,7 +13,7 @@ LL | g(); | ~ help: consider importing this function | -LL | use foo::f; +LL + use foo::f; | error[E0425]: cannot find function `g` in this scope @@ -39,7 +39,7 @@ LL | f(); | ~ help: consider importing this function | -LL | use bar::g; +LL + use bar::g; | error[E0425]: cannot find function `f` in this scope diff --git a/tests/ui/hygiene/no_implicit_prelude.stderr b/tests/ui/hygiene/no_implicit_prelude.stderr index c48c840352f..96187b1c501 100644 --- a/tests/ui/hygiene/no_implicit_prelude.stderr +++ b/tests/ui/hygiene/no_implicit_prelude.stderr @@ -10,7 +10,7 @@ LL | Vec::new(); = note: this error originates in the macro `::bar::m` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider importing this struct | -LL | use std::vec::Vec; +LL + use std::vec::Vec; | error[E0599]: no method named `clone` found for unit type `()` in the current scope @@ -26,7 +26,7 @@ LL | ().clone() = note: this error originates in the macro `::bar::m` (in Nightly builds, run with -Z macro-backtrace for more info) help: the following trait is implemented but not in scope; perhaps add a `use` for it: | -LL | use std::clone::Clone; +LL + use std::clone::Clone; | error: aborting due to 2 previous errors diff --git a/tests/ui/hygiene/trait_items.stderr b/tests/ui/hygiene/trait_items.stderr index 80bdbe0e21e..f303534c709 100644 --- a/tests/ui/hygiene/trait_items.stderr +++ b/tests/ui/hygiene/trait_items.stderr @@ -14,7 +14,7 @@ LL | pub macro m() { ().f() } = note: this error originates in the macro `::baz::m` (in Nightly builds, run with -Z macro-backtrace for more info) help: the following trait is implemented but not in scope; perhaps add a `use` for it: | -LL | use foo::T; +LL + use foo::T; | error: aborting due to previous error diff --git a/tests/ui/impl-trait/associated-impl-trait-type-generic-trait.rs b/tests/ui/impl-trait/associated-impl-trait-type-generic-trait.rs index 6c7c46b0e3d..0908a0bf39d 100644 --- a/tests/ui/impl-trait/associated-impl-trait-type-generic-trait.rs +++ b/tests/ui/impl-trait/associated-impl-trait-type-generic-trait.rs @@ -1,4 +1,4 @@ -#![feature(type_alias_impl_trait)] +#![feature(impl_trait_in_assoc_type)] // build-pass (FIXME(62277): could be check-pass?) trait Bar {} diff --git a/tests/ui/impl-trait/associated-impl-trait-type-trivial.rs b/tests/ui/impl-trait/associated-impl-trait-type-trivial.rs index cdda341cad8..b5ea90bb0c7 100644 --- a/tests/ui/impl-trait/associated-impl-trait-type-trivial.rs +++ b/tests/ui/impl-trait/associated-impl-trait-type-trivial.rs @@ -1,4 +1,4 @@ -#![feature(type_alias_impl_trait)] +#![feature(impl_trait_in_assoc_type)] // build-pass (FIXME(62277): could be check-pass?) trait Bar {} diff --git a/tests/ui/impl-trait/associated-impl-trait-type.rs b/tests/ui/impl-trait/associated-impl-trait-type.rs index d0661d66f4b..f5981261c38 100644 --- a/tests/ui/impl-trait/associated-impl-trait-type.rs +++ b/tests/ui/impl-trait/associated-impl-trait-type.rs @@ -1,4 +1,4 @@ -#![feature(type_alias_impl_trait)] +#![feature(impl_trait_in_assoc_type)] // build-pass (FIXME(62277): could be check-pass?) trait Bar {} diff --git a/tests/ui/impl-trait/issue-55872-1.rs b/tests/ui/impl-trait/issue-55872-1.rs index 22ff7ffa23c..f36a310ddf3 100644 --- a/tests/ui/impl-trait/issue-55872-1.rs +++ b/tests/ui/impl-trait/issue-55872-1.rs @@ -1,4 +1,4 @@ -#![feature(type_alias_impl_trait)] +#![feature(impl_trait_in_assoc_type)] pub trait Bar { type E: Copy; diff --git a/tests/ui/impl-trait/issue-55872-2.rs b/tests/ui/impl-trait/issue-55872-2.rs index cbc7b5d62e1..7a5cb3b3dfc 100644 --- a/tests/ui/impl-trait/issue-55872-2.rs +++ b/tests/ui/impl-trait/issue-55872-2.rs @@ -3,7 +3,7 @@ // [drop_tracking_mir] compile-flags: -Zdrop-tracking-mir // edition:2018 -#![feature(type_alias_impl_trait)] +#![feature(impl_trait_in_assoc_type)] pub trait Bar { type E: Send; diff --git a/tests/ui/impl-trait/issue-55872-2.stderr b/tests/ui/impl-trait/issue-55872-2.stderr deleted file mode 100644 index 477c964bd40..00000000000 --- a/tests/ui/impl-trait/issue-55872-2.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias - --> $DIR/issue-55872-2.rs:17:9 - | -LL | async {} - | ^^^^^^^^ - -error: aborting due to previous error - diff --git a/tests/ui/impl-trait/issue-55872-3.rs b/tests/ui/impl-trait/issue-55872-3.rs index 91811df93cd..d031271ac08 100644 --- a/tests/ui/impl-trait/issue-55872-3.rs +++ b/tests/ui/impl-trait/issue-55872-3.rs @@ -1,7 +1,7 @@ // edition:2018 // ignore-compare-mode-chalk -#![feature(type_alias_impl_trait)] +#![feature(impl_trait_in_assoc_type)] pub trait Bar { type E: Copy; diff --git a/tests/ui/impl-trait/issue-55872.rs b/tests/ui/impl-trait/issue-55872.rs index c4e6f643608..10850f0a933 100644 --- a/tests/ui/impl-trait/issue-55872.rs +++ b/tests/ui/impl-trait/issue-55872.rs @@ -1,4 +1,4 @@ -#![feature(type_alias_impl_trait)] +#![feature(impl_trait_in_assoc_type)] pub trait Bar { type E: Copy; diff --git a/tests/ui/impl-trait/issues/issue-82139.rs b/tests/ui/impl-trait/issues/issue-82139.rs index cc9167b340a..3f0b0f1a8de 100644 --- a/tests/ui/impl-trait/issues/issue-82139.rs +++ b/tests/ui/impl-trait/issues/issue-82139.rs @@ -1,4 +1,4 @@ -#![feature(type_alias_impl_trait)] +#![feature(impl_trait_in_assoc_type)] trait Trait { type Associated; diff --git a/tests/ui/impl-trait/issues/issue-83919.rs b/tests/ui/impl-trait/issues/issue-83919.rs index e76443a65db..4e699e7f302 100644 --- a/tests/ui/impl-trait/issues/issue-83919.rs +++ b/tests/ui/impl-trait/issues/issue-83919.rs @@ -1,4 +1,4 @@ -#![feature(type_alias_impl_trait)] +#![feature(impl_trait_in_assoc_type)] // edition:2021 @@ -6,8 +6,8 @@ use std::future::Future; trait Foo { type T; - type Fut2: Future<Output=Self::T>; // ICE got triggered with traits other than Future here - type Fut: Future<Output=Self::Fut2>; + type Fut2: Future<Output = Self::T>; // ICE got triggered with traits other than Future here + type Fut: Future<Output = Self::Fut2>; fn get_fut(&self) -> Self::Fut; } @@ -15,11 +15,11 @@ struct Implementor; impl Foo for Implementor { type T = u64; - type Fut2 = impl Future<Output=u64>; - type Fut = impl Future<Output=Self::Fut2>; + type Fut2 = impl Future<Output = u64>; + type Fut = impl Future<Output = Self::Fut2>; fn get_fut(&self) -> Self::Fut { - //~^ ERROR `{integer}` is not a future + //~^ ERROR `{integer}` is not a future async move { 42 // 42 does not impl Future and rustc does actually point out the error, diff --git a/tests/ui/impl-trait/issues/issue-86719.rs b/tests/ui/impl-trait/issues/issue-86719.rs index f4b0b3f33fc..7abab5bfb75 100644 --- a/tests/ui/impl-trait/issues/issue-86719.rs +++ b/tests/ui/impl-trait/issues/issue-86719.rs @@ -1,11 +1,12 @@ -#![feature(type_alias_impl_trait)] +#![feature(impl_trait_in_assoc_type)] trait Bar { type E; } impl<S> Bar for S { type E = impl ; //~ ERROR at least one trait must be specified - fn foo() -> Self::E { //~ ERROR `foo` is not a member + fn foo() -> Self::E { + //~^ ERROR `foo` is not a member |_| true //~ ERROR type annotations needed } } diff --git a/tests/ui/impl-trait/issues/issue-86719.stderr b/tests/ui/impl-trait/issues/issue-86719.stderr index 7592418fdfd..15893df5f94 100644 --- a/tests/ui/impl-trait/issues/issue-86719.stderr +++ b/tests/ui/impl-trait/issues/issue-86719.stderr @@ -8,12 +8,13 @@ error[E0407]: method `foo` is not a member of trait `Bar` --> $DIR/issue-86719.rs:8:5 | LL | / fn foo() -> Self::E { +LL | | LL | | |_| true LL | | } | |_____^ not a member of trait `Bar` error[E0282]: type annotations needed - --> $DIR/issue-86719.rs:9:10 + --> $DIR/issue-86719.rs:10:10 | LL | |_| true | ^ diff --git a/tests/ui/impl-trait/issues/issue-87340.rs b/tests/ui/impl-trait/issues/issue-87340.rs index f0f6d2bb61c..705a4addcb7 100644 --- a/tests/ui/impl-trait/issues/issue-87340.rs +++ b/tests/ui/impl-trait/issues/issue-87340.rs @@ -1,4 +1,4 @@ -#![feature(type_alias_impl_trait)] +#![feature(impl_trait_in_assoc_type)] trait X { type I; @@ -6,7 +6,7 @@ trait X { } impl<T> X for () { -//~^ ERROR `T` is not constrained by the impl trait, self type, or predicates + //~^ ERROR `T` is not constrained by the impl trait, self type, or predicates type I = impl Sized; fn f() -> Self::I {} } diff --git a/tests/ui/impl-trait/no-method-suggested-traits.stderr b/tests/ui/impl-trait/no-method-suggested-traits.stderr index 3c2c01dc227..160cc044078 100644 --- a/tests/ui/impl-trait/no-method-suggested-traits.stderr +++ b/tests/ui/impl-trait/no-method-suggested-traits.stderr @@ -7,13 +7,13 @@ LL | 1u32.method(); = help: items from traits can only be used if the trait is in scope help: the following traits are implemented but not in scope; perhaps add a `use` for one of them: | -LL | use foo::Bar; +LL + use foo::Bar; | -LL | use no_method_suggested_traits::Reexported; +LL + use no_method_suggested_traits::Reexported; | -LL | use no_method_suggested_traits::foo::PubPub; +LL + use no_method_suggested_traits::foo::PubPub; | -LL | use no_method_suggested_traits::qux::PrivPub; +LL + use no_method_suggested_traits::qux::PrivPub; | error[E0599]: no method named `method` found for struct `Rc<&mut Box<&u32>>` in the current scope @@ -25,13 +25,13 @@ LL | std::rc::Rc::new(&mut Box::new(&1u32)).method(); = help: items from traits can only be used if the trait is in scope help: the following traits are implemented but not in scope; perhaps add a `use` for one of them: | -LL | use foo::Bar; +LL + use foo::Bar; | -LL | use no_method_suggested_traits::Reexported; +LL + use no_method_suggested_traits::Reexported; | -LL | use no_method_suggested_traits::foo::PubPub; +LL + use no_method_suggested_traits::foo::PubPub; | -LL | use no_method_suggested_traits::qux::PrivPub; +LL + use no_method_suggested_traits::qux::PrivPub; | error[E0599]: no method named `method` found for type `char` in the current scope @@ -46,7 +46,7 @@ LL | 'a'.method(); = help: items from traits can only be used if the trait is in scope help: the following trait is implemented but not in scope; perhaps add a `use` for it: | -LL | use foo::Bar; +LL + use foo::Bar; | error[E0599]: no method named `method` found for struct `Rc<&mut Box<&char>>` in the current scope @@ -58,7 +58,7 @@ LL | std::rc::Rc::new(&mut Box::new(&'a')).method(); = help: items from traits can only be used if the trait is in scope help: the following trait is implemented but not in scope; perhaps add a `use` for it: | -LL | use foo::Bar; +LL + use foo::Bar; | error[E0599]: no method named `method` found for type `i32` in the current scope @@ -75,7 +75,7 @@ LL | fn method(&self) {} = help: items from traits can only be used if the trait is in scope help: the following trait is implemented but not in scope; perhaps add a `use` for it: | -LL | use no_method_suggested_traits::foo::PubPub; +LL + use no_method_suggested_traits::foo::PubPub; | error[E0599]: no method named `method` found for struct `Rc<&mut Box<&i32>>` in the current scope @@ -87,7 +87,7 @@ LL | std::rc::Rc::new(&mut Box::new(&1i32)).method(); = help: items from traits can only be used if the trait is in scope help: the following trait is implemented but not in scope; perhaps add a `use` for it: | -LL | use no_method_suggested_traits::foo::PubPub; +LL + use no_method_suggested_traits::foo::PubPub; | error[E0599]: no method named `method` found for struct `Foo` in the current scope diff --git a/tests/ui/impl-trait/type-alias-generic-param.rs b/tests/ui/impl-trait/type-alias-generic-param.rs index 3499b285926..1211625dac9 100644 --- a/tests/ui/impl-trait/type-alias-generic-param.rs +++ b/tests/ui/impl-trait/type-alias-generic-param.rs @@ -3,7 +3,7 @@ // types in 'item' position when generic parameters are involved // // run-pass -#![feature(type_alias_impl_trait)] +#![feature(impl_trait_in_assoc_type)] trait Meow { type MeowType; diff --git a/tests/ui/impl-trait/universal_wrong_bounds.stderr b/tests/ui/impl-trait/universal_wrong_bounds.stderr index 3b1a5e5f4ad..464d689589e 100644 --- a/tests/ui/impl-trait/universal_wrong_bounds.stderr +++ b/tests/ui/impl-trait/universal_wrong_bounds.stderr @@ -6,7 +6,7 @@ LL | fn wants_debug(g: impl Debug) { } | help: consider importing this trait instead | -LL | use std::fmt::Debug; +LL + use std::fmt::Debug; | error[E0404]: expected trait, found derive macro `Debug` @@ -17,7 +17,7 @@ LL | fn wants_display(g: impl Debug) { } | help: consider importing this trait instead | -LL | use std::fmt::Debug; +LL + use std::fmt::Debug; | error: aborting due to 2 previous errors diff --git a/tests/ui/impl-trait/where-allowed.rs b/tests/ui/impl-trait/where-allowed.rs index ff63b04c268..509d2716649 100644 --- a/tests/ui/impl-trait/where-allowed.rs +++ b/tests/ui/impl-trait/where-allowed.rs @@ -1,6 +1,8 @@ //! A simple test for testing many permutations of allowedness of //! impl Trait #![feature(impl_trait_in_fn_trait_return)] +#![feature(custom_inner_attributes)] +#![rustfmt::skip] use std::fmt::Debug; // Allowed @@ -116,7 +118,7 @@ trait DummyTrait { } impl DummyTrait for () { type Out = impl Debug; - //~^ ERROR `impl Trait` in type aliases is unstable + //~^ ERROR `impl Trait` in associated types is unstable fn in_trait_impl_parameter(_: impl Debug) { } // Allowed diff --git a/tests/ui/impl-trait/where-allowed.stderr b/tests/ui/impl-trait/where-allowed.stderr index 1cae3f77cc5..3e293437975 100644 --- a/tests/ui/impl-trait/where-allowed.stderr +++ b/tests/ui/impl-trait/where-allowed.stderr @@ -1,5 +1,5 @@ error[E0666]: nested `impl Trait` is not allowed - --> $DIR/where-allowed.rs:47:51 + --> $DIR/where-allowed.rs:49:51 | LL | fn in_impl_Fn_parameter_in_parameters(_: &impl Fn(impl Debug)) { panic!() } | --------^^^^^^^^^^- @@ -8,7 +8,7 @@ LL | fn in_impl_Fn_parameter_in_parameters(_: &impl Fn(impl Debug)) { panic!() } | outer `impl Trait` error[E0666]: nested `impl Trait` is not allowed - --> $DIR/where-allowed.rs:56:57 + --> $DIR/where-allowed.rs:58:57 | LL | fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic!() } | --------^^^^^^^^^^- @@ -16,17 +16,17 @@ LL | fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic | | nested `impl Trait` here | outer `impl Trait` -error[E0658]: `impl Trait` in type aliases is unstable - --> $DIR/where-allowed.rs:118:16 +error[E0658]: `impl Trait` in associated types is unstable + --> $DIR/where-allowed.rs:120:16 | LL | type Out = impl Debug; | ^^^^^^^^^^ | = note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information - = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable + = help: add `#![feature(impl_trait_in_assoc_type)]` to the crate attributes to enable error[E0658]: `impl Trait` in type aliases is unstable - --> $DIR/where-allowed.rs:153:23 + --> $DIR/where-allowed.rs:155:23 | LL | type InTypeAlias<R> = impl Debug; | ^^^^^^^^^^ @@ -35,7 +35,7 @@ LL | type InTypeAlias<R> = impl Debug; = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable error[E0658]: `impl Trait` in type aliases is unstable - --> $DIR/where-allowed.rs:156:39 + --> $DIR/where-allowed.rs:158:39 | LL | type InReturnInTypeAlias<R> = fn() -> impl Debug; | ^^^^^^^^^^ @@ -44,109 +44,109 @@ LL | type InReturnInTypeAlias<R> = fn() -> impl Debug; = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer params - --> $DIR/where-allowed.rs:16:40 + --> $DIR/where-allowed.rs:18:40 | LL | fn in_fn_parameter_in_parameters(_: fn(impl Debug)) { panic!() } | ^^^^^^^^^^ error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer return types - --> $DIR/where-allowed.rs:20:42 + --> $DIR/where-allowed.rs:22:42 | LL | fn in_fn_return_in_parameters(_: fn() -> impl Debug) { panic!() } | ^^^^^^^^^^ error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer params - --> $DIR/where-allowed.rs:24:38 + --> $DIR/where-allowed.rs:26:38 | LL | fn in_fn_parameter_in_return() -> fn(impl Debug) { panic!() } | ^^^^^^^^^^ error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer return types - --> $DIR/where-allowed.rs:28:40 + --> $DIR/where-allowed.rs:30:40 | LL | fn in_fn_return_in_return() -> fn() -> impl Debug { panic!() } | ^^^^^^^^^^ error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait params - --> $DIR/where-allowed.rs:32:49 + --> $DIR/where-allowed.rs:34:49 | LL | fn in_dyn_Fn_parameter_in_parameters(_: &dyn Fn(impl Debug)) { panic!() } | ^^^^^^^^^^ error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return types - --> $DIR/where-allowed.rs:36:51 + --> $DIR/where-allowed.rs:38:51 | LL | fn in_dyn_Fn_return_in_parameters(_: &dyn Fn() -> impl Debug) { panic!() } | ^^^^^^^^^^ error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait params - --> $DIR/where-allowed.rs:40:55 + --> $DIR/where-allowed.rs:42:55 | LL | fn in_dyn_Fn_parameter_in_return() -> &'static dyn Fn(impl Debug) { panic!() } | ^^^^^^^^^^ error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait params - --> $DIR/where-allowed.rs:47:51 + --> $DIR/where-allowed.rs:49:51 | LL | fn in_impl_Fn_parameter_in_parameters(_: &impl Fn(impl Debug)) { panic!() } | ^^^^^^^^^^ error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return types - --> $DIR/where-allowed.rs:52:53 + --> $DIR/where-allowed.rs:54:53 | LL | fn in_impl_Fn_return_in_parameters(_: &impl Fn() -> impl Debug) { panic!() } | ^^^^^^^^^^ error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait params - --> $DIR/where-allowed.rs:56:57 + --> $DIR/where-allowed.rs:58:57 | LL | fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic!() } | ^^^^^^^^^^ error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait params - --> $DIR/where-allowed.rs:64:38 + --> $DIR/where-allowed.rs:66:38 | LL | fn in_Fn_parameter_in_generics<F: Fn(impl Debug)> (_: F) { panic!() } | ^^^^^^^^^^ error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return types - --> $DIR/where-allowed.rs:68:40 + --> $DIR/where-allowed.rs:70:40 | LL | fn in_Fn_return_in_generics<F: Fn() -> impl Debug> (_: F) { panic!() } | ^^^^^^^^^^ error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in field types - --> $DIR/where-allowed.rs:81:32 + --> $DIR/where-allowed.rs:83:32 | LL | struct InBraceStructField { x: impl Debug } | ^^^^^^^^^^ error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in field types - --> $DIR/where-allowed.rs:85:41 + --> $DIR/where-allowed.rs:87:41 | LL | struct InAdtInBraceStructField { x: Vec<impl Debug> } | ^^^^^^^^^^ error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in field types - --> $DIR/where-allowed.rs:89:27 + --> $DIR/where-allowed.rs:91:27 | LL | struct InTupleStructField(impl Debug); | ^^^^^^^^^^ error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in field types - --> $DIR/where-allowed.rs:94:25 + --> $DIR/where-allowed.rs:96:25 | LL | InBraceVariant { x: impl Debug }, | ^^^^^^^^^^ error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in field types - --> $DIR/where-allowed.rs:96:20 + --> $DIR/where-allowed.rs:98:20 | LL | InTupleVariant(impl Debug), | ^^^^^^^^^^ error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in trait method return types - --> $DIR/where-allowed.rs:107:23 + --> $DIR/where-allowed.rs:109:23 | LL | fn in_return() -> impl Debug; | ^^^^^^^^^^ @@ -155,7 +155,7 @@ LL | fn in_return() -> impl Debug; = help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `impl` method return types - --> $DIR/where-allowed.rs:124:34 + --> $DIR/where-allowed.rs:126:34 | LL | fn in_trait_impl_return() -> impl Debug { () } | ^^^^^^^^^^ @@ -164,127 +164,127 @@ LL | fn in_trait_impl_return() -> impl Debug { () } = help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `extern fn` params - --> $DIR/where-allowed.rs:137:33 + --> $DIR/where-allowed.rs:139:33 | LL | fn in_foreign_parameters(_: impl Debug); | ^^^^^^^^^^ error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `extern fn` return types - --> $DIR/where-allowed.rs:140:31 + --> $DIR/where-allowed.rs:142:31 | LL | fn in_foreign_return() -> impl Debug; | ^^^^^^^^^^ error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer return types - --> $DIR/where-allowed.rs:156:39 + --> $DIR/where-allowed.rs:158:39 | LL | type InReturnInTypeAlias<R> = fn() -> impl Debug; | ^^^^^^^^^^ error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in traits - --> $DIR/where-allowed.rs:161:16 + --> $DIR/where-allowed.rs:163:16 | LL | impl PartialEq<impl Debug> for () { | ^^^^^^^^^^ error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in impl headers - --> $DIR/where-allowed.rs:166:24 + --> $DIR/where-allowed.rs:168:24 | LL | impl PartialEq<()> for impl Debug { | ^^^^^^^^^^ error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in impl headers - --> $DIR/where-allowed.rs:171:6 + --> $DIR/where-allowed.rs:173:6 | LL | impl impl Debug { | ^^^^^^^^^^ error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in impl headers - --> $DIR/where-allowed.rs:177:24 + --> $DIR/where-allowed.rs:179:24 | LL | impl InInherentImplAdt<impl Debug> { | ^^^^^^^^^^ error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in bounds - --> $DIR/where-allowed.rs:183:11 + --> $DIR/where-allowed.rs:185:11 | LL | where impl Debug: Debug | ^^^^^^^^^^ error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in bounds - --> $DIR/where-allowed.rs:190:15 + --> $DIR/where-allowed.rs:192:15 | LL | where Vec<impl Debug>: Debug | ^^^^^^^^^^ error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in bounds - --> $DIR/where-allowed.rs:197:24 + --> $DIR/where-allowed.rs:199:24 | LL | where T: PartialEq<impl Debug> | ^^^^^^^^^^ error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait params - --> $DIR/where-allowed.rs:204:17 + --> $DIR/where-allowed.rs:206:17 | LL | where T: Fn(impl Debug) | ^^^^^^^^^^ error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return types - --> $DIR/where-allowed.rs:211:22 + --> $DIR/where-allowed.rs:213:22 | LL | where T: Fn() -> impl Debug | ^^^^^^^^^^ error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter defaults - --> $DIR/where-allowed.rs:217:40 + --> $DIR/where-allowed.rs:219:40 | LL | struct InStructGenericParamDefault<T = impl Debug>(T); | ^^^^^^^^^^ error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter defaults - --> $DIR/where-allowed.rs:221:36 + --> $DIR/where-allowed.rs:223:36 | LL | enum InEnumGenericParamDefault<T = impl Debug> { Variant(T) } | ^^^^^^^^^^ error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter defaults - --> $DIR/where-allowed.rs:225:38 + --> $DIR/where-allowed.rs:227:38 | LL | trait InTraitGenericParamDefault<T = impl Debug> {} | ^^^^^^^^^^ error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter defaults - --> $DIR/where-allowed.rs:229:41 + --> $DIR/where-allowed.rs:231:41 | LL | type InTypeAliasGenericParamDefault<T = impl Debug> = T; | ^^^^^^^^^^ error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter defaults - --> $DIR/where-allowed.rs:233:11 + --> $DIR/where-allowed.rs:235:11 | LL | impl <T = impl Debug> T {} | ^^^^^^^^^^ error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter defaults - --> $DIR/where-allowed.rs:240:40 + --> $DIR/where-allowed.rs:242:40 | LL | fn in_method_generic_param_default<T = impl Debug>(_: T) {} | ^^^^^^^^^^ error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable bindings - --> $DIR/where-allowed.rs:246:29 + --> $DIR/where-allowed.rs:248:29 | LL | let _in_local_variable: impl Fn() = || {}; | ^^^^^^^^^ error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in closure return types - --> $DIR/where-allowed.rs:248:46 + --> $DIR/where-allowed.rs:250:46 | LL | let _in_return_in_local_variable = || -> impl Fn() { || {} }; | ^^^^^^^^^ error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions - --> $DIR/where-allowed.rs:233:7 + --> $DIR/where-allowed.rs:235:7 | LL | impl <T = impl Debug> T {} | ^^^^^^^^^^^^^^ @@ -294,7 +294,7 @@ LL | impl <T = impl Debug> T {} = note: `#[deny(invalid_type_param_default)]` on by default error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions - --> $DIR/where-allowed.rs:240:36 + --> $DIR/where-allowed.rs:242:36 | LL | fn in_method_generic_param_default<T = impl Debug>(_: T) {} | ^^^^^^^^^^^^^^ @@ -303,7 +303,7 @@ LL | fn in_method_generic_param_default<T = impl Debug>(_: T) {} = note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887> error[E0118]: no nominal type found for inherent implementation - --> $DIR/where-allowed.rs:233:1 + --> $DIR/where-allowed.rs:235:1 | LL | impl <T = impl Debug> T {} | ^^^^^^^^^^^^^^^^^^^^^^^ impl requires a nominal type diff --git a/tests/ui/imports/glob-resolve1.stderr b/tests/ui/imports/glob-resolve1.stderr index 3b66a5e3150..4401ef58732 100644 --- a/tests/ui/imports/glob-resolve1.stderr +++ b/tests/ui/imports/glob-resolve1.stderr @@ -60,7 +60,7 @@ LL | import(); | help: consider importing this function | -LL | use other::import; +LL + use other::import; | error[E0412]: cannot find type `A` in this scope diff --git a/tests/ui/imports/issue-38293.stderr b/tests/ui/imports/issue-38293.stderr index d2450ab1250..1bb7ae29e10 100644 --- a/tests/ui/imports/issue-38293.stderr +++ b/tests/ui/imports/issue-38293.stderr @@ -12,7 +12,7 @@ LL | baz(); | help: consider importing this function instead | -LL | use bar::baz; +LL + use bar::baz; | error: aborting due to 2 previous errors diff --git a/tests/ui/imports/issue-4366-2.stderr b/tests/ui/imports/issue-4366-2.stderr index 4c94634ee60..412423f4d59 100644 --- a/tests/ui/imports/issue-4366-2.stderr +++ b/tests/ui/imports/issue-4366-2.stderr @@ -18,7 +18,7 @@ LL | foo(); | help: consider importing this function instead | -LL | use foo::foo; +LL + use foo::foo; | error: aborting due to 2 previous errors diff --git a/tests/ui/imports/issue-4366.stderr b/tests/ui/imports/issue-4366.stderr index 469ea93e904..4d5b392a7e1 100644 --- a/tests/ui/imports/issue-4366.stderr +++ b/tests/ui/imports/issue-4366.stderr @@ -6,7 +6,7 @@ LL | fn sub() -> isize { foo(); 1 } | help: consider importing this function | -LL | use foo::foo; +LL + use foo::foo; | error: aborting due to previous error diff --git a/tests/ui/imports/overlapping_pub_trait.stderr b/tests/ui/imports/overlapping_pub_trait.stderr index d0c845a5e52..490dccd3e80 100644 --- a/tests/ui/imports/overlapping_pub_trait.stderr +++ b/tests/ui/imports/overlapping_pub_trait.stderr @@ -12,7 +12,7 @@ LL | pub trait Tr { fn method(&self); } = help: items from traits can only be used if the trait is in scope help: the following trait is implemented but not in scope; perhaps add a `use` for it: | -LL | use overlapping_pub_trait_source::m::Tr; +LL + use overlapping_pub_trait_source::m::Tr; | error: aborting due to previous error diff --git a/tests/ui/imports/unnamed_pub_trait.stderr b/tests/ui/imports/unnamed_pub_trait.stderr index 319dfd7e1b2..5133273c22f 100644 --- a/tests/ui/imports/unnamed_pub_trait.stderr +++ b/tests/ui/imports/unnamed_pub_trait.stderr @@ -12,7 +12,7 @@ LL | pub trait Tr { fn method(&self); } = help: items from traits can only be used if the trait is in scope help: the following trait is implemented but not in scope; perhaps add a `use` for it: | -LL | use unnamed_pub_trait_source::prelude::*; // trait Tr +LL + use unnamed_pub_trait_source::prelude::*; // trait Tr | error: aborting due to previous error diff --git a/tests/ui/internal/internal-unstable-const.stderr b/tests/ui/internal/internal-unstable-const.stderr index 37d2ea6d2dc..5c63992d819 100644 --- a/tests/ui/internal/internal-unstable-const.stderr +++ b/tests/ui/internal/internal-unstable-const.stderr @@ -6,11 +6,13 @@ LL | 1.0 + 1.0 | help: if it is not part of the public API, make this function unstably const | -LL | #[rustc_const_unstable(feature = "...", issue = "...")] +LL + #[rustc_const_unstable(feature = "...", issue = "...")] +LL | pub const fn foo() -> f32 { | help: otherwise `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks | -LL | #[rustc_allow_const_fn_unstable(const_fn_floating_point_arithmetic)] +LL + #[rustc_allow_const_fn_unstable(const_fn_floating_point_arithmetic)] +LL | pub const fn foo() -> f32 { | error: aborting due to previous error diff --git a/tests/ui/issues/issue-10465.stderr b/tests/ui/issues/issue-10465.stderr index 0ccf69dc060..1b7b9d5909e 100644 --- a/tests/ui/issues/issue-10465.stderr +++ b/tests/ui/issues/issue-10465.stderr @@ -7,7 +7,7 @@ LL | b.foo(); = help: items from traits can only be used if the trait is in scope help: the following trait is implemented but not in scope; perhaps add a `use` for it: | -LL | use a::A; +LL + use a::A; | error: aborting due to previous error diff --git a/tests/ui/issues/issue-17546.stderr b/tests/ui/issues/issue-17546.stderr index 81592320a27..cf7ed1bbd66 100644 --- a/tests/ui/issues/issue-17546.stderr +++ b/tests/ui/issues/issue-17546.stderr @@ -24,13 +24,13 @@ LL | fn new() -> Result<foo::MyEnum, String> { | help: consider importing one of these items instead | -LL | use std::fmt::Result; +LL + use std::fmt::Result; | -LL | use std::io::Result; +LL + use std::io::Result; | -LL | use std::result::Result; +LL + use std::result::Result; | -LL | use std::thread::Result; +LL + use std::thread::Result; | error[E0573]: expected type, found variant `Result` @@ -41,13 +41,13 @@ LL | fn new() -> Result<foo::MyEnum, String> { | help: consider importing one of these items instead | -LL | use std::fmt::Result; +LL + use std::fmt::Result; | -LL | use std::io::Result; +LL + use std::io::Result; | -LL | use std::result::Result; +LL + use std::result::Result; | -LL | use std::thread::Result; +LL + use std::thread::Result; | error[E0573]: expected type, found variant `NoResult` diff --git a/tests/ui/issues/issue-20162.stderr b/tests/ui/issues/issue-20162.stderr index 1c5b76fbfc1..ebdf2528fe1 100644 --- a/tests/ui/issues/issue-20162.stderr +++ b/tests/ui/issues/issue-20162.stderr @@ -8,7 +8,8 @@ note: required by a bound in `slice::<impl [T]>::sort` --> $SRC_DIR/alloc/src/slice.rs:LL:COL help: consider annotating `X` with `#[derive(Ord)]` | -LL | #[derive(Ord)] +LL + #[derive(Ord)] +LL | struct X { x: i32 } | error: aborting due to previous error diff --git a/tests/ui/issues/issue-21160.stderr b/tests/ui/issues/issue-21160.stderr index 266749376eb..b39a3aad371 100644 --- a/tests/ui/issues/issue-21160.stderr +++ b/tests/ui/issues/issue-21160.stderr @@ -9,7 +9,8 @@ LL | struct Foo(Bar); = note: this error originates in the derive macro `Hash` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider annotating `Bar` with `#[derive(Hash)]` | -LL | #[derive(Hash)] +LL + #[derive(Hash)] +LL | struct Bar; | error: aborting due to previous error diff --git a/tests/ui/issues/issue-35976.unimported.stderr b/tests/ui/issues/issue-35976.unimported.stderr index 5d61bb8ea37..b31d2a31551 100644 --- a/tests/ui/issues/issue-35976.unimported.stderr +++ b/tests/ui/issues/issue-35976.unimported.stderr @@ -9,7 +9,7 @@ LL | arg.wait(); | help: another candidate was found in the following trait, perhaps add a `use` for it: | -LL | use private::Future; +LL + use private::Future; | error: aborting due to previous error diff --git a/tests/ui/issues/issue-37534.stderr b/tests/ui/issues/issue-37534.stderr index 895479986f1..7d3dd8800bd 100644 --- a/tests/ui/issues/issue-37534.stderr +++ b/tests/ui/issues/issue-37534.stderr @@ -6,7 +6,7 @@ LL | struct Foo<T: ?Hash> { } | help: consider importing this trait instead | -LL | use std::hash::Hash; +LL + use std::hash::Hash; | warning: default bound relaxed for a type parameter, but this does nothing because the given bound is not a default; only `?Sized` is supported diff --git a/tests/ui/issues/issue-39175.stderr b/tests/ui/issues/issue-39175.stderr index afceae82e68..3a1476ac0e3 100644 --- a/tests/ui/issues/issue-39175.stderr +++ b/tests/ui/issues/issue-39175.stderr @@ -7,7 +7,7 @@ LL | Command::new("echo").arg("hello").exec(); = help: items from traits can only be used if the trait is in scope help: the following trait is implemented but not in scope; perhaps add a `use` for it: | -LL | use std::os::unix::process::CommandExt; +LL + use std::os::unix::process::CommandExt; | error: aborting due to previous error diff --git a/tests/ui/issues/issue-56175.stderr b/tests/ui/issues/issue-56175.stderr index 013a440ed04..1ddee1f4895 100644 --- a/tests/ui/issues/issue-56175.stderr +++ b/tests/ui/issues/issue-56175.stderr @@ -12,7 +12,7 @@ LL | fn trait_method(&self) { = help: items from traits can only be used if the trait is in scope help: the following trait is implemented but not in scope; perhaps add a `use` for it: | -LL | use reexported_trait::Trait; +LL + use reexported_trait::Trait; | error[E0599]: no method named `trait_method_b` found for struct `FooStruct` in the current scope @@ -29,7 +29,7 @@ LL | fn trait_method_b(&self) { = help: items from traits can only be used if the trait is in scope help: the following trait is implemented but not in scope; perhaps add a `use` for it: | -LL | use reexported_trait::TraitBRename; +LL + use reexported_trait::TraitBRename; | error: aborting due to 2 previous errors diff --git a/tests/ui/issues/issue-62375.stderr b/tests/ui/issues/issue-62375.stderr index 478e025bed2..a6fd3700edd 100644 --- a/tests/ui/issues/issue-62375.stderr +++ b/tests/ui/issues/issue-62375.stderr @@ -13,7 +13,8 @@ LL | enum A { | ^^^^^^ must implement `PartialEq<_>` help: consider annotating `A` with `#[derive(PartialEq)]` | -LL | #[derive(PartialEq)] +LL + #[derive(PartialEq)] +LL | enum A { | error: aborting due to previous error diff --git a/tests/ui/issues/issue-77919.stderr b/tests/ui/issues/issue-77919.stderr index d154bfe0cb5..d6dcc8997b9 100644 --- a/tests/ui/issues/issue-77919.stderr +++ b/tests/ui/issues/issue-77919.stderr @@ -6,7 +6,7 @@ LL | _n: PhantomData, | help: consider importing this struct | -LL | use std::marker::PhantomData; +LL + use std::marker::PhantomData; | error[E0412]: cannot find type `VAL` in this scope diff --git a/tests/ui/kindck/kindck-impl-type-params.stderr b/tests/ui/kindck/kindck-impl-type-params.stderr index 6fd1fc3f7a1..efb25bf83e1 100644 --- a/tests/ui/kindck/kindck-impl-type-params.stderr +++ b/tests/ui/kindck/kindck-impl-type-params.stderr @@ -107,7 +107,8 @@ LL | impl<T: Send + Copy + 'static> Gettable<T> for S<T> {} = note: required for the cast from `S<Foo>` to the object type `dyn Gettable<Foo>` help: consider annotating `Foo` with `#[derive(Copy)]` | -LL | #[derive(Copy)] +LL + #[derive(Copy)] +LL | struct Foo; // does not impl Copy | error: aborting due to 6 previous errors diff --git a/tests/ui/layout/issue-84108.stderr b/tests/ui/layout/issue-84108.stderr index 36be6424110..5ad450bed07 100644 --- a/tests/ui/layout/issue-84108.stderr +++ b/tests/ui/layout/issue-84108.stderr @@ -6,7 +6,7 @@ LL | static FOO: (dyn AsRef<OsStr>, u8) = ("hello", 42); | help: consider importing this struct | -LL | use std::ffi::OsStr; +LL + use std::ffi::OsStr; | error[E0412]: cannot find type `Path` in this scope @@ -17,7 +17,7 @@ LL | const BAR: (&Path, [u8], usize) = ("hello", [], 42); | help: consider importing this struct | -LL | use std::path::Path; +LL + use std::path::Path; | error[E0277]: the size for values of type `[u8]` cannot be known at compilation time diff --git a/tests/ui/lexer/issue-108019-bad-emoji-recovery.rs b/tests/ui/lexer/issue-108019-bad-emoji-recovery.rs deleted file mode 100644 index f0f86224560..00000000000 --- a/tests/ui/lexer/issue-108019-bad-emoji-recovery.rs +++ /dev/null @@ -1,45 +0,0 @@ -#![allow(unused_labels)] - -// FIXME(#108019): outdated Unicode table -// fn foo() { -// '🥺 loop { -// break -// } -// } - -fn bar() { - '🐱 loop { - //~^ ERROR labeled expression must be followed by `:` - //~| ERROR lifetimes or labels cannot contain emojis - break - } -} - -fn qux() { - 'a🐱 loop { - //~^ ERROR labeled expression must be followed by `:` - //~| ERROR lifetimes or labels cannot contain emojis - break - } -} - -fn quux() { - '1🐱 loop { - //~^ ERROR labeled expression must be followed by `:` - //~| ERROR lifetimes or labels cannot start with a number - break - } -} - -fn x<'🐱>() -> &'🐱 () { - //~^ ERROR lifetimes or labels cannot contain emojis - //~| ERROR lifetimes or labels cannot contain emojis - &() -} - -fn y() { - 'a🐱: loop {} - //~^ ERROR lifetimes or labels cannot contain emojis -} - -fn main() {} diff --git a/tests/ui/lexer/issue-108019-bad-emoji-recovery.stderr b/tests/ui/lexer/issue-108019-bad-emoji-recovery.stderr deleted file mode 100644 index be77ffdea34..00000000000 --- a/tests/ui/lexer/issue-108019-bad-emoji-recovery.stderr +++ /dev/null @@ -1,86 +0,0 @@ -error: labeled expression must be followed by `:` - --> $DIR/issue-108019-bad-emoji-recovery.rs:11:5 - | -LL | '🐱 loop { - | ^--- help: add `:` after the label - | | - | _____the label - | | -LL | | -LL | | -LL | | break -LL | | } - | |_____^ - | - = note: labels are used before loops and blocks, allowing e.g., `break 'label` to them - -error: labeled expression must be followed by `:` - --> $DIR/issue-108019-bad-emoji-recovery.rs:19:5 - | -LL | 'a🐱 loop { - | ^---- help: add `:` after the label - | | - | _____the label - | | -LL | | -LL | | -LL | | break -LL | | } - | |_____^ - | - = note: labels are used before loops and blocks, allowing e.g., `break 'label` to them - -error: labeled expression must be followed by `:` - --> $DIR/issue-108019-bad-emoji-recovery.rs:27:5 - | -LL | '1🐱 loop { - | ^---- help: add `:` after the label - | | - | _____the label - | | -LL | | -LL | | -LL | | break -LL | | } - | |_____^ - | - = note: labels are used before loops and blocks, allowing e.g., `break 'label` to them - -error: lifetimes or labels cannot contain emojis - --> $DIR/issue-108019-bad-emoji-recovery.rs:11:5 - | -LL | '🐱 loop { - | ^^^ - -error: lifetimes or labels cannot contain emojis - --> $DIR/issue-108019-bad-emoji-recovery.rs:19:5 - | -LL | 'a🐱 loop { - | ^^^^ - -error: lifetimes or labels cannot start with a number - --> $DIR/issue-108019-bad-emoji-recovery.rs:27:5 - | -LL | '1🐱 loop { - | ^^^^ - -error: lifetimes or labels cannot contain emojis - --> $DIR/issue-108019-bad-emoji-recovery.rs:34:6 - | -LL | fn x<'🐱>() -> &'🐱 () { - | ^^^ - -error: lifetimes or labels cannot contain emojis - --> $DIR/issue-108019-bad-emoji-recovery.rs:34:16 - | -LL | fn x<'🐱>() -> &'🐱 () { - | ^^^ - -error: lifetimes or labels cannot contain emojis - --> $DIR/issue-108019-bad-emoji-recovery.rs:41:5 - | -LL | 'a🐱: loop {} - | ^^^^ - -error: aborting due to 9 previous errors - diff --git a/tests/ui/lint/dead-code/issue-59003.rs b/tests/ui/lint/dead-code/issue-59003.rs new file mode 100644 index 00000000000..966d6412870 --- /dev/null +++ b/tests/ui/lint/dead-code/issue-59003.rs @@ -0,0 +1,18 @@ +// check-pass + +// Make sure we don't have any false positives about the "struct is never constructed" lint. + +#![deny(dead_code)] + +struct Foo { + #[allow(dead_code)] + inner: u32, +} + +impl From<u32> for Foo { + fn from(inner: u32) -> Self { + Self { inner } + } +} + +fn main() {} diff --git a/tests/ui/lint/inline-trait-and-foreign-items.rs b/tests/ui/lint/inline-trait-and-foreign-items.rs index 13dab7ed954..39bc01f71b5 100644 --- a/tests/ui/lint/inline-trait-and-foreign-items.rs +++ b/tests/ui/lint/inline-trait-and-foreign-items.rs @@ -1,5 +1,5 @@ #![feature(extern_types)] -#![feature(type_alias_impl_trait)] +#![feature(impl_trait_in_assoc_type)] #![warn(unused_attributes)] diff --git a/tests/ui/lint/no-coverage.rs b/tests/ui/lint/no-coverage.rs index ff24c12b2bc..07906a43472 100644 --- a/tests/ui/lint/no-coverage.rs +++ b/tests/ui/lint/no-coverage.rs @@ -1,6 +1,6 @@ #![feature(extern_types)] #![feature(no_coverage)] -#![feature(type_alias_impl_trait)] +#![feature(impl_trait_in_assoc_type)] #![warn(unused_attributes)] #![no_coverage] //~^ WARN: `#[no_coverage]` does not propagate into items and must be applied to the contained functions directly diff --git a/tests/ui/macros/issue-100199.stderr b/tests/ui/macros/issue-100199.stderr index 2cb45dc1247..89a6f585ce4 100644 --- a/tests/ui/macros/issue-100199.stderr +++ b/tests/ui/macros/issue-100199.stderr @@ -7,7 +7,7 @@ LL | #[issue_100199::struct_with_bound] = note: this error originates in the attribute macro `issue_100199::struct_with_bound` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider importing this trait | -LL | use traits::MyTrait; +LL + use traits::MyTrait; | error: aborting due to previous error diff --git a/tests/ui/macros/macro-outer-attributes.stderr b/tests/ui/macros/macro-outer-attributes.stderr index 4ea760ab82b..0bdc3416f80 100644 --- a/tests/ui/macros/macro-outer-attributes.stderr +++ b/tests/ui/macros/macro-outer-attributes.stderr @@ -6,7 +6,7 @@ LL | a::bar(); | help: consider importing this function | -LL | use b::bar; +LL + use b::bar; | help: if you import `bar`, refer to it directly | diff --git a/tests/ui/macros/nonterminal-matching.stderr b/tests/ui/macros/nonterminal-matching.stderr index 762ecc3207f..c2b047022ed 100644 --- a/tests/ui/macros/nonterminal-matching.stderr +++ b/tests/ui/macros/nonterminal-matching.stderr @@ -18,7 +18,9 @@ LL | macro n(a $nt_item b) { ... LL | complex_nonterminal!(enum E {}); | ------------------------------- in this macro invocation - = note: captured metavariables except for `$tt`, `$ident` and `$lifetime` cannot be compared to other tokens + = note: captured metavariables except for `:tt`, `:ident` and `:lifetime` cannot be compared to other tokens + = note: see <https://doc.rust-lang.org/nightly/reference/macros-by-example.html#forwarding-a-matched-fragment> for more information + = help: try using `:tt` instead in the macro definition = note: this error originates in the macro `complex_nonterminal` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/tests/ui/malformed/malformed-derive-entry.stderr b/tests/ui/malformed/malformed-derive-entry.stderr index 6ff6fbabb4a..3059d75d718 100644 --- a/tests/ui/malformed/malformed-derive-entry.stderr +++ b/tests/ui/malformed/malformed-derive-entry.stderr @@ -27,7 +27,8 @@ note: required by a bound in `Copy` = note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider annotating `Test1` with `#[derive(Clone)]` | -LL | #[derive(Clone)] +LL + #[derive(Clone)] +LL | struct Test1; | error[E0277]: the trait bound `Test2: Clone` is not satisfied @@ -41,7 +42,8 @@ note: required by a bound in `Copy` = note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider annotating `Test2` with `#[derive(Clone)]` | -LL | #[derive(Clone)] +LL + #[derive(Clone)] +LL | struct Test2; | error: aborting due to 5 previous errors diff --git a/tests/ui/methods/inherent-bound-in-probe.rs b/tests/ui/methods/inherent-bound-in-probe.rs new file mode 100644 index 00000000000..81a99ca010e --- /dev/null +++ b/tests/ui/methods/inherent-bound-in-probe.rs @@ -0,0 +1,49 @@ +// normalize-stderr-test: "long-type-\d+" -> "long-type-hash" + +// Fixes #110131 +// +// The issue is that we were constructing an `ImplDerived` cause code for the +// `&'a T: IntoIterator<Item = &'a u8>` obligation for `Helper::new`, which is +// incorrect because derived obligations are only expected to come from *traits*. + +struct SeqBuffer<'a, T> +where + &'a T: IntoIterator<Item = &'a u8>, +{ + iter: <&'a T as IntoIterator>::IntoIter, +} + +struct Helper<'a, T> +where + &'a T: IntoIterator<Item = &'a u8>, +{ + buf: SeqBuffer<'a, T>, +} + +impl<'a, T> Helper<'a, T> +where + &'a T: IntoIterator<Item = &'a u8>, +{ + fn new(sq: &'a T) -> Self { + loop {} + } +} + +struct BitReaderWrapper<T>(T); + +impl<'a, T> IntoIterator for &'a BitReaderWrapper<T> +where + &'a T: IntoIterator<Item = &'a u8>, +{ + type Item = u32; + + type IntoIter = Helper<'a, T>; + //~^ ERROR `Helper<'a, T>` is not an iterator + + fn into_iter(self) -> Self::IntoIter { + Helper::new(&self.0) + //~^ ERROR overflow evaluating the requirement `&_: IntoIterator` + } +} + +fn main() {} diff --git a/tests/ui/methods/inherent-bound-in-probe.stderr b/tests/ui/methods/inherent-bound-in-probe.stderr new file mode 100644 index 00000000000..ff03a7edb05 --- /dev/null +++ b/tests/ui/methods/inherent-bound-in-probe.stderr @@ -0,0 +1,38 @@ +error[E0277]: `Helper<'a, T>` is not an iterator + --> $DIR/inherent-bound-in-probe.rs:40:21 + | +LL | type IntoIter = Helper<'a, T>; + | ^^^^^^^^^^^^^ `Helper<'a, T>` is not an iterator + | + = help: the trait `Iterator` is not implemented for `Helper<'a, T>` +note: required by a bound in `std::iter::IntoIterator::IntoIter` + --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL + +error[E0275]: overflow evaluating the requirement `&_: IntoIterator` + --> $DIR/inherent-bound-in-probe.rs:44:17 + | +LL | Helper::new(&self.0) + | ^^^ + | + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`inherent_bound_in_probe`) +note: required for `&BitReaderWrapper<_>` to implement `IntoIterator` + --> $DIR/inherent-bound-in-probe.rs:34:13 + | +LL | impl<'a, T> IntoIterator for &'a BitReaderWrapper<T> + | ^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^ +LL | where +LL | &'a T: IntoIterator<Item = &'a u8>, + | ------------- unsatisfied trait bound introduced here + = note: 126 redundant requirements hidden + = note: required for `&BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<...>>>>>` to implement `IntoIterator` + = note: the full type name has been written to '$TEST_BUILD_DIR/methods/inherent-bound-in-probe/inherent-bound-in-probe.long-type-hash.txt' +note: required by a bound in `Helper<'a, T>` + --> $DIR/inherent-bound-in-probe.rs:25:25 + | +LL | &'a T: IntoIterator<Item = &'a u8>, + | ^^^^^^^^^^^^^ required by this bound in `Helper<'a, T>` + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0275, E0277. +For more information about an error, try `rustc --explain E0275`. diff --git a/tests/ui/mir/validate/transmute_cast_sized.rs b/tests/ui/mir/validate/transmute_cast_sized.rs new file mode 100644 index 00000000000..eaaf7eb3ecd --- /dev/null +++ b/tests/ui/mir/validate/transmute_cast_sized.rs @@ -0,0 +1,17 @@ +// build-pass +// compile-flags: -Zvalidate-mir +// edition: 2021 + +#![crate_type = "lib"] + +// Use `PhantomData` to get target-independent size +async fn get(_r: std::marker::PhantomData<&i32>) { + loop {} +} + +pub fn check() { + let mut v = get(loop {}); + let _ = || unsafe { + v = std::mem::transmute([0_u8; 1]); + }; +} diff --git a/tests/ui/mismatched_types/method-help-unsatisfied-bound.stderr b/tests/ui/mismatched_types/method-help-unsatisfied-bound.stderr index d3b7525072f..9dab3e52255 100644 --- a/tests/ui/mismatched_types/method-help-unsatisfied-bound.stderr +++ b/tests/ui/mismatched_types/method-help-unsatisfied-bound.stderr @@ -10,7 +10,8 @@ note: required by a bound in `Result::<T, E>::unwrap` --> $SRC_DIR/core/src/result.rs:LL:COL help: consider annotating `Foo` with `#[derive(Debug)]` | -LL | #[derive(Debug)] +LL + #[derive(Debug)] +LL | struct Foo; | error: aborting due to previous error diff --git a/tests/ui/modules/issue-107649.stderr b/tests/ui/modules/issue-107649.stderr index 1cea71f2829..38a910b57b4 100644 --- a/tests/ui/modules/issue-107649.stderr +++ b/tests/ui/modules/issue-107649.stderr @@ -10,7 +10,8 @@ error[E0277]: `Dummy` doesn't implement `Debug` help: consider annotating `Dummy` with `#[derive(Debug)]` --> $DIR/auxiliary/dummy_lib.rs:2:1 | -2 | #[derive(Debug)] +2 + #[derive(Debug)] +3 | #[path = "auxiliary/dummy_lib.rs"] | error: aborting due to previous error diff --git a/tests/ui/namespace/namespace-mix.stderr b/tests/ui/namespace/namespace-mix.stderr index cb72d4a1c42..3ac5e96c574 100644 --- a/tests/ui/namespace/namespace-mix.stderr +++ b/tests/ui/namespace/namespace-mix.stderr @@ -14,9 +14,9 @@ LL | check(m1::TS); | ~~ help: consider importing one of these items instead | -LL | use m2::S; +LL + use m2::S; | -LL | use xm2::S; +LL + use xm2::S; | help: if you import `S`, refer to it directly | @@ -42,9 +42,9 @@ LL | check(xm1::TS); | ~~ help: consider importing one of these items instead | -LL | use m2::S; +LL + use m2::S; | -LL | use xm2::S; +LL + use xm2::S; | help: if you import `S`, refer to it directly | @@ -68,9 +68,9 @@ LL | check(m7::TV); | ~~ help: consider importing one of these items instead | -LL | use m8::V; +LL + use m8::V; | -LL | use xm8::V; +LL + use xm8::V; | help: if you import `V`, refer to it directly | @@ -96,9 +96,9 @@ LL | check(xm7::TV); | ~~ help: consider importing one of these items instead | -LL | use m8::V; +LL + use m8::V; | -LL | use xm8::V; +LL + use xm8::V; | help: if you import `V`, refer to it directly | diff --git a/tests/ui/nll/issue-78561.rs b/tests/ui/nll/issue-78561.rs index 55147fcd1bd..1a2a3ca56c8 100644 --- a/tests/ui/nll/issue-78561.rs +++ b/tests/ui/nll/issue-78561.rs @@ -1,5 +1,5 @@ // check-pass -#![feature(type_alias_impl_trait)] +#![feature(impl_trait_in_assoc_type)] pub trait Trait { type A; diff --git a/tests/ui/not-clone-closure.stderr b/tests/ui/not-clone-closure.stderr index 37d94cf0ebd..db9307c6185 100644 --- a/tests/ui/not-clone-closure.stderr +++ b/tests/ui/not-clone-closure.stderr @@ -14,7 +14,8 @@ LL | let hello = move || { | ^^^^^^^ help: consider annotating `S` with `#[derive(Clone)]` | -LL | #[derive(Clone)] +LL + #[derive(Clone)] +LL | struct S(i32); | error: aborting due to previous error diff --git a/tests/ui/on-unimplemented/no-debug.stderr b/tests/ui/on-unimplemented/no-debug.stderr index 1035da54d8a..97d67dbd82e 100644 --- a/tests/ui/on-unimplemented/no-debug.stderr +++ b/tests/ui/on-unimplemented/no-debug.stderr @@ -9,7 +9,8 @@ LL | println!("{:?} {:?}", Foo, Bar); = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider annotating `Foo` with `#[derive(Debug)]` | -LL | #[derive(Debug)] +LL + #[derive(Debug)] +LL | struct Foo; | error[E0277]: `Bar` doesn't implement `Debug` diff --git a/tests/ui/parser/circular_modules_main.stderr b/tests/ui/parser/circular_modules_main.stderr index 1094def6014..2de70789358 100644 --- a/tests/ui/parser/circular_modules_main.stderr +++ b/tests/ui/parser/circular_modules_main.stderr @@ -12,7 +12,7 @@ LL | println!("{}", circular_modules_main::hi_str()); | help: consider importing this function | -LL | use hi_str; +LL + use hi_str; | help: if you import `hi_str`, refer to it directly | diff --git a/tests/ui/parser/numeric-lifetime.rs b/tests/ui/parser/numeric-lifetime.rs index a082a8a44df..2d82354c62c 100644 --- a/tests/ui/parser/numeric-lifetime.rs +++ b/tests/ui/parser/numeric-lifetime.rs @@ -1,6 +1,6 @@ struct S<'1> { s: &'1 usize } -//~^ ERROR lifetimes or labels cannot start with a number -//~| ERROR lifetimes or labels cannot start with a number +//~^ ERROR lifetimes cannot start with a number +//~| ERROR lifetimes cannot start with a number fn main() { // verify that the parse error doesn't stop type checking let x: usize = ""; diff --git a/tests/ui/parser/numeric-lifetime.stderr b/tests/ui/parser/numeric-lifetime.stderr index 66e35dca923..7c1bcb72631 100644 --- a/tests/ui/parser/numeric-lifetime.stderr +++ b/tests/ui/parser/numeric-lifetime.stderr @@ -6,13 +6,13 @@ LL | let x: usize = ""; | | | expected due to this -error: lifetimes or labels cannot start with a number +error: lifetimes cannot start with a number --> $DIR/numeric-lifetime.rs:1:10 | LL | struct S<'1> { s: &'1 usize } | ^^ -error: lifetimes or labels cannot start with a number +error: lifetimes cannot start with a number --> $DIR/numeric-lifetime.rs:1:20 | LL | struct S<'1> { s: &'1 usize } diff --git a/tests/ui/privacy/privacy-ns1.stderr b/tests/ui/privacy/privacy-ns1.stderr index 91bc84e70ac..9710cc48637 100644 --- a/tests/ui/privacy/privacy-ns1.stderr +++ b/tests/ui/privacy/privacy-ns1.stderr @@ -13,7 +13,7 @@ LL | Baz(); | ~~~ help: consider importing this function instead | -LL | use foo2::Bar; +LL + use foo2::Bar; | error[E0425]: cannot find function, tuple struct or tuple variant `Bar` in this scope @@ -31,7 +31,7 @@ LL | Baz(); | ~~~ help: consider importing this function | -LL | use foo2::Bar; +LL + use foo2::Bar; | error[E0412]: cannot find type `Bar` in this scope @@ -49,7 +49,7 @@ LL | let _x: Box<Baz>; | ~~~ help: consider importing this trait | -LL | use foo1::Bar; +LL + use foo1::Bar; | error[E0747]: constant provided when a type was expected diff --git a/tests/ui/privacy/privacy-ns2.stderr b/tests/ui/privacy/privacy-ns2.stderr index 904e9013f94..75e735e1e6a 100644 --- a/tests/ui/privacy/privacy-ns2.stderr +++ b/tests/ui/privacy/privacy-ns2.stderr @@ -6,7 +6,7 @@ LL | Bar(); | help: consider importing this function instead | -LL | use foo2::Bar; +LL + use foo2::Bar; | error[E0423]: expected function, tuple struct or tuple variant, found trait `Bar` @@ -24,7 +24,7 @@ LL | Baz(); | ~~~ help: consider importing this function instead | -LL | use foo2::Bar; +LL + use foo2::Bar; | error[E0573]: expected type, found function `Bar` @@ -39,7 +39,7 @@ LL | let _x = Bar(); | ~ help: consider importing this trait instead | -LL | use foo1::Bar; +LL + use foo1::Bar; | error[E0603]: trait `Bar` is private diff --git a/tests/ui/privacy/private-in-public-assoc-ty.rs b/tests/ui/privacy/private-in-public-assoc-ty.rs index fba72c13170..d4d379bdb73 100644 --- a/tests/ui/privacy/private-in-public-assoc-ty.rs +++ b/tests/ui/privacy/private-in-public-assoc-ty.rs @@ -2,7 +2,7 @@ // This test also ensures that the checks are performed even inside private modules. #![feature(associated_type_defaults)] -#![feature(type_alias_impl_trait)] +#![feature(impl_trait_in_assoc_type)] mod m { struct Priv; diff --git a/tests/ui/privacy/private-in-public-type-alias-impl-trait.rs b/tests/ui/privacy/private-in-public-type-alias-impl-trait.rs index c7df31529bc..fe6ed46734c 100644 --- a/tests/ui/privacy/private-in-public-type-alias-impl-trait.rs +++ b/tests/ui/privacy/private-in-public-type-alias-impl-trait.rs @@ -1,5 +1,5 @@ // build-pass (FIXME(62277): could be check-pass?) - +#![feature(impl_trait_in_assoc_type)] #![feature(type_alias_impl_trait)] #![deny(private_in_public)] diff --git a/tests/ui/proc-macro/amputate-span.stderr b/tests/ui/proc-macro/amputate-span.stderr index ab467041144..aa797339be4 100644 --- a/tests/ui/proc-macro/amputate-span.stderr +++ b/tests/ui/proc-macro/amputate-span.stderr @@ -6,7 +6,7 @@ LL | Command::new("git"); | help: consider importing this struct | -LL | use std::process::Command; +LL + use std::process::Command; | error[E0433]: failed to resolve: use of undeclared type `Command` @@ -17,7 +17,7 @@ LL | Command::new("git"); | help: consider importing this struct | -LL | use std::process::Command; +LL + use std::process::Command; | error: aborting due to 2 previous errors diff --git a/tests/ui/proc-macro/attributes-on-modules-fail.stderr b/tests/ui/proc-macro/attributes-on-modules-fail.stderr index bb6cbb6984d..97521f23aee 100644 --- a/tests/ui/proc-macro/attributes-on-modules-fail.stderr +++ b/tests/ui/proc-macro/attributes-on-modules-fail.stderr @@ -50,7 +50,7 @@ LL | type A = Y; | help: consider importing this struct | -LL | use Y; +LL + use Y; | error[E0412]: cannot find type `X` in this scope @@ -61,7 +61,7 @@ LL | type A = X; | help: consider importing this struct | -LL | use m::X; +LL + use m::X; | error: aborting due to 7 previous errors diff --git a/tests/ui/proc-macro/derive-bad.rs b/tests/ui/proc-macro/derive-bad.rs index cb5188b5fb4..92d35f5371a 100644 --- a/tests/ui/proc-macro/derive-bad.rs +++ b/tests/ui/proc-macro/derive-bad.rs @@ -4,7 +4,7 @@ extern crate derive_bad; #[derive(A)] -//~^ ERROR proc-macro derive produced unparseable tokens +//~^ ERROR proc-macro derive produced unparsable tokens //~| ERROR expected `:`, found `}` struct A; //~ ERROR the name `A` is defined multiple times diff --git a/tests/ui/proc-macro/derive-bad.stderr b/tests/ui/proc-macro/derive-bad.stderr index 241f99b28c2..43e97f40ba8 100644 --- a/tests/ui/proc-macro/derive-bad.stderr +++ b/tests/ui/proc-macro/derive-bad.stderr @@ -9,7 +9,7 @@ LL | #[derive(A)] | = note: this error originates in the derive macro `A` (in Nightly builds, run with -Z macro-backtrace for more info) -error: proc-macro derive produced unparseable tokens +error: proc-macro derive produced unparsable tokens --> $DIR/derive-bad.rs:6:10 | LL | #[derive(A)] diff --git a/tests/ui/proc-macro/issue-91800.rs b/tests/ui/proc-macro/issue-91800.rs index 0c1281de4f8..f48c8bf72d7 100644 --- a/tests/ui/proc-macro/issue-91800.rs +++ b/tests/ui/proc-macro/issue-91800.rs @@ -5,7 +5,7 @@ extern crate issue_91800_macro; #[derive(MyTrait)] //~^ ERROR macros that expand to items must be delimited with braces or followed by a semicolon -//~| ERROR proc-macro derive produced unparseable tokens +//~| ERROR proc-macro derive produced unparsable tokens #[attribute_macro] //~^ ERROR macros that expand to items must be delimited with braces or followed by a semicolon struct MyStruct; diff --git a/tests/ui/proc-macro/issue-91800.stderr b/tests/ui/proc-macro/issue-91800.stderr index 9c356263a36..d831d62e919 100644 --- a/tests/ui/proc-macro/issue-91800.stderr +++ b/tests/ui/proc-macro/issue-91800.stderr @@ -6,7 +6,7 @@ LL | #[derive(MyTrait)] | = note: this error originates in the derive macro `MyTrait` (in Nightly builds, run with -Z macro-backtrace for more info) -error: proc-macro derive produced unparseable tokens +error: proc-macro derive produced unparsable tokens --> $DIR/issue-91800.rs:6:10 | LL | #[derive(MyTrait)] diff --git a/tests/ui/repeat-expr/repeat-to-run-dtor-twice.stderr b/tests/ui/repeat-expr/repeat-to-run-dtor-twice.stderr index 36b93616375..1bf8e6e062f 100644 --- a/tests/ui/repeat-expr/repeat-to-run-dtor-twice.stderr +++ b/tests/ui/repeat-expr/repeat-to-run-dtor-twice.stderr @@ -7,7 +7,8 @@ LL | let _ = [ a; 5 ]; = note: the `Copy` trait is required because this value will be copied for each element of the array help: consider annotating `Foo` with `#[derive(Copy)]` | -LL | #[derive(Copy)] +LL + #[derive(Copy)] +LL | struct Foo { | error: aborting due to previous error diff --git a/tests/ui/resolve/crate-in-paths.stderr b/tests/ui/resolve/crate-in-paths.stderr index b7cf4950759..07fb5dcc035 100644 --- a/tests/ui/resolve/crate-in-paths.stderr +++ b/tests/ui/resolve/crate-in-paths.stderr @@ -6,7 +6,7 @@ LL | Foo; | help: consider importing this unit struct | -LL | use crate::bar::Foo; +LL + use crate::bar::Foo; | error: aborting due to previous error diff --git a/tests/ui/resolve/enums-are-namespaced-xc.stderr b/tests/ui/resolve/enums-are-namespaced-xc.stderr index 6448e596d56..5af6cb04275 100644 --- a/tests/ui/resolve/enums-are-namespaced-xc.stderr +++ b/tests/ui/resolve/enums-are-namespaced-xc.stderr @@ -6,7 +6,7 @@ LL | let _ = namespaced_enums::A; | help: consider importing this unit variant | -LL | use namespaced_enums::Foo::A; +LL + use namespaced_enums::Foo::A; | help: if you import `A`, refer to it directly | @@ -22,7 +22,7 @@ LL | let _ = namespaced_enums::B(10); | help: consider importing this tuple variant | -LL | use namespaced_enums::Foo::B; +LL + use namespaced_enums::Foo::B; | help: if you import `B`, refer to it directly | @@ -38,7 +38,7 @@ LL | let _ = namespaced_enums::C { a: 10 }; | help: consider importing this variant | -LL | use namespaced_enums::Foo::C; +LL + use namespaced_enums::Foo::C; | help: if you import `C`, refer to it directly | diff --git a/tests/ui/resolve/filter-intrinsics.stderr b/tests/ui/resolve/filter-intrinsics.stderr index 955070891fb..cc1092dd0cf 100644 --- a/tests/ui/resolve/filter-intrinsics.stderr +++ b/tests/ui/resolve/filter-intrinsics.stderr @@ -6,7 +6,7 @@ LL | let _ = size_of::<usize>(); | help: consider importing this function | -LL | use std::mem::size_of; +LL + use std::mem::size_of; | error[E0425]: cannot find function `fabsf64` in this scope @@ -17,7 +17,7 @@ LL | let _ = fabsf64(1.0); | help: consider importing this function | -LL | use std::intrinsics::fabsf64; +LL + use std::intrinsics::fabsf64; | error: aborting due to 2 previous errors diff --git a/tests/ui/resolve/issue-102946.stderr b/tests/ui/resolve/issue-102946.stderr index 65be0258e6d..b2cdcb25c3f 100644 --- a/tests/ui/resolve/issue-102946.stderr +++ b/tests/ui/resolve/issue-102946.stderr @@ -6,7 +6,7 @@ LL | impl Error for str::Utf8Error { | help: consider importing this trait | -LL | use std::error::Error; +LL + use std::error::Error; | error[E0223]: ambiguous associated type diff --git a/tests/ui/resolve/issue-16058.stderr b/tests/ui/resolve/issue-16058.stderr index c47d22cef5f..710002a154e 100644 --- a/tests/ui/resolve/issue-16058.stderr +++ b/tests/ui/resolve/issue-16058.stderr @@ -6,11 +6,11 @@ LL | Result { | help: consider importing one of these items instead | -LL | use std::fmt::Result; +LL + use std::fmt::Result; | -LL | use std::io::Result; +LL + use std::io::Result; | -LL | use std::thread::Result; +LL + use std::thread::Result; | error: aborting due to previous error diff --git a/tests/ui/resolve/issue-17518.stderr b/tests/ui/resolve/issue-17518.stderr index 034d0d01bfb..492e3b34a17 100644 --- a/tests/ui/resolve/issue-17518.stderr +++ b/tests/ui/resolve/issue-17518.stderr @@ -6,7 +6,7 @@ LL | E { name: "foobar" }; | help: consider importing this variant | -LL | use SomeEnum::E; +LL + use SomeEnum::E; | error: aborting due to previous error diff --git a/tests/ui/resolve/issue-21221-1.stderr b/tests/ui/resolve/issue-21221-1.stderr index 538eeead9fc..a38116cd728 100644 --- a/tests/ui/resolve/issue-21221-1.stderr +++ b/tests/ui/resolve/issue-21221-1.stderr @@ -6,11 +6,11 @@ LL | impl Mul for Foo { | help: consider importing one of these items | -LL | use mul1::Mul; +LL + use mul1::Mul; | -LL | use mul2::Mul; +LL + use mul2::Mul; | -LL | use std::ops::Mul; +LL + use std::ops::Mul; | error[E0412]: cannot find type `Mul` in this scope @@ -21,11 +21,11 @@ LL | fn getMul() -> Mul { | help: consider importing one of these items | -LL | use mul1::Mul; +LL + use mul1::Mul; | -LL | use mul2::Mul; +LL + use mul2::Mul; | -LL | use std::ops::Mul; +LL + use std::ops::Mul; | error[E0405]: cannot find trait `ThisTraitReallyDoesntExistInAnyModuleReally` in this scope @@ -42,7 +42,7 @@ LL | impl Div for Foo { | help: consider importing this trait | -LL | use std::ops::Div; +LL + use std::ops::Div; | error: aborting due to 4 previous errors diff --git a/tests/ui/resolve/issue-21221-2.stderr b/tests/ui/resolve/issue-21221-2.stderr index d4fd7cb1257..9beb626623e 100644 --- a/tests/ui/resolve/issue-21221-2.stderr +++ b/tests/ui/resolve/issue-21221-2.stderr @@ -6,9 +6,9 @@ LL | impl T for Foo { } | help: consider importing one of these items | -LL | use baz::T; +LL + use baz::T; | -LL | use foo::bar::T; +LL + use foo::bar::T; | error: aborting due to previous error diff --git a/tests/ui/resolve/issue-21221-3.stderr b/tests/ui/resolve/issue-21221-3.stderr index f12e5b09bac..0dabdfd9b39 100644 --- a/tests/ui/resolve/issue-21221-3.stderr +++ b/tests/ui/resolve/issue-21221-3.stderr @@ -6,7 +6,7 @@ LL | impl OuterTrait for Foo {} | help: consider importing this trait | -LL | use issue_21221_3::outer::OuterTrait; +LL + use issue_21221_3::outer::OuterTrait; | error: aborting due to previous error diff --git a/tests/ui/resolve/issue-21221-4.stderr b/tests/ui/resolve/issue-21221-4.stderr index fc15444d0c0..5af14b1b68d 100644 --- a/tests/ui/resolve/issue-21221-4.stderr +++ b/tests/ui/resolve/issue-21221-4.stderr @@ -6,7 +6,7 @@ LL | impl T for Foo {} | help: consider importing this trait | -LL | use issue_21221_4::T; +LL + use issue_21221_4::T; | error: aborting due to previous error diff --git a/tests/ui/resolve/issue-2356.stderr b/tests/ui/resolve/issue-2356.stderr index 36f3da7c955..313b3e30dd9 100644 --- a/tests/ui/resolve/issue-2356.stderr +++ b/tests/ui/resolve/issue-2356.stderr @@ -10,7 +10,7 @@ LL | Self::default(); | ~~~~~~~~~~~~~ help: consider importing this function | -LL | use std::default::default; +LL + use std::default::default; | error[E0425]: cannot find value `whiskers` in this scope diff --git a/tests/ui/resolve/issue-26545.stderr b/tests/ui/resolve/issue-26545.stderr index d3c86692501..42a7531c5b9 100644 --- a/tests/ui/resolve/issue-26545.stderr +++ b/tests/ui/resolve/issue-26545.stderr @@ -6,7 +6,7 @@ LL | B(()); | help: consider importing this tuple struct | -LL | use foo::B; +LL + use foo::B; | error: aborting due to previous error diff --git a/tests/ui/resolve/issue-35675.stderr b/tests/ui/resolve/issue-35675.stderr index 4a06196d548..44af65b0768 100644 --- a/tests/ui/resolve/issue-35675.stderr +++ b/tests/ui/resolve/issue-35675.stderr @@ -17,7 +17,7 @@ LL | Apple(5) | help: consider importing this tuple variant | -LL | use Fruit::Apple; +LL + use Fruit::Apple; | error[E0573]: expected type, found variant `Fruit::Apple` @@ -37,7 +37,7 @@ LL | Apple(5) | help: consider importing this tuple variant | -LL | use Fruit::Apple; +LL + use Fruit::Apple; | error[E0573]: expected type, found variant `Ok` diff --git a/tests/ui/resolve/issue-3907.stderr b/tests/ui/resolve/issue-3907.stderr index 6fc61cae843..70631a13cdf 100644 --- a/tests/ui/resolve/issue-3907.stderr +++ b/tests/ui/resolve/issue-3907.stderr @@ -10,7 +10,7 @@ LL | trait Foo = dyn issue_3907::Foo; | help: consider importing this trait instead | -LL | use issue_3907::Foo; +LL + use issue_3907::Foo; | error: aborting due to previous error diff --git a/tests/ui/resolve/issue-50599.stderr b/tests/ui/resolve/issue-50599.stderr index b07482c83cc..d7419b64fac 100644 --- a/tests/ui/resolve/issue-50599.stderr +++ b/tests/ui/resolve/issue-50599.stderr @@ -6,9 +6,9 @@ LL | const M: usize = (f64::from(N) * std::f64::LOG10_2) as usize; | help: consider importing one of these items | -LL | use std::f32::consts::LOG10_2; +LL + use std::f32::consts::LOG10_2; | -LL | use std::f64::consts::LOG10_2; +LL + use std::f64::consts::LOG10_2; | help: if you import `LOG10_2`, refer to it directly | diff --git a/tests/ui/resolve/issue-73427.stderr b/tests/ui/resolve/issue-73427.stderr index 4af5f29d809..622de9b39bd 100644 --- a/tests/ui/resolve/issue-73427.stderr +++ b/tests/ui/resolve/issue-73427.stderr @@ -107,9 +107,9 @@ LL | (E::TupleWithFields(/* fields */)).foo(); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ help: consider importing one of these items instead | -LL | use std::f32::consts::E; +LL + use std::f32::consts::E; | -LL | use std::f64::consts::E; +LL + use std::f64::consts::E; | error[E0532]: expected tuple struct or tuple variant, found enum `A` diff --git a/tests/ui/resolve/issue-90113.stderr b/tests/ui/resolve/issue-90113.stderr index 1b78720571c..5f55d9c241a 100644 --- a/tests/ui/resolve/issue-90113.stderr +++ b/tests/ui/resolve/issue-90113.stderr @@ -6,7 +6,7 @@ LL | Cons(..) => {} | help: consider importing this tuple variant | -LL | use list::List::Cons; +LL + use list::List::Cons; | error: aborting due to previous error diff --git a/tests/ui/resolve/missing-in-namespace.stderr b/tests/ui/resolve/missing-in-namespace.stderr index fc925ba3b6a..7a7b749aebb 100644 --- a/tests/ui/resolve/missing-in-namespace.stderr +++ b/tests/ui/resolve/missing-in-namespace.stderr @@ -6,7 +6,7 @@ LL | let _map = std::hahmap::HashMap::new(); | help: consider importing this struct | -LL | use std::collections::HashMap; +LL + use std::collections::HashMap; | help: if you import `HashMap`, refer to it directly | diff --git a/tests/ui/resolve/no-implicit-prelude-nested.stderr b/tests/ui/resolve/no-implicit-prelude-nested.stderr index 198b630c52c..49cf72bfee2 100644 --- a/tests/ui/resolve/no-implicit-prelude-nested.stderr +++ b/tests/ui/resolve/no-implicit-prelude-nested.stderr @@ -6,7 +6,7 @@ LL | impl Add for Test {} | help: consider importing this trait | -LL | use std::ops::Add; +LL + use std::ops::Add; | error[E0404]: expected trait, found derive macro `Clone` @@ -17,7 +17,7 @@ LL | impl Clone for Test {} | help: consider importing this trait instead | -LL | use std::clone::Clone; +LL + use std::clone::Clone; | error[E0405]: cannot find trait `Iterator` in this scope @@ -28,7 +28,7 @@ LL | impl Iterator for Test {} | help: consider importing this trait | -LL | use std::iter::Iterator; +LL + use std::iter::Iterator; | error[E0405]: cannot find trait `ToString` in this scope @@ -39,7 +39,7 @@ LL | impl ToString for Test {} | help: consider importing this trait | -LL | use std::string::ToString; +LL + use std::string::ToString; | error[E0405]: cannot find trait `Writer` in this scope @@ -56,7 +56,7 @@ LL | drop(2) | help: consider importing this function | -LL | use std::mem::drop; +LL + use std::mem::drop; | error[E0405]: cannot find trait `Add` in this scope @@ -67,7 +67,7 @@ LL | impl Add for Test {} | help: consider importing this trait | -LL | use std::ops::Add; +LL + use std::ops::Add; | error[E0404]: expected trait, found derive macro `Clone` @@ -78,7 +78,7 @@ LL | impl Clone for Test {} | help: consider importing this trait instead | -LL | use std::clone::Clone; +LL + use std::clone::Clone; | error[E0405]: cannot find trait `Iterator` in this scope @@ -89,7 +89,7 @@ LL | impl Iterator for Test {} | help: consider importing this trait | -LL | use std::iter::Iterator; +LL + use std::iter::Iterator; | error[E0405]: cannot find trait `ToString` in this scope @@ -100,7 +100,7 @@ LL | impl ToString for Test {} | help: consider importing this trait | -LL | use std::string::ToString; +LL + use std::string::ToString; | error[E0405]: cannot find trait `Writer` in this scope @@ -117,7 +117,7 @@ LL | drop(2) | help: consider importing this function | -LL | use std::mem::drop; +LL + use std::mem::drop; | error[E0405]: cannot find trait `Add` in this scope @@ -128,7 +128,7 @@ LL | impl Add for Test {} | help: consider importing this trait | -LL | use std::ops::Add; +LL + use std::ops::Add; | error[E0404]: expected trait, found derive macro `Clone` @@ -139,7 +139,7 @@ LL | impl Clone for Test {} | help: consider importing this trait instead | -LL | use std::clone::Clone; +LL + use std::clone::Clone; | error[E0405]: cannot find trait `Iterator` in this scope @@ -150,7 +150,7 @@ LL | impl Iterator for Test {} | help: consider importing this trait | -LL | use std::iter::Iterator; +LL + use std::iter::Iterator; | error[E0405]: cannot find trait `ToString` in this scope @@ -161,7 +161,7 @@ LL | impl ToString for Test {} | help: consider importing this trait | -LL | use std::string::ToString; +LL + use std::string::ToString; | error[E0405]: cannot find trait `Writer` in this scope @@ -178,7 +178,7 @@ LL | drop(2) | help: consider importing this function | -LL | use std::mem::drop; +LL + use std::mem::drop; | error: aborting due to 18 previous errors diff --git a/tests/ui/resolve/no-implicit-prelude.stderr b/tests/ui/resolve/no-implicit-prelude.stderr index 36a9b65b7d1..5a759743f72 100644 --- a/tests/ui/resolve/no-implicit-prelude.stderr +++ b/tests/ui/resolve/no-implicit-prelude.stderr @@ -6,7 +6,7 @@ LL | impl Add for Test {} | help: consider importing this trait | -LL | use std::ops::Add; +LL + use std::ops::Add; | error[E0404]: expected trait, found derive macro `Clone` @@ -17,7 +17,7 @@ LL | impl Clone for Test {} | help: consider importing this trait instead | -LL | use std::clone::Clone; +LL + use std::clone::Clone; | error[E0405]: cannot find trait `Iterator` in this scope @@ -28,7 +28,7 @@ LL | impl Iterator for Test {} | help: consider importing this trait | -LL | use std::iter::Iterator; +LL + use std::iter::Iterator; | error[E0405]: cannot find trait `ToString` in this scope @@ -39,7 +39,7 @@ LL | impl ToString for Test {} | help: consider importing this trait | -LL | use std::string::ToString; +LL + use std::string::ToString; | error[E0405]: cannot find trait `Writer` in this scope @@ -56,7 +56,7 @@ LL | drop(2) | help: consider importing this function | -LL | use std::mem::drop; +LL + use std::mem::drop; | error: aborting due to 6 previous errors diff --git a/tests/ui/resolve/privacy-enum-ctor.stderr b/tests/ui/resolve/privacy-enum-ctor.stderr index 3c051429fd0..0bb09090569 100644 --- a/tests/ui/resolve/privacy-enum-ctor.stderr +++ b/tests/ui/resolve/privacy-enum-ctor.stderr @@ -84,9 +84,9 @@ LL | let _: E = m::f; | ~ help: consider importing one of these items instead | -LL | use std::f32::consts::E; +LL + use std::f32::consts::E; | -LL | use std::f64::consts::E; +LL + use std::f64::consts::E; | help: if you import `E`, refer to it directly | @@ -121,9 +121,9 @@ LL | let _: E = (E::Fn(/* fields */)); | ~~~~~~~~~~~~~~~~~~~~~ help: consider importing one of these items instead | -LL | use std::f32::consts::E; +LL + use std::f32::consts::E; | -LL | use std::f64::consts::E; +LL + use std::f64::consts::E; | error[E0412]: cannot find type `Z` in this scope diff --git a/tests/ui/resolve/resolve-primitive-fallback.stderr b/tests/ui/resolve/resolve-primitive-fallback.stderr index f803f9da2af..e3a5d4edcf1 100644 --- a/tests/ui/resolve/resolve-primitive-fallback.stderr +++ b/tests/ui/resolve/resolve-primitive-fallback.stderr @@ -12,7 +12,7 @@ LL | let _: ::u8; | help: consider importing this builtin type | -LL | use std::primitive::u8; +LL + use std::primitive::u8; | help: if you import `u8`, refer to it directly | diff --git a/tests/ui/resolve/use_suggestion.stderr b/tests/ui/resolve/use_suggestion.stderr index 54ad853831f..1155f5caa17 100644 --- a/tests/ui/resolve/use_suggestion.stderr +++ b/tests/ui/resolve/use_suggestion.stderr @@ -6,7 +6,7 @@ LL | let x1 = HashMap::new(); | help: consider importing this struct | -LL | use std::collections::HashMap; +LL + use std::collections::HashMap; | error[E0412]: cannot find type `HashMap` in this scope @@ -17,7 +17,7 @@ LL | let y1: HashMap; | help: consider importing this struct | -LL | use std::collections::HashMap; +LL + use std::collections::HashMap; | error[E0412]: cannot find type `GooMap` in this scope diff --git a/tests/ui/resolve/use_suggestion_placement.stderr b/tests/ui/resolve/use_suggestion_placement.stderr index 0aadd82f6c2..3611f9ae6b4 100644 --- a/tests/ui/resolve/use_suggestion_placement.stderr +++ b/tests/ui/resolve/use_suggestion_placement.stderr @@ -6,7 +6,7 @@ LL | type Bar = Path; | help: consider importing this struct | -LL | use std::path::Path; +LL + use std::path::Path; | error[E0425]: cannot find value `A` in this scope @@ -17,7 +17,7 @@ LL | let _ = A; | help: consider importing this constant | -LL | use m::A; +LL + use m::A; | error[E0412]: cannot find type `HashMap` in this scope @@ -28,7 +28,7 @@ LL | type Dict<K, V> = HashMap<K, V>; | help: consider importing this struct | -LL | use std::collections::HashMap; +LL + use std::collections::HashMap; | error: aborting due to 3 previous errors diff --git a/tests/ui/rfc-2361-dbg-macro/dbg-macro-requires-debug.stderr b/tests/ui/rfc-2361-dbg-macro/dbg-macro-requires-debug.stderr index d8b5a9e6364..ce165e64632 100644 --- a/tests/ui/rfc-2361-dbg-macro/dbg-macro-requires-debug.stderr +++ b/tests/ui/rfc-2361-dbg-macro/dbg-macro-requires-debug.stderr @@ -9,7 +9,8 @@ LL | let _: NotDebug = dbg!(NotDebug); = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `dbg` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider annotating `NotDebug` with `#[derive(Debug)]` | -LL | #[derive(Debug)] +LL + #[derive(Debug)] +LL | struct NotDebug; | error: aborting due to previous error diff --git a/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.stderr b/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.stderr index 6b6c578bff8..653037ef398 100644 --- a/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.stderr +++ b/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.stderr @@ -16,7 +16,8 @@ LL | pub struct S(A); = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider annotating `A` with `#[derive(Default)]` | -LL | #[derive(Default)] +LL + #[derive(Default)] +LL | pub struct A; | error[E0015]: cannot call non-const fn `<A as Default>::default` in constant functions diff --git a/tests/ui/rust-2018/issue-52202-use-suggestions.stderr b/tests/ui/rust-2018/issue-52202-use-suggestions.stderr index 38cd9713d1a..9933b92439c 100644 --- a/tests/ui/rust-2018/issue-52202-use-suggestions.stderr +++ b/tests/ui/rust-2018/issue-52202-use-suggestions.stderr @@ -6,13 +6,13 @@ LL | let _d = Drain {}; | help: consider importing one of these items | -LL | use crate::plumbing::Drain; +LL + use crate::plumbing::Drain; | -LL | use std::collections::binary_heap::Drain; +LL + use std::collections::binary_heap::Drain; | -LL | use std::collections::hash_map::Drain; +LL + use std::collections::hash_map::Drain; | -LL | use std::collections::hash_set::Drain; +LL + use std::collections::hash_set::Drain; | and 3 other candidates diff --git a/tests/ui/rust-2018/trait-import-suggestions.stderr b/tests/ui/rust-2018/trait-import-suggestions.stderr index 6454b6045e4..325c5976e7c 100644 --- a/tests/ui/rust-2018/trait-import-suggestions.stderr +++ b/tests/ui/rust-2018/trait-import-suggestions.stderr @@ -10,7 +10,7 @@ LL | x.foobar(); = help: items from traits can only be used if the trait is in scope help: the following trait is implemented but not in scope; perhaps add a `use` for it: | -LL | use crate::foo::foobar::Foobar; +LL + use crate::foo::foobar::Foobar; | error[E0599]: no method named `bar` found for type `u32` in the current scope @@ -25,7 +25,7 @@ LL | x.bar(); = help: items from traits can only be used if the trait is in scope help: the following trait is implemented but not in scope; perhaps add a `use` for it: | -LL | use crate::foo::Bar; +LL + use crate::foo::Bar; | error[E0599]: no method named `baz` found for type `u32` in the current scope @@ -43,7 +43,7 @@ LL | let y = u32::from_str("33"); = help: items from traits can only be used if the trait is in scope help: the following trait is implemented but not in scope; perhaps add a `use` for it: | -LL | use std::str::FromStr; +LL + use std::str::FromStr; | help: there is an associated function with a similar name | diff --git a/tests/ui/rust-2018/uniform-paths/issue-87932.stderr b/tests/ui/rust-2018/uniform-paths/issue-87932.stderr index b52720ae3d9..ac2baa3595b 100644 --- a/tests/ui/rust-2018/uniform-paths/issue-87932.stderr +++ b/tests/ui/rust-2018/uniform-paths/issue-87932.stderr @@ -10,7 +10,7 @@ LL | A::deserialize(); = help: items from traits can only be used if the trait is in scope help: the following trait is implemented but not in scope; perhaps add a `use` for it: | -LL | use <crate::A as issue_87932_a::Deserialize>::deserialize::_a::Deserialize; +LL + use <crate::A as issue_87932_a::Deserialize>::deserialize::_a::Deserialize; | error: aborting due to previous error diff --git a/tests/ui/rust-2021/future-prelude-collision-shadow.stderr b/tests/ui/rust-2021/future-prelude-collision-shadow.stderr index 3d21b735aea..9dfaf13e2ec 100644 --- a/tests/ui/rust-2021/future-prelude-collision-shadow.stderr +++ b/tests/ui/rust-2021/future-prelude-collision-shadow.stderr @@ -8,9 +8,9 @@ LL | let _: u32 = 3u8.try_into().unwrap(); = note: 'std::convert::TryInto' is included in the prelude starting in Edition 2021 help: the following traits are implemented but not in scope; perhaps add a `use` for one of them: | -LL | use crate::m::TryIntoU32; +LL + use crate::m::TryIntoU32; | -LL | use std::convert::TryInto; +LL + use std::convert::TryInto; | error: aborting due to previous error diff --git a/tests/ui/self/class-missing-self.stderr b/tests/ui/self/class-missing-self.stderr index 063c3f013c5..3c37d819743 100644 --- a/tests/ui/self/class-missing-self.stderr +++ b/tests/ui/self/class-missing-self.stderr @@ -16,7 +16,7 @@ LL | self.sleep(); | +++++ help: consider importing this function | -LL | use std::thread::sleep; +LL + use std::thread::sleep; | error: aborting due to 2 previous errors diff --git a/tests/ui/shadowed/shadowed-trait-methods.stderr b/tests/ui/shadowed/shadowed-trait-methods.stderr index c3b9084affd..1af0400c886 100644 --- a/tests/ui/shadowed/shadowed-trait-methods.stderr +++ b/tests/ui/shadowed/shadowed-trait-methods.stderr @@ -10,7 +10,7 @@ LL | ().f() = help: items from traits can only be used if the trait is in scope help: the following trait is implemented but not in scope; perhaps add a `use` for it: | -LL | use foo::T; +LL + use foo::T; | error: aborting due to previous error diff --git a/tests/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-96258.stderr b/tests/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-96258.stderr index 37b2f413860..60433e1c284 100644 --- a/tests/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-96258.stderr +++ b/tests/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-96258.stderr @@ -15,7 +15,7 @@ LL | interval: Duration, | help: consider importing this struct | -LL | use std::time::Duration; +LL + use std::time::Duration; | error: aborting due to 2 previous errors diff --git a/tests/ui/span/issue-35987.stderr b/tests/ui/span/issue-35987.stderr index 057d40ac0cb..88c86d2a91b 100644 --- a/tests/ui/span/issue-35987.stderr +++ b/tests/ui/span/issue-35987.stderr @@ -11,7 +11,7 @@ LL | impl<T: Clone, Add> Add for Foo<T> { | help: consider importing this trait instead | -LL | use std::ops::Add; +LL + use std::ops::Add; | error: aborting due to previous error diff --git a/tests/ui/span/issue-71363.stderr b/tests/ui/span/issue-71363.stderr index cb5cc320276..90b623e89cf 100644 --- a/tests/ui/span/issue-71363.stderr +++ b/tests/ui/span/issue-71363.stderr @@ -21,7 +21,8 @@ note: required by a bound in `std::error::Error` --> $SRC_DIR/core/src/error.rs:LL:COL help: consider annotating `MyError` with `#[derive(Debug)]` | -3 | #[derive(Debug)] +3 + #[derive(Debug)] +4 | struct MyError; | error: aborting due to 2 previous errors diff --git a/tests/ui/specialization/issue-59435.stderr b/tests/ui/specialization/issue-59435.stderr index 21145940668..e8a12e4d928 100644 --- a/tests/ui/specialization/issue-59435.stderr +++ b/tests/ui/specialization/issue-59435.stderr @@ -11,7 +11,8 @@ LL | type MyType: Default; | ^^^^^^^ required by this bound in `MyTrait::MyType` help: consider annotating `MyStruct` with `#[derive(Default)]` | -LL | #[derive(Default)] +LL + #[derive(Default)] +LL | struct MyStruct {} | error: aborting due to previous error diff --git a/tests/ui/structs/struct-path-alias-bounds.stderr b/tests/ui/structs/struct-path-alias-bounds.stderr index 266291f62b4..5b01208c56f 100644 --- a/tests/ui/structs/struct-path-alias-bounds.stderr +++ b/tests/ui/structs/struct-path-alias-bounds.stderr @@ -11,7 +11,8 @@ LL | struct S<T: Clone> { a: T } | ^^^^^ required by this bound in `S` help: consider annotating `NoClone` with `#[derive(Clone)]` | -LL | #[derive(Clone)] +LL + #[derive(Clone)] +LL | struct NoClone; | error: aborting due to previous error diff --git a/tests/ui/suggestions/clone-on-unconstrained-borrowed-type-param.stderr b/tests/ui/suggestions/clone-on-unconstrained-borrowed-type-param.stderr index 45593035b9d..0716005c679 100644 --- a/tests/ui/suggestions/clone-on-unconstrained-borrowed-type-param.stderr +++ b/tests/ui/suggestions/clone-on-unconstrained-borrowed-type-param.stderr @@ -35,7 +35,8 @@ LL | t.clone() | ^ help: consider annotating `Foo` with `#[derive(Clone)]` | -LL | #[derive(Clone)] +LL + #[derive(Clone)] +LL | struct Foo; | error: aborting due to 2 previous errors diff --git a/tests/ui/suggestions/core-std-import-order-issue-83564.stderr b/tests/ui/suggestions/core-std-import-order-issue-83564.stderr index e4e1fc591c4..48ee44a74f2 100644 --- a/tests/ui/suggestions/core-std-import-order-issue-83564.stderr +++ b/tests/ui/suggestions/core-std-import-order-issue-83564.stderr @@ -6,9 +6,9 @@ LL | let _x = NonZeroU32::new(5).unwrap(); | help: consider importing one of these items | -LL | use core::num::NonZeroU32; +LL + use core::num::NonZeroU32; | -LL | use std::num::NonZeroU32; +LL + use std::num::NonZeroU32; | error: aborting due to previous error diff --git a/tests/ui/suggestions/derive-macro-missing-bounds.stderr b/tests/ui/suggestions/derive-macro-missing-bounds.stderr index 79036279df9..c3f305c1770 100644 --- a/tests/ui/suggestions/derive-macro-missing-bounds.stderr +++ b/tests/ui/suggestions/derive-macro-missing-bounds.stderr @@ -11,7 +11,8 @@ LL | struct Outer<T>(Inner<T>); = note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider annotating `a::Inner<T>` with `#[derive(Debug)]` | -LL | #[derive(Debug)] +LL + #[derive(Debug)] +LL | struct Inner<T>(T); | help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement | diff --git a/tests/ui/suggestions/derive-trait-for-method-call.stderr b/tests/ui/suggestions/derive-trait-for-method-call.stderr index 924b26a8c75..e2db0da74f0 100644 --- a/tests/ui/suggestions/derive-trait-for-method-call.stderr +++ b/tests/ui/suggestions/derive-trait-for-method-call.stderr @@ -32,7 +32,8 @@ note: the trait `Default` must be implemented --> $SRC_DIR/core/src/default.rs:LL:COL help: consider annotating `Enum` with `#[derive(Clone)]` | -LL | #[derive(Clone)] +LL + #[derive(Clone)] +LL | enum Enum { | error[E0599]: the method `test` exists for struct `Foo<Struct, CloneStruct>`, but its trait bounds were not satisfied @@ -67,11 +68,13 @@ LL | impl<X: Clone + Default + , Y: Clone + Default> Foo<X, Y> { | unsatisfied trait bound introduced here help: consider annotating `CloneStruct` with `#[derive(Default)]` | -LL | #[derive(Default)] +LL + #[derive(Default)] +LL | struct CloneStruct { | help: consider annotating `Struct` with `#[derive(Clone, Default)]` | -LL | #[derive(Clone, Default)] +LL + #[derive(Clone, Default)] +LL | struct Struct { | error[E0599]: the method `test` exists for struct `Foo<Vec<Enum>, Instant>`, but its trait bounds were not satisfied diff --git a/tests/ui/suggestions/dont-wrap-ambiguous-receivers.stderr b/tests/ui/suggestions/dont-wrap-ambiguous-receivers.stderr index 4658ecb3a7a..85fbb8b88e8 100644 --- a/tests/ui/suggestions/dont-wrap-ambiguous-receivers.stderr +++ b/tests/ui/suggestions/dont-wrap-ambiguous-receivers.stderr @@ -10,9 +10,9 @@ LL | banana::Chaenomeles.pick() = help: items from traits can only be used if the trait is in scope help: the following traits are implemented but not in scope; perhaps add a `use` for one of them: | -LL | use banana::Apple; +LL + use banana::Apple; | -LL | use banana::Peach; +LL + use banana::Peach; | error: aborting due to previous error diff --git a/tests/ui/suggestions/import-trait-for-method-call.stderr b/tests/ui/suggestions/import-trait-for-method-call.stderr index f159b51a269..3f54daf136f 100644 --- a/tests/ui/suggestions/import-trait-for-method-call.stderr +++ b/tests/ui/suggestions/import-trait-for-method-call.stderr @@ -10,7 +10,7 @@ LL | h.finish() = help: items from traits can only be used if the trait is in scope help: the following trait is implemented but not in scope; perhaps add a `use` for it: | -LL | use std::hash::Hasher; +LL + use std::hash::Hasher; | error[E0599]: the method `as_ref` exists for reference `&dyn Bar`, but its trait bounds were not satisfied diff --git a/tests/ui/suggestions/invalid-bin-op.stderr b/tests/ui/suggestions/invalid-bin-op.stderr index 08502dfeb2d..e291cedb835 100644 --- a/tests/ui/suggestions/invalid-bin-op.stderr +++ b/tests/ui/suggestions/invalid-bin-op.stderr @@ -13,7 +13,8 @@ LL | struct S<T>(T); | ^^^^^^^^^^^ must implement `PartialEq<_>` help: consider annotating `S<T>` with `#[derive(PartialEq)]` | -LL | #[derive(PartialEq)] +LL + #[derive(PartialEq)] +LL | struct S<T>(T); | help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement | diff --git a/tests/ui/suggestions/issue-84973-blacklist.stderr b/tests/ui/suggestions/issue-84973-blacklist.stderr index c20cc816484..1e243f81b10 100644 --- a/tests/ui/suggestions/issue-84973-blacklist.stderr +++ b/tests/ui/suggestions/issue-84973-blacklist.stderr @@ -27,7 +27,8 @@ LL | fn f_clone<T: Clone>(t: T) {} | ^^^^^ required by this bound in `f_clone` help: consider annotating `S` with `#[derive(Clone)]` | -LL | #[derive(Clone)] +LL + #[derive(Clone)] +LL | struct S; | error[E0277]: `[static generator@$DIR/issue-84973-blacklist.rs:17:13: 17:22]` cannot be unpinned diff --git a/tests/ui/suggestions/no-extern-crate-in-type.stderr b/tests/ui/suggestions/no-extern-crate-in-type.stderr index 876eef2b624..68100e56cbc 100644 --- a/tests/ui/suggestions/no-extern-crate-in-type.stderr +++ b/tests/ui/suggestions/no-extern-crate-in-type.stderr @@ -6,7 +6,7 @@ LL | type Output = Option<Foo>; | help: consider importing this struct | -LL | use foo::Foo; +LL + use foo::Foo; | error: aborting due to previous error diff --git a/tests/ui/suggestions/raw-name-use-suggestion.stderr b/tests/ui/suggestions/raw-name-use-suggestion.stderr index 95c26b9ade8..fb070ffc332 100644 --- a/tests/ui/suggestions/raw-name-use-suggestion.stderr +++ b/tests/ui/suggestions/raw-name-use-suggestion.stderr @@ -28,7 +28,7 @@ LL | r#break(); | help: consider importing this function | -LL | use foo::r#break; +LL + use foo::r#break; | error: aborting due to 3 previous errors diff --git a/tests/ui/suggestions/suggest-tryinto-edition-change.stderr b/tests/ui/suggestions/suggest-tryinto-edition-change.stderr index 018083f9e03..671f5efddd9 100644 --- a/tests/ui/suggestions/suggest-tryinto-edition-change.stderr +++ b/tests/ui/suggestions/suggest-tryinto-edition-change.stderr @@ -8,9 +8,9 @@ LL | let _i: i16 = TryFrom::try_from(0_i32).unwrap(); = note: 'core::convert::TryFrom' is included in the prelude starting in Edition 2021 help: consider importing one of these items | -LL | use core::convert::TryFrom; +LL + use core::convert::TryFrom; | -LL | use std::convert::TryFrom; +LL + use std::convert::TryFrom; | error[E0433]: failed to resolve: use of undeclared type `TryInto` @@ -23,9 +23,9 @@ LL | let _i: i16 = TryInto::try_into(0_i32).unwrap(); = note: 'core::convert::TryInto' is included in the prelude starting in Edition 2021 help: consider importing one of these items | -LL | use core::convert::TryInto; +LL + use core::convert::TryInto; | -LL | use std::convert::TryInto; +LL + use std::convert::TryInto; | error[E0433]: failed to resolve: use of undeclared type `FromIterator` @@ -42,9 +42,9 @@ LL | let _v: Vec<_> = IntoIterator::from_iter(&[1]); | ~~~~~~~~~~~~ help: consider importing one of these items | -LL | use core::iter::FromIterator; +LL + use core::iter::FromIterator; | -LL | use std::iter::FromIterator; +LL + use std::iter::FromIterator; | error[E0599]: no method named `try_into` found for type `i32` in the current scope @@ -60,7 +60,7 @@ LL | let _i: i16 = 0_i32.try_into().unwrap(); = note: 'std::convert::TryInto' is included in the prelude starting in Edition 2021 help: the following trait is implemented but not in scope; perhaps add a `use` for it: | -LL | use std::convert::TryInto; +LL + use std::convert::TryInto; | error: aborting due to 4 previous errors diff --git a/tests/ui/suggestions/use-placement-resolve.stderr b/tests/ui/suggestions/use-placement-resolve.stderr index 9da9e8e2702..77724e7e2a4 100644 --- a/tests/ui/suggestions/use-placement-resolve.stderr +++ b/tests/ui/suggestions/use-placement-resolve.stderr @@ -6,7 +6,7 @@ LL | fn foobar<T: Debug>(x: T) {} | help: consider importing this trait instead | -LL | use std::fmt::Debug; +LL + use std::fmt::Debug; | error: aborting due to previous error diff --git a/tests/ui/suggestions/use-placement-typeck.stderr b/tests/ui/suggestions/use-placement-typeck.stderr index 3b2749773a1..e900e12b7df 100644 --- a/tests/ui/suggestions/use-placement-typeck.stderr +++ b/tests/ui/suggestions/use-placement-typeck.stderr @@ -13,7 +13,7 @@ LL | pub struct S; = help: items from traits can only be used if the trait is in scope help: the following trait is implemented but not in scope; perhaps add a `use` for it: | -LL | use m::Foo; +LL + use m::Foo; | error: aborting due to previous error diff --git a/tests/ui/test-attrs/issue-109816.rs b/tests/ui/test-attrs/issue-109816.rs new file mode 100644 index 00000000000..21fe5bc53b7 --- /dev/null +++ b/tests/ui/test-attrs/issue-109816.rs @@ -0,0 +1,7 @@ +// compile-flags: --test + +fn align_offset_weird_strides() { + #[test] + //~^ ERROR the `#[test]` attribute may only be used on a non-associated function + struct A5(u32, u8); +} diff --git a/tests/ui/test-attrs/issue-109816.stderr b/tests/ui/test-attrs/issue-109816.stderr new file mode 100644 index 00000000000..e6993287555 --- /dev/null +++ b/tests/ui/test-attrs/issue-109816.stderr @@ -0,0 +1,16 @@ +error: the `#[test]` attribute may only be used on a non-associated function + --> $DIR/issue-109816.rs:4:5 + | +LL | #[test] + | ^^^^^^^ the `#[test]` macro causes a function to be run as a test and has no effect on non-functions +LL | +LL | struct A5(u32, u8); + | ------------------- expected a non-associated function, found a struct + | +help: replace with conditional compilation to make the item only exist when tests are being run + | +LL | #[cfg(test)] + | + +error: aborting due to previous error + diff --git a/tests/ui/test-attrs/test-attr-non-associated-functions.rs b/tests/ui/test-attrs/test-attr-non-associated-functions.rs index 31e567c3960..2481919b616 100644 --- a/tests/ui/test-attrs/test-attr-non-associated-functions.rs +++ b/tests/ui/test-attrs/test-attr-non-associated-functions.rs @@ -1,18 +1,16 @@ -// #[test] attribute is not allowed on associated functions or methods -// reworded error message // compile-flags:--test struct A {} impl A { #[test] + //~^ ERROR the `#[test]` attribute may only be used on a non-associated function fn new() -> A { - //~^ ERROR `#[test]` attribute is only allowed on non associated functions A {} } #[test] + //~^ ERROR the `#[test]` attribute may only be used on a non-associated function fn recovery_witness() -> A { - //~^ ERROR `#[test]` attribute is only allowed on non associated functions A {} } } diff --git a/tests/ui/test-attrs/test-attr-non-associated-functions.stderr b/tests/ui/test-attrs/test-attr-non-associated-functions.stderr index a81b8f3980c..3e3a951aff3 100644 --- a/tests/ui/test-attrs/test-attr-non-associated-functions.stderr +++ b/tests/ui/test-attrs/test-attr-non-associated-functions.stderr @@ -1,20 +1,24 @@ -error: `#[test]` attribute is only allowed on non associated functions - --> $DIR/test-attr-non-associated-functions.rs:9:5 - | -LL | / fn new() -> A { -LL | | -LL | | A {} -LL | | } - | |_____^ +error: the `#[test]` attribute may only be used on a non-associated function + --> $DIR/test-attr-non-associated-functions.rs:6:5 + | +LL | #[test] + | ^^^^^^^ the `#[test]` macro causes a function to be run as a test and has no effect on non-functions + | +help: replace with conditional compilation to make the item only exist when tests are being run + | +LL | #[cfg(test)] + | -error: `#[test]` attribute is only allowed on non associated functions - --> $DIR/test-attr-non-associated-functions.rs:14:5 - | -LL | / fn recovery_witness() -> A { -LL | | -LL | | A {} -LL | | } - | |_____^ +error: the `#[test]` attribute may only be used on a non-associated function + --> $DIR/test-attr-non-associated-functions.rs:11:5 + | +LL | #[test] + | ^^^^^^^ the `#[test]` macro causes a function to be run as a test and has no effect on non-functions + | +help: replace with conditional compilation to make the item only exist when tests are being run + | +LL | #[cfg(test)] + | error: aborting due to 2 previous errors diff --git a/tests/ui/test-attrs/test-on-not-fn.stderr b/tests/ui/test-attrs/test-on-not-fn.stderr index fc2c5f62bed..7a9913fbcfa 100644 --- a/tests/ui/test-attrs/test-on-not-fn.stderr +++ b/tests/ui/test-attrs/test-on-not-fn.stderr @@ -2,7 +2,7 @@ error: the `#[test]` attribute may only be used on a non-associated function --> $DIR/test-on-not-fn.rs:3:1 | LL | #[test] - | ^^^^^^^ the `#[test]` macro causes a function to be run on a test and has no effect on non-functions + | ^^^^^^^ the `#[test]` macro causes a function to be run as a test and has no effect on non-functions LL | mod test {} | ----------- expected a non-associated function, found a module | @@ -15,7 +15,7 @@ error: the `#[test]` attribute may only be used on a non-associated function --> $DIR/test-on-not-fn.rs:6:1 | LL | #[test] - | ^^^^^^^ the `#[test]` macro causes a function to be run on a test and has no effect on non-functions + | ^^^^^^^ the `#[test]` macro causes a function to be run as a test and has no effect on non-functions LL | / mod loooooooooooooong_teeeeeeeeeest { LL | | /* LL | | this is a comment @@ -34,7 +34,7 @@ error: the `#[test]` attribute may only be used on a non-associated function --> $DIR/test-on-not-fn.rs:20:1 | LL | #[test] - | ^^^^^^^ the `#[test]` macro causes a function to be run on a test and has no effect on non-functions + | ^^^^^^^ the `#[test]` macro causes a function to be run as a test and has no effect on non-functions LL | extern "C" {} | ------------- expected a non-associated function, found an extern block | @@ -47,7 +47,7 @@ error: the `#[test]` attribute may only be used on a non-associated function --> $DIR/test-on-not-fn.rs:23:1 | LL | #[test] - | ^^^^^^^ the `#[test]` macro causes a function to be run on a test and has no effect on non-functions + | ^^^^^^^ the `#[test]` macro causes a function to be run as a test and has no effect on non-functions LL | trait Foo {} | ------------ expected a non-associated function, found a trait | @@ -60,7 +60,7 @@ error: the `#[test]` attribute may only be used on a non-associated function --> $DIR/test-on-not-fn.rs:26:1 | LL | #[test] - | ^^^^^^^ the `#[test]` macro causes a function to be run on a test and has no effect on non-functions + | ^^^^^^^ the `#[test]` macro causes a function to be run as a test and has no effect on non-functions LL | impl Foo for i32 {} | ------------------- expected a non-associated function, found an implementation | @@ -73,7 +73,7 @@ error: the `#[test]` attribute may only be used on a non-associated function --> $DIR/test-on-not-fn.rs:29:1 | LL | #[test] - | ^^^^^^^ the `#[test]` macro causes a function to be run on a test and has no effect on non-functions + | ^^^^^^^ the `#[test]` macro causes a function to be run as a test and has no effect on non-functions LL | const FOO: i32 = -1_i32; | ------------------------ expected a non-associated function, found a constant item | @@ -86,7 +86,7 @@ error: the `#[test]` attribute may only be used on a non-associated function --> $DIR/test-on-not-fn.rs:32:1 | LL | #[test] - | ^^^^^^^ the `#[test]` macro causes a function to be run on a test and has no effect on non-functions + | ^^^^^^^ the `#[test]` macro causes a function to be run as a test and has no effect on non-functions LL | static BAR: u64 = 10_000_u64; | ----------------------------- expected a non-associated function, found a static item | @@ -99,7 +99,7 @@ error: the `#[test]` attribute may only be used on a non-associated function --> $DIR/test-on-not-fn.rs:35:1 | LL | #[test] - | ^^^^^^^ the `#[test]` macro causes a function to be run on a test and has no effect on non-functions + | ^^^^^^^ the `#[test]` macro causes a function to be run as a test and has no effect on non-functions LL | / enum MyUnit { LL | | Unit, LL | | } @@ -114,7 +114,7 @@ error: the `#[test]` attribute may only be used on a non-associated function --> $DIR/test-on-not-fn.rs:40:1 | LL | #[test] - | ^^^^^^^ the `#[test]` macro causes a function to be run on a test and has no effect on non-functions + | ^^^^^^^ the `#[test]` macro causes a function to be run as a test and has no effect on non-functions LL | struct NewI32(i32); | ------------------- expected a non-associated function, found a struct | @@ -127,7 +127,7 @@ error: the `#[test]` attribute may only be used on a non-associated function --> $DIR/test-on-not-fn.rs:43:1 | LL | #[test] - | ^^^^^^^ the `#[test]` macro causes a function to be run on a test and has no effect on non-functions + | ^^^^^^^ the `#[test]` macro causes a function to be run as a test and has no effect on non-functions LL | / union Spooky { LL | | x: i32, LL | | y: u32, @@ -143,7 +143,7 @@ error: the `#[test]` attribute may only be used on a non-associated function --> $DIR/test-on-not-fn.rs:50:1 | LL | #[test] - | ^^^^^^^ the `#[test]` macro causes a function to be run on a test and has no effect on non-functions + | ^^^^^^^ the `#[test]` macro causes a function to be run as a test and has no effect on non-functions LL | #[derive(Copy, Clone, Debug)] LL | / struct MoreAttrs { LL | | a: i32, @@ -160,7 +160,7 @@ warning: the `#[test]` attribute may only be used on a non-associated function --> $DIR/test-on-not-fn.rs:61:1 | LL | #[test] - | ^^^^^^^ the `#[test]` macro causes a function to be run on a test and has no effect on non-functions + | ^^^^^^^ the `#[test]` macro causes a function to be run as a test and has no effect on non-functions LL | foo!(); | ------- expected a non-associated function, found an item macro invocation | diff --git a/tests/ui/trait-bounds/impl-bound-with-references-error.stderr b/tests/ui/trait-bounds/impl-bound-with-references-error.stderr index 95fd6bd504c..b114d295d78 100644 --- a/tests/ui/trait-bounds/impl-bound-with-references-error.stderr +++ b/tests/ui/trait-bounds/impl-bound-with-references-error.stderr @@ -6,7 +6,7 @@ LL | T: Into<Cow<'static, str>>, | help: consider importing this enum | -LL | use std::borrow::Cow; +LL + use std::borrow::Cow; | error[E0119]: conflicting implementations of trait `From<LabelText>` for type `LabelText` diff --git a/tests/ui/trait-bounds/shadowed-path-in-trait-bound-suggestion.stderr b/tests/ui/trait-bounds/shadowed-path-in-trait-bound-suggestion.stderr index b297662955e..4547e1c984c 100644 --- a/tests/ui/trait-bounds/shadowed-path-in-trait-bound-suggestion.stderr +++ b/tests/ui/trait-bounds/shadowed-path-in-trait-bound-suggestion.stderr @@ -6,7 +6,7 @@ LL | pub struct A<H: A::Trait>(pub H); | help: consider importing this trait | -LL | use A::Trait; +LL + use A::Trait; | help: if you import `Trait`, refer to it directly | diff --git a/tests/ui/traits/inductive-overflow/supertrait-auto-trait.stderr b/tests/ui/traits/inductive-overflow/supertrait-auto-trait.stderr index dc967d51298..e723c7c5181 100644 --- a/tests/ui/traits/inductive-overflow/supertrait-auto-trait.stderr +++ b/tests/ui/traits/inductive-overflow/supertrait-auto-trait.stderr @@ -26,7 +26,8 @@ LL | fn copy<T: Magic>(x: T) -> (T, T) { (x, x) } | ^^^^^ required by this bound in `copy` help: consider annotating `NoClone` with `#[derive(Copy)]` | -LL | #[derive(Copy)] +LL + #[derive(Copy)] +LL | struct NoClone; | error: aborting due to 2 previous errors diff --git a/tests/ui/traits/issue-71136.stderr b/tests/ui/traits/issue-71136.stderr index f541733929d..ef55796187e 100644 --- a/tests/ui/traits/issue-71136.stderr +++ b/tests/ui/traits/issue-71136.stderr @@ -11,7 +11,8 @@ LL | the_foos: Vec<Foo>, = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider annotating `Foo` with `#[derive(Clone)]` | -LL | #[derive(Clone)] +LL + #[derive(Clone)] +LL | struct Foo(u8); | error: aborting due to previous error diff --git a/tests/ui/traits/issue-78372.stderr b/tests/ui/traits/issue-78372.stderr index 8e7fd5f2557..ec692ff911d 100644 --- a/tests/ui/traits/issue-78372.stderr +++ b/tests/ui/traits/issue-78372.stderr @@ -6,7 +6,7 @@ LL | struct Smaht<T, MISC>(PhantomData); | help: consider importing this struct | -LL | use std::marker::PhantomData; +LL + use std::marker::PhantomData; | error[E0412]: cannot find type `U` in this scope diff --git a/tests/ui/traits/item-privacy.stderr b/tests/ui/traits/item-privacy.stderr index 04995b3a17b..f5381318925 100644 --- a/tests/ui/traits/item-privacy.stderr +++ b/tests/ui/traits/item-privacy.stderr @@ -29,7 +29,7 @@ LL | S.b(); = help: items from traits can only be used if the trait is in scope help: the following trait is implemented but not in scope; perhaps add a `use` for it: | -LL | use method::B; +LL + use method::B; | error[E0624]: method `a` is private @@ -69,7 +69,7 @@ LL | S::b(&S); = help: items from traits can only be used if the trait is in scope help: the following trait is implemented but not in scope; perhaps add a `use` for it: | -LL | use method::B; +LL + use method::B; | error[E0624]: method `a` is private @@ -109,7 +109,7 @@ LL | S::B; = help: items from traits can only be used if the trait is in scope help: the following trait is implemented but not in scope; perhaps add a `use` for it: | -LL | use assoc_const::B; +LL + use assoc_const::B; | error[E0624]: associated constant `A` is private diff --git a/tests/ui/traits/method-private.stderr b/tests/ui/traits/method-private.stderr index 55656f21e00..e11799308c5 100644 --- a/tests/ui/traits/method-private.stderr +++ b/tests/ui/traits/method-private.stderr @@ -10,7 +10,7 @@ LL | foo.method(); = help: items from traits can only be used if the trait is in scope help: the following trait is implemented but not in scope; perhaps add a `use` for it: | -LL | use inner::Bar; +LL + use inner::Bar; | error: aborting due to previous error diff --git a/tests/ui/traits/new-solver/recursive-self-normalization-2.rs b/tests/ui/traits/new-solver/recursive-self-normalization-2.rs index 7417d6018a1..8c029f5179d 100644 --- a/tests/ui/traits/new-solver/recursive-self-normalization-2.rs +++ b/tests/ui/traits/new-solver/recursive-self-normalization-2.rs @@ -13,7 +13,7 @@ fn needs_bar<S: Bar>() {} fn test<T: Foo1<Assoc1 = <T as Foo2>::Assoc2> + Foo2<Assoc2 = <T as Foo1>::Assoc1>>() { needs_bar::<T::Assoc1>(); - //~^ ERROR type annotations needed + //~^ ERROR overflow evaluating the requirement `<T as Foo1>::Assoc1: Bar` } fn main() {} diff --git a/tests/ui/traits/new-solver/recursive-self-normalization-2.stderr b/tests/ui/traits/new-solver/recursive-self-normalization-2.stderr index e3a92e85e17..139b0a45680 100644 --- a/tests/ui/traits/new-solver/recursive-self-normalization-2.stderr +++ b/tests/ui/traits/new-solver/recursive-self-normalization-2.stderr @@ -1,10 +1,10 @@ -error[E0283]: type annotations needed: cannot satisfy `<T as Foo1>::Assoc1: Bar` +error[E0275]: overflow evaluating the requirement `<T as Foo1>::Assoc1: Bar` --> $DIR/recursive-self-normalization-2.rs:15:5 | LL | needs_bar::<T::Assoc1>(); | ^^^^^^^^^^^^^^^^^^^^^^ | - = note: cannot satisfy `<T as Foo1>::Assoc1: Bar` + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`recursive_self_normalization_2`) note: required by a bound in `needs_bar` --> $DIR/recursive-self-normalization-2.rs:12:17 | @@ -13,4 +13,4 @@ LL | fn needs_bar<S: Bar>() {} error: aborting due to previous error -For more information about this error, try `rustc --explain E0283`. +For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/traits/new-solver/recursive-self-normalization.rs b/tests/ui/traits/new-solver/recursive-self-normalization.rs index f3e3d71d813..06d187b5fdf 100644 --- a/tests/ui/traits/new-solver/recursive-self-normalization.rs +++ b/tests/ui/traits/new-solver/recursive-self-normalization.rs @@ -9,7 +9,7 @@ fn needs_bar<S: Bar>() {} fn test<T: Foo<Assoc = <T as Foo>::Assoc>>() { needs_bar::<T::Assoc>(); - //~^ ERROR type annotations needed + //~^ ERROR overflow evaluating the requirement `<T as Foo>::Assoc: Bar` } fn main() {} diff --git a/tests/ui/traits/new-solver/recursive-self-normalization.stderr b/tests/ui/traits/new-solver/recursive-self-normalization.stderr index 773007aebaa..8e9b9b4b4ce 100644 --- a/tests/ui/traits/new-solver/recursive-self-normalization.stderr +++ b/tests/ui/traits/new-solver/recursive-self-normalization.stderr @@ -1,10 +1,10 @@ -error[E0283]: type annotations needed: cannot satisfy `<T as Foo>::Assoc: Bar` +error[E0275]: overflow evaluating the requirement `<T as Foo>::Assoc: Bar` --> $DIR/recursive-self-normalization.rs:11:5 | LL | needs_bar::<T::Assoc>(); | ^^^^^^^^^^^^^^^^^^^^^ | - = note: cannot satisfy `<T as Foo>::Assoc: Bar` + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`recursive_self_normalization`) note: required by a bound in `needs_bar` --> $DIR/recursive-self-normalization.rs:8:17 | @@ -13,4 +13,4 @@ LL | fn needs_bar<S: Bar>() {} error: aborting due to previous error -For more information about this error, try `rustc --explain E0283`. +For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/traits/non_lifetime_binders/missing-assoc-item.stderr b/tests/ui/traits/non_lifetime_binders/missing-assoc-item.stderr index be6955c111e..d985386423d 100644 --- a/tests/ui/traits/non_lifetime_binders/missing-assoc-item.stderr +++ b/tests/ui/traits/non_lifetime_binders/missing-assoc-item.stderr @@ -11,7 +11,12 @@ error[E0223]: ambiguous associated type --> $DIR/missing-assoc-item.rs:6:12 | LL | for<B> B::Item: Send, - | ^^^^^^^ help: use the fully-qualified path: `<B as IntoIterator>::Item` + | ^^^^^^^ + | +help: if there were a trait named `Example` with associated type `Item` implemented for `B`, you could use the fully-qualified path + | +LL | for<B> <B as Example>::Item: Send, + | ~~~~~~~~~~~~~~~~~~~~ error: aborting due to previous error; 1 warning emitted diff --git a/tests/ui/type-alias-impl-trait/assoc-type-const.rs b/tests/ui/type-alias-impl-trait/assoc-type-const.rs index 0ade36dafa4..62f66914ee3 100644 --- a/tests/ui/type-alias-impl-trait/assoc-type-const.rs +++ b/tests/ui/type-alias-impl-trait/assoc-type-const.rs @@ -2,7 +2,7 @@ // const generics in an associated opaque type // check-pass -#![feature(type_alias_impl_trait)] +#![feature(impl_trait_in_assoc_type)] trait UnwrapItemsExt<'a, const C: usize> { type Iter; diff --git a/tests/ui/type-alias-impl-trait/assoc-type-lifetime-unconstrained.rs b/tests/ui/type-alias-impl-trait/assoc-type-lifetime-unconstrained.rs index 3f34b00ec77..7c7c68ad60a 100644 --- a/tests/ui/type-alias-impl-trait/assoc-type-lifetime-unconstrained.rs +++ b/tests/ui/type-alias-impl-trait/assoc-type-lifetime-unconstrained.rs @@ -1,7 +1,7 @@ // Tests that we don't allow unconstrained lifetime parameters in impls when // the lifetime is used in an associated opaque type. -#![feature(type_alias_impl_trait)] +#![feature(impl_trait_in_assoc_type)] trait UnwrapItemsExt { type Iter; diff --git a/tests/ui/type-alias-impl-trait/assoc-type-lifetime.rs b/tests/ui/type-alias-impl-trait/assoc-type-lifetime.rs index 39f785d8cc5..81dacbcfb7e 100644 --- a/tests/ui/type-alias-impl-trait/assoc-type-lifetime.rs +++ b/tests/ui/type-alias-impl-trait/assoc-type-lifetime.rs @@ -2,7 +2,7 @@ // lifetimes are used in an associated opaque type // check-pass -#![feature(type_alias_impl_trait)] +#![feature(impl_trait_in_assoc_type)] trait UnwrapItemsExt<'a> { type Iter; diff --git a/tests/ui/type-alias-impl-trait/associated-type-impl-trait-lifetime.rs b/tests/ui/type-alias-impl-trait/associated-type-impl-trait-lifetime.rs index 962606508be..551815d021a 100644 --- a/tests/ui/type-alias-impl-trait/associated-type-impl-trait-lifetime.rs +++ b/tests/ui/type-alias-impl-trait/associated-type-impl-trait-lifetime.rs @@ -1,6 +1,6 @@ //check-pass -#![feature(type_alias_impl_trait)] +#![feature(impl_trait_in_assoc_type)] trait Trait { type Opaque1; diff --git a/tests/ui/type-alias-impl-trait/auxiliary/collect_hidden_types.rs b/tests/ui/type-alias-impl-trait/auxiliary/collect_hidden_types.rs index 75d20a6fef9..444a4e6957f 100644 --- a/tests/ui/type-alias-impl-trait/auxiliary/collect_hidden_types.rs +++ b/tests/ui/type-alias-impl-trait/auxiliary/collect_hidden_types.rs @@ -1,4 +1,4 @@ -#![feature(type_alias_impl_trait)] +#![feature(impl_trait_in_assoc_type)] // edition:2018 diff --git a/tests/ui/type-alias-impl-trait/auxiliary/cross_crate_ice2.rs b/tests/ui/type-alias-impl-trait/auxiliary/cross_crate_ice2.rs index 119f7df1ffd..98c9615035a 100644 --- a/tests/ui/type-alias-impl-trait/auxiliary/cross_crate_ice2.rs +++ b/tests/ui/type-alias-impl-trait/auxiliary/cross_crate_ice2.rs @@ -1,7 +1,7 @@ // Crate that exports an opaque `impl Trait` type. Used for testing cross-crate. #![crate_type = "rlib"] -#![feature(type_alias_impl_trait)] +#![feature(impl_trait_in_assoc_type)] pub trait View { type Tmp: Iterator<Item = u32>; diff --git a/tests/ui/type-alias-impl-trait/impl-with-unconstrained-param.rs b/tests/ui/type-alias-impl-trait/impl-with-unconstrained-param.rs index 851c2f66c47..1824ff5e2fb 100644 --- a/tests/ui/type-alias-impl-trait/impl-with-unconstrained-param.rs +++ b/tests/ui/type-alias-impl-trait/impl-with-unconstrained-param.rs @@ -1,7 +1,7 @@ // Ensure that we don't ICE if associated type impl trait is used in an impl // with an unconstrained type parameter. -#![feature(type_alias_impl_trait)] +#![feature(impl_trait_in_assoc_type)] trait X { type I; diff --git a/tests/ui/type-alias-impl-trait/imply_bounds_from_bounds.rs b/tests/ui/type-alias-impl-trait/imply_bounds_from_bounds.rs index ee9bce15d34..4f99236f4ea 100644 --- a/tests/ui/type-alias-impl-trait/imply_bounds_from_bounds.rs +++ b/tests/ui/type-alias-impl-trait/imply_bounds_from_bounds.rs @@ -1,6 +1,6 @@ // check-pass -#![feature(type_alias_impl_trait)] +#![feature(impl_trait_in_assoc_type)] trait Callable { type Output; diff --git a/tests/ui/type-alias-impl-trait/imply_bounds_from_bounds_param.rs b/tests/ui/type-alias-impl-trait/imply_bounds_from_bounds_param.rs index ae21a9134a4..5d5645077c2 100644 --- a/tests/ui/type-alias-impl-trait/imply_bounds_from_bounds_param.rs +++ b/tests/ui/type-alias-impl-trait/imply_bounds_from_bounds_param.rs @@ -1,4 +1,4 @@ -#![feature(type_alias_impl_trait)] +#![feature(impl_trait_in_assoc_type)] trait Callable { type Output; @@ -17,7 +17,9 @@ impl<'a> PlusOne for &'a mut i32 { impl<T: PlusOne> Callable for T { type Output = impl PlusOne; - fn call(t: T) -> Self::Output { t } + fn call(t: T) -> Self::Output { + t + } } fn test<'a>(y: &'a mut i32) -> impl PlusOne { diff --git a/tests/ui/type-alias-impl-trait/imply_bounds_from_bounds_param.stderr b/tests/ui/type-alias-impl-trait/imply_bounds_from_bounds_param.stderr index e52d5f9de69..66e4783157b 100644 --- a/tests/ui/type-alias-impl-trait/imply_bounds_from_bounds_param.stderr +++ b/tests/ui/type-alias-impl-trait/imply_bounds_from_bounds_param.stderr @@ -1,5 +1,5 @@ error[E0700]: hidden type for `impl PlusOne` captures lifetime that does not appear in bounds - --> $DIR/imply_bounds_from_bounds_param.rs:24:5 + --> $DIR/imply_bounds_from_bounds_param.rs:26:5 | LL | fn test<'a>(y: &'a mut i32) -> impl PlusOne { | -- ------------ opaque type defined here diff --git a/tests/ui/type-alias-impl-trait/incoherent-assoc-imp-trait.rs b/tests/ui/type-alias-impl-trait/incoherent-assoc-imp-trait.rs index 685d76ee36f..8df59c68fef 100644 --- a/tests/ui/type-alias-impl-trait/incoherent-assoc-imp-trait.rs +++ b/tests/ui/type-alias-impl-trait/incoherent-assoc-imp-trait.rs @@ -1,7 +1,7 @@ // Regression test for issue 67856 #![feature(unboxed_closures)] -#![feature(type_alias_impl_trait)] +#![feature(impl_trait_in_assoc_type)] #![feature(fn_traits)] trait MyTrait {} diff --git a/tests/ui/type-alias-impl-trait/issue-53598.rs b/tests/ui/type-alias-impl-trait/issue-53598.rs index 9c1cbf926f5..e3e2787b66b 100644 --- a/tests/ui/type-alias-impl-trait/issue-53598.rs +++ b/tests/ui/type-alias-impl-trait/issue-53598.rs @@ -1,4 +1,4 @@ -#![feature(type_alias_impl_trait)] +#![feature(impl_trait_in_assoc_type)] use std::fmt::Debug; diff --git a/tests/ui/type-alias-impl-trait/issue-57188-associate-impl-capture.rs b/tests/ui/type-alias-impl-trait/issue-57188-associate-impl-capture.rs index 3a7a5da075f..3bdb3bf1d53 100644 --- a/tests/ui/type-alias-impl-trait/issue-57188-associate-impl-capture.rs +++ b/tests/ui/type-alias-impl-trait/issue-57188-associate-impl-capture.rs @@ -2,7 +2,7 @@ // check-pass -#![feature(type_alias_impl_trait)] +#![feature(impl_trait_in_assoc_type)] struct Baz<'a> { source: &'a str, diff --git a/tests/ui/type-alias-impl-trait/issue-57611-trait-alias.rs b/tests/ui/type-alias-impl-trait/issue-57611-trait-alias.rs index cad3e0f6677..3917bb3b6cf 100644 --- a/tests/ui/type-alias-impl-trait/issue-57611-trait-alias.rs +++ b/tests/ui/type-alias-impl-trait/issue-57611-trait-alias.rs @@ -3,7 +3,7 @@ // Ensures that we don't ICE #![feature(trait_alias)] -#![feature(type_alias_impl_trait)] +#![feature(impl_trait_in_assoc_type)] trait Foo { type Bar: Baz<Self, Self>; diff --git a/tests/ui/type-alias-impl-trait/issue-57700.rs b/tests/ui/type-alias-impl-trait/issue-57700.rs index 48458938702..8746545ecc9 100644 --- a/tests/ui/type-alias-impl-trait/issue-57700.rs +++ b/tests/ui/type-alias-impl-trait/issue-57700.rs @@ -1,5 +1,5 @@ #![feature(arbitrary_self_types)] -#![feature(type_alias_impl_trait)] +#![feature(impl_trait_in_assoc_type)] use std::ops::Deref; diff --git a/tests/ui/type-alias-impl-trait/issue-57807-associated-type.rs b/tests/ui/type-alias-impl-trait/issue-57807-associated-type.rs index fcab2c7db26..841bac5f6a0 100644 --- a/tests/ui/type-alias-impl-trait/issue-57807-associated-type.rs +++ b/tests/ui/type-alias-impl-trait/issue-57807-associated-type.rs @@ -2,7 +2,7 @@ // that we properly unify associated types within // a type alias impl trait // check-pass -#![feature(type_alias_impl_trait)] +#![feature(impl_trait_in_assoc_type)] trait Bar { type A; diff --git a/tests/ui/type-alias-impl-trait/issue-58887.rs b/tests/ui/type-alias-impl-trait/issue-58887.rs index 96ac7860283..9675867656a 100644 --- a/tests/ui/type-alias-impl-trait/issue-58887.rs +++ b/tests/ui/type-alias-impl-trait/issue-58887.rs @@ -1,6 +1,6 @@ // run-pass -#![feature(type_alias_impl_trait)] +#![feature(impl_trait_in_assoc_type)] trait UnwrapItemsExt { type Iter; diff --git a/tests/ui/type-alias-impl-trait/issue-60371.rs b/tests/ui/type-alias-impl-trait/issue-60371.rs index 9a40f3d9b64..a6173967333 100644 --- a/tests/ui/type-alias-impl-trait/issue-60371.rs +++ b/tests/ui/type-alias-impl-trait/issue-60371.rs @@ -5,7 +5,7 @@ trait Bug { } impl Bug for &() { - type Item = impl Bug; //~ ERROR `impl Trait` in type aliases is unstable + type Item = impl Bug; //~ ERROR `impl Trait` in associated types is unstable const FUN: fn() -> Self::Item = || (); //~^ ERROR the trait bound `(): Bug` is not satisfied diff --git a/tests/ui/type-alias-impl-trait/issue-60371.stderr b/tests/ui/type-alias-impl-trait/issue-60371.stderr index d0c04371bd7..ffc66473635 100644 --- a/tests/ui/type-alias-impl-trait/issue-60371.stderr +++ b/tests/ui/type-alias-impl-trait/issue-60371.stderr @@ -1,11 +1,11 @@ -error[E0658]: `impl Trait` in type aliases is unstable +error[E0658]: `impl Trait` in associated types is unstable --> $DIR/issue-60371.rs:8:17 | LL | type Item = impl Bug; | ^^^^^^^^ | = note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information - = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable + = help: add `#![feature(impl_trait_in_assoc_type)]` to the crate attributes to enable error[E0277]: the trait bound `(): Bug` is not satisfied --> $DIR/issue-60371.rs:10:40 diff --git a/tests/ui/type-alias-impl-trait/issue-60564-working.rs b/tests/ui/type-alias-impl-trait/issue-60564-working.rs index 38accc8241c..c4687c29de8 100644 --- a/tests/ui/type-alias-impl-trait/issue-60564-working.rs +++ b/tests/ui/type-alias-impl-trait/issue-60564-working.rs @@ -1,4 +1,4 @@ -#![feature(type_alias_impl_trait)] +#![feature(impl_trait_in_assoc_type)] // check-pass diff --git a/tests/ui/type-alias-impl-trait/issue-62000-associate-impl-trait-lifetimes.rs b/tests/ui/type-alias-impl-trait/issue-62000-associate-impl-trait-lifetimes.rs index 36779a0ce89..0245eab7969 100644 --- a/tests/ui/type-alias-impl-trait/issue-62000-associate-impl-trait-lifetimes.rs +++ b/tests/ui/type-alias-impl-trait/issue-62000-associate-impl-trait-lifetimes.rs @@ -2,7 +2,7 @@ // check-pass -#![feature(type_alias_impl_trait)] +#![feature(impl_trait_in_assoc_type)] trait MyTrait { type AssocType: Send; diff --git a/tests/ui/type-alias-impl-trait/issue-74761-2.rs b/tests/ui/type-alias-impl-trait/issue-74761-2.rs index d26ca5c3ead..f582592e9bc 100644 --- a/tests/ui/type-alias-impl-trait/issue-74761-2.rs +++ b/tests/ui/type-alias-impl-trait/issue-74761-2.rs @@ -1,4 +1,4 @@ -#![feature(type_alias_impl_trait)] +#![feature(impl_trait_in_assoc_type)] pub trait A { type B; diff --git a/tests/ui/type-alias-impl-trait/issue-74761.rs b/tests/ui/type-alias-impl-trait/issue-74761.rs index d26ca5c3ead..f582592e9bc 100644 --- a/tests/ui/type-alias-impl-trait/issue-74761.rs +++ b/tests/ui/type-alias-impl-trait/issue-74761.rs @@ -1,4 +1,4 @@ -#![feature(type_alias_impl_trait)] +#![feature(impl_trait_in_assoc_type)] pub trait A { type B; diff --git a/tests/ui/type-alias-impl-trait/issue-78450.rs b/tests/ui/type-alias-impl-trait/issue-78450.rs index fccbfb74fa2..2a984c1ed71 100644 --- a/tests/ui/type-alias-impl-trait/issue-78450.rs +++ b/tests/ui/type-alias-impl-trait/issue-78450.rs @@ -1,6 +1,6 @@ // check-pass -#![feature(type_alias_impl_trait)] +#![feature(impl_trait_in_assoc_type)] pub trait AssociatedImpl { type ImplTrait; diff --git a/tests/ui/type-alias-impl-trait/issue-89952.rs b/tests/ui/type-alias-impl-trait/issue-89952.rs index dc0f19c042a..f0ba9fa7cec 100644 --- a/tests/ui/type-alias-impl-trait/issue-89952.rs +++ b/tests/ui/type-alias-impl-trait/issue-89952.rs @@ -1,6 +1,6 @@ // check-pass -#![feature(type_alias_impl_trait)] +#![feature(impl_trait_in_assoc_type)] trait SomeTrait {} impl SomeTrait for () {} diff --git a/tests/ui/type-alias-impl-trait/issue-90400-1.rs b/tests/ui/type-alias-impl-trait/issue-90400-1.rs index 15aead2f641..50207605748 100644 --- a/tests/ui/type-alias-impl-trait/issue-90400-1.rs +++ b/tests/ui/type-alias-impl-trait/issue-90400-1.rs @@ -1,7 +1,7 @@ // Regression test for #90400, // taken from https://github.com/rust-lang/rust/issues/90400#issuecomment-954927836 -#![feature(type_alias_impl_trait)] +#![feature(impl_trait_in_assoc_type)] trait Bar { fn bar(&self); diff --git a/tests/ui/type-alias-impl-trait/issue-90400-2.rs b/tests/ui/type-alias-impl-trait/issue-90400-2.rs index 4c6e893c172..60ff962ea2e 100644 --- a/tests/ui/type-alias-impl-trait/issue-90400-2.rs +++ b/tests/ui/type-alias-impl-trait/issue-90400-2.rs @@ -1,7 +1,7 @@ // Regression test for #90400, // taken from https://github.com/rust-lang/rust/issues/90400#issuecomment-954927836 -#![feature(type_alias_impl_trait)] +#![feature(impl_trait_in_assoc_type)] trait Bar { fn bar(&self); diff --git a/tests/ui/type-alias-impl-trait/issue-94429.rs b/tests/ui/type-alias-impl-trait/issue-94429.rs index 2c965b875a0..d764545f906 100644 --- a/tests/ui/type-alias-impl-trait/issue-94429.rs +++ b/tests/ui/type-alias-impl-trait/issue-94429.rs @@ -1,4 +1,4 @@ -#![feature(type_alias_impl_trait, generator_trait, generators)] +#![feature(impl_trait_in_assoc_type, generator_trait, generators)] use std::ops::Generator; trait Runnable { @@ -13,7 +13,7 @@ impl Runnable for Implementor { type Gen = impl Generator<Yield = (), Return = ()>; fn run(&mut self) -> Self::Gen { - //~^ ERROR: type mismatch resolving + //~^ ERROR: type mismatch resolving move || { yield 1; } diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-unconstrained-lifetime.rs b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-unconstrained-lifetime.rs index efbf4f1e351..296a3f3e300 100644 --- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-unconstrained-lifetime.rs +++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-unconstrained-lifetime.rs @@ -1,6 +1,6 @@ // regression test for #74018 -#![feature(type_alias_impl_trait)] +#![feature(impl_trait_in_assoc_type)] trait Trait { type Associated; diff --git a/tests/ui/typeck/explain_clone_autoref.stderr b/tests/ui/typeck/explain_clone_autoref.stderr index 4539da4389b..38cb7fe5518 100644 --- a/tests/ui/typeck/explain_clone_autoref.stderr +++ b/tests/ui/typeck/explain_clone_autoref.stderr @@ -14,7 +14,8 @@ LL | nc.clone() | ^^ help: consider annotating `NotClone` with `#[derive(Clone)]` | -LL | #[derive(Clone)] +LL + #[derive(Clone)] +LL | struct NotClone; | error: aborting due to previous error diff --git a/tests/ui/typeck/issue-110052.rs b/tests/ui/typeck/issue-110052.rs new file mode 100644 index 00000000000..f124b58b5b6 --- /dev/null +++ b/tests/ui/typeck/issue-110052.rs @@ -0,0 +1,12 @@ +// Makes sure we deal with escaping lifetimes *above* INNERMOST when +// suggesting trait for ambiguous associated type. + +impl<I, V> Validator<I> for () +where + for<'iter> dyn Validator<<&'iter I>::Item>:, + //~^ ERROR ambiguous associated type +{} + +pub trait Validator<T> {} + +fn main() {} diff --git a/tests/ui/typeck/issue-110052.stderr b/tests/ui/typeck/issue-110052.stderr new file mode 100644 index 00000000000..0c15c03a740 --- /dev/null +++ b/tests/ui/typeck/issue-110052.stderr @@ -0,0 +1,9 @@ +error[E0223]: ambiguous associated type + --> $DIR/issue-110052.rs:6:30 + | +LL | for<'iter> dyn Validator<<&'iter I>::Item>:, + | ^^^^^^^^^^^^^^^^ help: use the fully-qualified path: `<&'iter I as IntoIterator>::Item` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0223`. diff --git a/tests/ui/typeck/issue-43189.stderr b/tests/ui/typeck/issue-43189.stderr index caf7530b85a..c072e6a08ba 100644 --- a/tests/ui/typeck/issue-43189.stderr +++ b/tests/ui/typeck/issue-43189.stderr @@ -12,7 +12,7 @@ LL | fn a(&self) {} = help: items from traits can only be used if the trait is in scope help: the following trait is implemented but not in scope; perhaps add a `use` for it: | -LL | use xcrate_issue_43189_b::xcrate_issue_43189_a::A; +LL + use xcrate_issue_43189_b::xcrate_issue_43189_a::A; | error: aborting due to previous error diff --git a/tests/ui/underscore-imports/shadow.stderr b/tests/ui/underscore-imports/shadow.stderr index 7faede4e6d0..f2c19405bbb 100644 --- a/tests/ui/underscore-imports/shadow.stderr +++ b/tests/ui/underscore-imports/shadow.stderr @@ -7,7 +7,7 @@ LL | x.deref(); = help: items from traits can only be used if the trait is in scope help: the following trait is implemented but not in scope; perhaps add a `use` for it: | -LL | use std::ops::Deref; +LL + use std::ops::Deref; | error: aborting due to previous error diff --git a/tests/ui/union/union-derive-clone.mirunsafeck.stderr b/tests/ui/union/union-derive-clone.mirunsafeck.stderr index b80e8b988ad..4d23d230fa3 100644 --- a/tests/ui/union/union-derive-clone.mirunsafeck.stderr +++ b/tests/ui/union/union-derive-clone.mirunsafeck.stderr @@ -9,7 +9,8 @@ note: required by a bound in `AssertParamIsCopy` = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider annotating `U1` with `#[derive(Copy)]` | -LL | #[derive(Copy)] +LL + #[derive(Copy)] +LL | union U1 { | error[E0599]: the method `clone` exists for union `U5<CloneNoCopy>`, but its trait bounds were not satisfied @@ -34,7 +35,8 @@ LL | #[derive(Clone, Copy)] | ^^^^^ unsatisfied trait bound introduced in this `derive` macro help: consider annotating `CloneNoCopy` with `#[derive(Clone, Copy)]` | -LL | #[derive(Clone, Copy)] +LL + #[derive(Clone, Copy)] +LL | struct CloneNoCopy; | error: aborting due to 2 previous errors diff --git a/tests/ui/union/union-derive-clone.thirunsafeck.stderr b/tests/ui/union/union-derive-clone.thirunsafeck.stderr index b80e8b988ad..4d23d230fa3 100644 --- a/tests/ui/union/union-derive-clone.thirunsafeck.stderr +++ b/tests/ui/union/union-derive-clone.thirunsafeck.stderr @@ -9,7 +9,8 @@ note: required by a bound in `AssertParamIsCopy` = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider annotating `U1` with `#[derive(Copy)]` | -LL | #[derive(Copy)] +LL + #[derive(Copy)] +LL | union U1 { | error[E0599]: the method `clone` exists for union `U5<CloneNoCopy>`, but its trait bounds were not satisfied @@ -34,7 +35,8 @@ LL | #[derive(Clone, Copy)] | ^^^^^ unsatisfied trait bound introduced in this `derive` macro help: consider annotating `CloneNoCopy` with `#[derive(Clone, Copy)]` | -LL | #[derive(Clone, Copy)] +LL + #[derive(Clone, Copy)] +LL | struct CloneNoCopy; | error: aborting due to 2 previous errors diff --git a/tests/ui/union/union-derive-eq.mirunsafeck.stderr b/tests/ui/union/union-derive-eq.mirunsafeck.stderr index 9e55390b54d..136cd883e26 100644 --- a/tests/ui/union/union-derive-eq.mirunsafeck.stderr +++ b/tests/ui/union/union-derive-eq.mirunsafeck.stderr @@ -12,7 +12,8 @@ note: required by a bound in `AssertParamIsEq` = note: this error originates in the derive macro `Eq` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider annotating `PartialEqNotEq` with `#[derive(Eq)]` | -LL | #[derive(Eq)] +LL + #[derive(Eq)] +LL | struct PartialEqNotEq; | error: aborting due to previous error diff --git a/tests/ui/union/union-derive-eq.thirunsafeck.stderr b/tests/ui/union/union-derive-eq.thirunsafeck.stderr index 9e55390b54d..136cd883e26 100644 --- a/tests/ui/union/union-derive-eq.thirunsafeck.stderr +++ b/tests/ui/union/union-derive-eq.thirunsafeck.stderr @@ -12,7 +12,8 @@ note: required by a bound in `AssertParamIsEq` = note: this error originates in the derive macro `Eq` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider annotating `PartialEqNotEq` with `#[derive(Eq)]` | -LL | #[derive(Eq)] +LL + #[derive(Eq)] +LL | struct PartialEqNotEq; | error: aborting due to previous error diff --git a/tests/ui/unresolved/unresolved-candidates.stderr b/tests/ui/unresolved/unresolved-candidates.stderr index ea737c567b9..7ef2f6b1a29 100644 --- a/tests/ui/unresolved/unresolved-candidates.stderr +++ b/tests/ui/unresolved/unresolved-candidates.stderr @@ -17,7 +17,7 @@ LL | impl Trait for () {} | help: consider importing this trait | -LL | use a::Trait; +LL + use a::Trait; | error: aborting due to 2 previous errors diff --git a/tests/ui/wf/issue-110157.rs b/tests/ui/wf/issue-110157.rs new file mode 100644 index 00000000000..43a8ce72ff1 --- /dev/null +++ b/tests/ui/wf/issue-110157.rs @@ -0,0 +1,12 @@ +struct NeedsDropTypes<'tcx, F>(std::marker::PhantomData<&'tcx F>); + +impl<'tcx, F, I> Iterator for NeedsDropTypes<'tcx, F> +//~^ ERROR type annotations needed +where + F: Fn(&Missing) -> Result<I, ()>, + //~^ ERROR cannot find type `Missing` in this scope + I: Iterator<Item = Missing>, + //~^ ERROR cannot find type `Missing` in this scope +{} + +fn main() {} diff --git a/tests/ui/wf/issue-110157.stderr b/tests/ui/wf/issue-110157.stderr new file mode 100644 index 00000000000..91d801e9470 --- /dev/null +++ b/tests/ui/wf/issue-110157.stderr @@ -0,0 +1,32 @@ +error[E0412]: cannot find type `Missing` in this scope + --> $DIR/issue-110157.rs:6:12 + | +LL | F: Fn(&Missing) -> Result<I, ()>, + | ^^^^^^^ not found in this scope + +error[E0412]: cannot find type `Missing` in this scope + --> $DIR/issue-110157.rs:8:24 + | +LL | I: Iterator<Item = Missing>, + | ^^^^^^^ not found in this scope + +error[E0283]: type annotations needed + --> $DIR/issue-110157.rs:3:31 + | +LL | impl<'tcx, F, I> Iterator for NeedsDropTypes<'tcx, F> + | ^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `I` + | + = note: cannot satisfy `_: Iterator` +note: required for `NeedsDropTypes<'tcx, F>` to implement `Iterator` + --> $DIR/issue-110157.rs:3:18 + | +LL | impl<'tcx, F, I> Iterator for NeedsDropTypes<'tcx, F> + | ^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | I: Iterator<Item = Missing>, + | ------------------------ unsatisfied trait bound introduced here + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0283, E0412. +For more information about an error, try `rustc --explain E0283`. diff --git a/tests/ui/wf/wf-const-type.stderr b/tests/ui/wf/wf-const-type.stderr index 85938364ede..617969720a6 100644 --- a/tests/ui/wf/wf-const-type.stderr +++ b/tests/ui/wf/wf-const-type.stderr @@ -12,7 +12,8 @@ LL | struct IsCopy<T:Copy> { t: T } | ^^^^ required by this bound in `IsCopy` help: consider annotating `NotCopy` with `#[derive(Copy)]` | -LL | #[derive(Copy)] +LL + #[derive(Copy)] +LL | struct NotCopy; | error: aborting due to previous error diff --git a/tests/ui/wf/wf-static-type.stderr b/tests/ui/wf/wf-static-type.stderr index 16c6124b652..bb5a57834eb 100644 --- a/tests/ui/wf/wf-static-type.stderr +++ b/tests/ui/wf/wf-static-type.stderr @@ -12,7 +12,8 @@ LL | struct IsCopy<T:Copy> { t: T } | ^^^^ required by this bound in `IsCopy` help: consider annotating `NotCopy` with `#[derive(Copy)]` | -LL | #[derive(Copy)] +LL + #[derive(Copy)] +LL | struct NotCopy; | error: aborting due to previous error diff --git a/tests/ui/where-clauses/where-clauses-method-unsatisfied.stderr b/tests/ui/where-clauses/where-clauses-method-unsatisfied.stderr index e90502977ff..6cf71729514 100644 --- a/tests/ui/where-clauses/where-clauses-method-unsatisfied.stderr +++ b/tests/ui/where-clauses/where-clauses-method-unsatisfied.stderr @@ -11,7 +11,8 @@ LL | fn equals(&self, u: &Foo<T>) -> bool where T : Eq { | ^^ required by this bound in `Foo::<T>::equals` help: consider annotating `Bar` with `#[derive(Eq)]` | -LL | #[derive(Eq)] +LL + #[derive(Eq)] +LL | struct Bar; // does not implement Eq | error: aborting due to previous error diff --git a/tests/ui/where-clauses/where-clauses-unsatisfied.stderr b/tests/ui/where-clauses/where-clauses-unsatisfied.stderr index b1805a4522f..4d239bf4307 100644 --- a/tests/ui/where-clauses/where-clauses-unsatisfied.stderr +++ b/tests/ui/where-clauses/where-clauses-unsatisfied.stderr @@ -11,7 +11,8 @@ LL | fn equal<T>(a: &T, b: &T) -> bool where T : Eq { a == b } | ^^ required by this bound in `equal` help: consider annotating `Struct` with `#[derive(Eq)]` | -LL | #[derive(Eq)] +LL + #[derive(Eq)] +LL | struct Struct; | error: aborting due to previous error |
