diff options
| author | bors <bors@rust-lang.org> | 2025-01-21 12:33:33 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2025-01-21 12:33:33 +0000 |
| commit | cd805f09ffbfa3896c8f50a619de9b67e1d9f3c3 (patch) | |
| tree | 47b1e83d312b17963558a651199af49e065bdb24 | |
| parent | a7a6c64a657f68113301c2ffe0745b49a16442d1 (diff) | |
| parent | 824a867e82b540503f8ae1f589445d9f9a8ce941 (diff) | |
| download | rust-cd805f09ffbfa3896c8f50a619de9b67e1d9f3c3.tar.gz rust-cd805f09ffbfa3896c8f50a619de9b67e1d9f3c3.zip | |
Auto merge of #133830 - compiler-errors:span-key, r=lcnr
Rework dyn trait lowering to stop being so intertwined with trait alias expansion This PR reworks the trait object lowering code to stop handling trait aliases so funky, and removes the `TraitAliasExpander` in favor of a much simpler design. This refactoring is important for making the code that I'm writing in https://github.com/rust-lang/rust/pull/133397 understandable and easy to maintain, so the diagnostics regressions are IMO inevitable. In the old trait object lowering code, we used to be a bit sloppy with the lists of traits in their unexpanded and expanded forms. This PR largely rewrites this logic to expand the trait aliases *once* and handle them more responsibly throughout afterwards. Please review this with whitespace disabled. r? lcnr
26 files changed, 561 insertions, 642 deletions
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs index 71a5727ed6c..72ad190df7e 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs @@ -4,13 +4,12 @@ use rustc_errors::struct_span_code_err; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_lint_defs::builtin::UNUSED_ASSOCIATED_TYPE_BOUNDS; -use rustc_middle::span_bug; use rustc_middle::ty::fold::BottomUpFolder; use rustc_middle::ty::{ self, DynKind, ExistentialPredicateStableCmpExt as _, Ty, TyCtxt, TypeFoldable, TypeVisitableExt, Upcast, }; -use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span}; +use rustc_span::{ErrorGuaranteed, Span}; use rustc_trait_selection::error_reporting::traits::report_dyn_incompatibility; use rustc_trait_selection::traits::{self, hir_ty_lowering_dyn_compatibility_violations}; use rustc_type_ir::elaborate::ClauseWithSupertraitSpan; @@ -30,16 +29,16 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { &self, span: Span, hir_id: hir::HirId, - hir_trait_bounds: &[hir::PolyTraitRef<'tcx>], + hir_bounds: &[hir::PolyTraitRef<'tcx>], lifetime: &hir::Lifetime, representation: DynKind, ) -> Ty<'tcx> { let tcx = self.tcx(); + let dummy_self = tcx.types.trait_object_dummy_self; - let mut bounds = Bounds::default(); + let mut user_written_bounds = Bounds::default(); let mut potential_assoc_types = Vec::new(); - let dummy_self = self.tcx().types.trait_object_dummy_self; - for trait_bound in hir_trait_bounds.iter().rev() { + for trait_bound in hir_bounds.iter() { if let hir::BoundPolarity::Maybe(_) = trait_bound.modifiers.polarity { continue; } @@ -53,92 +52,67 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { hir::BoundConstness::Never, hir::BoundPolarity::Positive, dummy_self, - &mut bounds, + &mut user_written_bounds, PredicateFilter::SelfOnly, ) { potential_assoc_types.extend(cur_potential_assoc_types); } } - let mut trait_bounds = vec![]; - let mut projection_bounds = vec![]; - for (pred, span) in bounds.clauses() { - let bound_pred = pred.kind(); - match bound_pred.skip_binder() { - ty::ClauseKind::Trait(trait_pred) => { - assert_eq!(trait_pred.polarity, ty::PredicatePolarity::Positive); - trait_bounds.push((bound_pred.rebind(trait_pred.trait_ref), span)); - } - ty::ClauseKind::Projection(proj) => { - projection_bounds.push((bound_pred.rebind(proj), span)); - } - ty::ClauseKind::TypeOutlives(_) => { - // Do nothing, we deal with regions separately - } - ty::ClauseKind::RegionOutlives(_) - | ty::ClauseKind::ConstArgHasType(..) - | ty::ClauseKind::WellFormed(_) - | ty::ClauseKind::ConstEvaluatable(_) - | ty::ClauseKind::HostEffect(..) => { - span_bug!(span, "did not expect {pred} clause in object bounds"); - } - } - } - - // Expand trait aliases recursively and check that only one regular (non-auto) trait - // is used and no 'maybe' bounds are used. - let expanded_traits = - traits::expand_trait_aliases(tcx, trait_bounds.iter().map(|&(a, b)| (a, b))); - - let (mut auto_traits, regular_traits): (Vec<_>, Vec<_>) = - expanded_traits.partition(|i| tcx.trait_is_auto(i.trait_ref().def_id())); + let (trait_bounds, mut projection_bounds) = + traits::expand_trait_aliases(tcx, user_written_bounds.clauses()); + let (regular_traits, mut auto_traits): (Vec<_>, Vec<_>) = trait_bounds + .into_iter() + .partition(|(trait_ref, _)| !tcx.trait_is_auto(trait_ref.def_id())); + // We don't support empty trait objects. + if regular_traits.is_empty() && auto_traits.is_empty() { + let guar = + self.report_trait_object_with_no_traits_error(span, user_written_bounds.clauses()); + return Ty::new_error(tcx, guar); + } // We don't support >1 principal if regular_traits.len() > 1 { let guar = self.report_trait_object_addition_traits_error(®ular_traits); return Ty::new_error(tcx, guar); } - // We don't support empty trait objects. - if regular_traits.is_empty() && auto_traits.is_empty() { - let guar = self.report_trait_object_with_no_traits_error(span, &trait_bounds); - return Ty::new_error(tcx, guar); - } // Don't create a dyn trait if we have errors in the principal. - if let Err(guar) = trait_bounds.error_reported() { + if let Err(guar) = regular_traits.error_reported() { return Ty::new_error(tcx, guar); } // Check that there are no gross dyn-compatibility violations; // most importantly, that the supertraits don't contain `Self`, // to avoid ICEs. - for item in ®ular_traits { - let violations = - hir_ty_lowering_dyn_compatibility_violations(tcx, item.trait_ref().def_id()); - if !violations.is_empty() { - let reported = report_dyn_incompatibility( - tcx, - span, - Some(hir_id), - item.trait_ref().def_id(), - &violations, - ) - .emit(); - return Ty::new_error(tcx, reported); + for (clause, span) in user_written_bounds.clauses() { + if let Some(trait_pred) = clause.as_trait_clause() { + let violations = + hir_ty_lowering_dyn_compatibility_violations(tcx, trait_pred.def_id()); + if !violations.is_empty() { + let reported = report_dyn_incompatibility( + tcx, + span, + Some(hir_id), + trait_pred.def_id(), + &violations, + ) + .emit(); + return Ty::new_error(tcx, reported); + } } } - let mut needed_associated_types = FxIndexSet::default(); - - let principal_span = regular_traits.first().map_or(DUMMY_SP, |info| info.bottom().1); - let regular_traits_refs_spans = trait_bounds - .into_iter() - .filter(|(trait_ref, _)| !tcx.trait_is_auto(trait_ref.def_id())); + let principal_trait = regular_traits.into_iter().next(); - for (base_trait_ref, original_span) in regular_traits_refs_spans { - let base_pred: ty::Predicate<'tcx> = base_trait_ref.upcast(tcx); + let mut needed_associated_types = FxIndexSet::default(); + if let Some((principal_trait, spans)) = &principal_trait { + let pred: ty::Predicate<'tcx> = (*principal_trait).upcast(tcx); for ClauseWithSupertraitSpan { pred, supertrait_span } in - traits::elaborate(tcx, [ClauseWithSupertraitSpan::new(base_pred, original_span)]) - .filter_only_self() + traits::elaborate(tcx, [ClauseWithSupertraitSpan::new( + pred, + *spans.last().unwrap(), + )]) + .filter_only_self() { debug!("observing object predicate `{pred:?}`"); @@ -179,7 +153,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // } // ``` // - // Here, the user could theoretically write `dyn MyTrait<Output = X>`, + // Here, the user could theoretically write `dyn MyTrait<MyOutput = X>`, // but actually supporting that would "expand" to an infinitely-long type // `fix $ τ → dyn MyTrait<MyOutput = X, Output = <τ as MyTrait>::MyOutput`. // @@ -188,12 +162,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // the discussion in #56288 for alternatives. if !references_self { // Include projections defined on supertraits. - projection_bounds.push((pred, original_span)); + projection_bounds.push((pred, supertrait_span)); } self.check_elaborated_projection_mentions_input_lifetimes( pred, - original_span, + *spans.first().unwrap(), supertrait_span, ); } @@ -202,11 +176,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } } - // `dyn Trait<Assoc = Foo>` desugars to (not Rust syntax) `dyn Trait where <Self as Trait>::Assoc = Foo`. - // So every `Projection` clause is an `Assoc = Foo` bound. `associated_types` contains all associated - // types's `DefId`, so the following loop removes all the `DefIds` of the associated types that have a - // corresponding `Projection` clause - for (projection_bound, span) in &projection_bounds { + // `dyn Trait<Assoc = Foo>` desugars to (not Rust syntax) `dyn Trait where + // <Self as Trait>::Assoc = Foo`. So every `Projection` clause is an + // `Assoc = Foo` bound. `needed_associated_types` contains all associated + // types that we expect to be provided by the user, so the following loop + // removes all the associated types that have a corresponding `Projection` + // clause, either from expanding trait aliases or written by the user. + for &(projection_bound, span) in &projection_bounds { let def_id = projection_bound.item_def_id(); let trait_ref = tcx.anonymize_bound_vars( projection_bound.map_bound(|p| p.projection_term.trait_ref(tcx)), @@ -216,17 +192,17 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { tcx.emit_node_span_lint( UNUSED_ASSOCIATED_TYPE_BOUNDS, hir_id, - *span, - crate::errors::UnusedAssociatedTypeBounds { span: *span }, + span, + crate::errors::UnusedAssociatedTypeBounds { span }, ); } } if let Err(guar) = self.check_for_required_assoc_tys( - principal_span, + principal_trait.as_ref().map_or(smallvec![], |(_, spans)| spans.clone()), needed_associated_types, potential_assoc_types, - hir_trait_bounds, + hir_bounds, ) { return Ty::new_error(tcx, guar); } @@ -236,32 +212,36 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // We remove duplicates by inserting into a `FxHashSet` to avoid re-ordering // the bounds let mut duplicates = FxHashSet::default(); - auto_traits.retain(|i| duplicates.insert(i.trait_ref().def_id())); - debug!(?regular_traits); + auto_traits.retain(|(trait_pred, _)| duplicates.insert(trait_pred.def_id())); + + debug!(?principal_trait); debug!(?auto_traits); // Erase the `dummy_self` (`trait_object_dummy_self`) used above. - let existential_trait_refs = regular_traits.iter().map(|i| { - i.trait_ref().map_bound(|trait_ref: ty::TraitRef<'tcx>| { + let principal_trait_ref = principal_trait.map(|(trait_pred, spans)| { + trait_pred.map_bound(|trait_pred| { + let trait_ref = trait_pred.trait_ref; + assert_eq!(trait_pred.polarity, ty::PredicatePolarity::Positive); assert_eq!(trait_ref.self_ty(), dummy_self); + let span = *spans.first().unwrap(); + // Verify that `dummy_self` did not leak inside default type parameters. This // could not be done at path creation, since we need to see through trait aliases. let mut missing_type_params = vec![]; - let mut references_self = false; let generics = tcx.generics_of(trait_ref.def_id); let args: Vec<_> = trait_ref .args .iter() .enumerate() - .skip(1) // Remove `Self` for `ExistentialPredicate`. + // Skip `Self` + .skip(1) .map(|(index, arg)| { if arg == dummy_self.into() { let param = &generics.own_params[index]; missing_type_params.push(param.name); Ty::new_misc_error(tcx).into() } else if arg.walk().any(|arg| arg == dummy_self.into()) { - references_self = true; let guar = self.dcx().span_delayed_bug( span, "trait object trait bounds reference `Self`", @@ -273,8 +253,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { }) .collect(); - let span = i.bottom().1; - let empty_generic_args = hir_trait_bounds.iter().any(|hir_bound| { + let empty_generic_args = hir_bounds.iter().any(|hir_bound| { hir_bound.trait_ref.path.res == Res::Def(DefKind::Trait, trait_ref.def_id) && hir_bound.span.contains(span) }); @@ -285,26 +264,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { empty_generic_args, ); - if references_self { - let def_id = i.bottom().0.def_id(); - struct_span_code_err!( - self.dcx(), - i.bottom().1, - E0038, - "the {} `{}` cannot be made into an object", - tcx.def_descr(def_id), - tcx.item_name(def_id), - ) - .with_note( - rustc_middle::traits::DynCompatibilityViolation::SupertraitSelf( - smallvec![], - ) - .error_msg(), - ) - .emit(); - } - - ty::ExistentialTraitRef::new(tcx, trait_ref.def_id, args) + ty::ExistentialPredicate::Trait(ty::ExistentialTraitRef::new( + tcx, + trait_ref.def_id, + args, + )) }) }); @@ -327,21 +291,24 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { b.projection_term = replace_dummy_self_with_error(tcx, b.projection_term, guar); } - ty::ExistentialProjection::erase_self_ty(tcx, b) + ty::ExistentialPredicate::Projection(ty::ExistentialProjection::erase_self_ty( + tcx, b, + )) }) }); - let regular_trait_predicates = existential_trait_refs - .map(|trait_ref| trait_ref.map_bound(ty::ExistentialPredicate::Trait)); - let auto_trait_predicates = auto_traits.into_iter().map(|trait_ref| { - ty::Binder::dummy(ty::ExistentialPredicate::AutoTrait(trait_ref.trait_ref().def_id())) + let auto_trait_predicates = auto_traits.into_iter().map(|(trait_pred, _)| { + assert_eq!(trait_pred.polarity(), ty::PredicatePolarity::Positive); + assert_eq!(trait_pred.self_ty().skip_binder(), dummy_self); + + ty::Binder::dummy(ty::ExistentialPredicate::AutoTrait(trait_pred.def_id())) }); + // N.b. principal, projections, auto traits // FIXME: This is actually wrong with multiple principals in regards to symbol mangling - let mut v = regular_trait_predicates - .chain( - existential_projections.map(|x| x.map_bound(ty::ExistentialPredicate::Projection)), - ) + let mut v = principal_trait_ref + .into_iter() + .chain(existential_projections) .chain(auto_trait_predicates) .collect::<SmallVec<[_; 8]>>(); v.sort_by(|a, b| a.skip_binder().stable_cmp(tcx, &b.skip_binder())); diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs index 7a3d921f00e..5d751a25080 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs @@ -11,7 +11,7 @@ use rustc_hir::def_id::DefId; use rustc_middle::bug; use rustc_middle::ty::print::{PrintPolyTraitRefExt as _, PrintTraitRefExt as _}; use rustc_middle::ty::{ - self, AdtDef, Binder, GenericParamDefKind, TraitRef, Ty, TyCtxt, TypeVisitableExt, + self, AdtDef, GenericParamDefKind, Ty, TyCtxt, TypeVisitableExt, suggest_constraining_type_param, }; use rustc_session::parse::feature_err; @@ -19,8 +19,9 @@ use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::{BytePos, DUMMY_SP, Ident, Span, Symbol, kw, sym}; use rustc_trait_selection::error_reporting::traits::report_dyn_incompatibility; use rustc_trait_selection::traits::{ - FulfillmentError, TraitAliasExpansionInfo, dyn_compatibility_violations_for_assoc_item, + FulfillmentError, dyn_compatibility_violations_for_assoc_item, }; +use smallvec::SmallVec; use crate::errors::{ self, AssocItemConstraintsNotAllowedHere, ManualImplementation, MissingTypeParams, @@ -720,7 +721,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { /// emit a generic note suggesting using a `where` clause to constraint instead. pub(crate) fn check_for_required_assoc_tys( &self, - principal_span: Span, + spans: SmallVec<[Span; 1]>, missing_assoc_types: FxIndexSet<(DefId, ty::PolyTraitRef<'tcx>)>, potential_assoc_types: Vec<usize>, trait_bounds: &[hir::PolyTraitRef<'_>], @@ -729,6 +730,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { return Ok(()); } + let principal_span = *spans.first().unwrap(); + let tcx = self.tcx(); // FIXME: This logic needs some more care w.r.t handling of conflicts let missing_assoc_types: Vec<_> = missing_assoc_types @@ -1124,29 +1127,36 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { pub fn report_trait_object_addition_traits_error( &self, - regular_traits: &Vec<TraitAliasExpansionInfo<'_>>, + regular_traits: &Vec<(ty::PolyTraitPredicate<'tcx>, SmallVec<[Span; 1]>)>, ) -> ErrorGuaranteed { - let first_trait = ®ular_traits[0]; - let additional_trait = ®ular_traits[1]; + // we use the last span to point at the traits themselves, + // and all other preceding spans are trait alias expansions. + let (&first_span, first_alias_spans) = regular_traits[0].1.split_last().unwrap(); + let (&second_span, second_alias_spans) = regular_traits[1].1.split_last().unwrap(); let mut err = struct_span_code_err!( self.dcx(), - additional_trait.bottom().1, + *regular_traits[1].1.first().unwrap(), E0225, "only auto traits can be used as additional traits in a trait object" ); - additional_trait.label_with_exp_info( - &mut err, - "additional non-auto trait", - "additional use", - ); - first_trait.label_with_exp_info(&mut err, "first non-auto trait", "first use"); + err.span_label(first_span, "first non-auto trait"); + for &alias_span in first_alias_spans { + err.span_label(alias_span, "first non-auto trait comes from this alias"); + } + err.span_label(second_span, "additional non-auto trait"); + for &alias_span in second_alias_spans { + err.span_label(alias_span, "second non-auto trait comes from this alias"); + } err.help(format!( "consider creating a new trait with all of these as supertraits and using that \ trait here instead: `trait NewTrait: {} {{}}`", regular_traits .iter() // FIXME: This should `print_sugared`, but also needs to integrate projection bounds... - .map(|t| t.trait_ref().print_only_trait_path().to_string()) + .map(|(pred, _)| pred + .map_bound(|pred| pred.trait_ref) + .print_only_trait_path() + .to_string()) .collect::<Vec<_>>() .join(" + "), )); @@ -1161,14 +1171,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { pub fn report_trait_object_with_no_traits_error( &self, span: Span, - trait_bounds: &Vec<(Binder<'tcx, TraitRef<'tcx>>, Span)>, + user_written_clauses: impl IntoIterator<Item = (ty::Clause<'tcx>, Span)>, ) -> ErrorGuaranteed { let tcx = self.tcx(); - let trait_alias_span = trait_bounds - .iter() - .map(|&(trait_ref, _)| trait_ref.def_id()) - .find(|&trait_ref| tcx.is_trait_alias(trait_ref)) - .map(|trait_ref| tcx.def_span(trait_ref)); + let trait_alias_span = user_written_clauses + .into_iter() + .filter_map(|(clause, _)| clause.as_trait_clause()) + .find(|trait_ref| tcx.is_trait_alias(trait_ref.def_id())) + .map(|trait_ref| tcx.def_span(trait_ref.def_id())); self.dcx().emit_err(TraitObjectDeclaredWithNoTraits { span, trait_alias_span }) } diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 116765325a9..b9d1f93bfb8 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -1,6 +1,5 @@ use std::cell::{Cell, RefCell}; use std::cmp::max; -use std::iter; use std::ops::Deref; use rustc_data_structures::fx::FxHashSet; @@ -1009,11 +1008,11 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { if self.tcx.is_trait_alias(trait_def_id) { // For trait aliases, recursively assume all explicitly named traits are relevant - for expansion in traits::expand_trait_aliases( - self.tcx, - iter::once((ty::Binder::dummy(trait_ref), self.span)), - ) { - let bound_trait_ref = expansion.trait_ref(); + for (bound_trait_pred, _) in + traits::expand_trait_aliases(self.tcx, [(trait_ref.upcast(self.tcx), self.span)]).0 + { + assert_eq!(bound_trait_pred.polarity(), ty::PredicatePolarity::Positive); + let bound_trait_ref = bound_trait_pred.map_bound(|pred| pred.trait_ref); for item in self.impl_or_trait_item(bound_trait_ref.def_id()) { if !self.has_applicable_self(&item) { self.record_static_candidate(CandidateSource::Trait( diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs index cd4f77bb4cf..592aee24ccc 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs @@ -437,7 +437,8 @@ pub fn report_dyn_incompatibility<'tcx>( tcx.dcx(), span, E0038, - "the trait `{}` cannot be made into an object", + "the {} `{}` cannot be made into an object", + tcx.def_descr(trait_def_id), trait_str ); err.span_label(span, format!("`{trait_str}` cannot be made into an object")); diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index da16a742099..7a485419444 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -66,9 +66,9 @@ pub use self::specialize::{ }; pub use self::structural_normalize::StructurallyNormalizeExt; pub use self::util::{ - BoundVarReplacer, PlaceholderReplacer, TraitAliasExpander, TraitAliasExpansionInfo, elaborate, - expand_trait_aliases, impl_item_is_final, supertraits, - transitive_bounds_that_define_assoc_item, upcast_choices, with_replaced_escaping_bound_vars, + BoundVarReplacer, PlaceholderReplacer, elaborate, expand_trait_aliases, impl_item_is_final, + supertraits, transitive_bounds_that_define_assoc_item, upcast_choices, + with_replaced_escaping_bound_vars, }; use crate::error_reporting::InferCtxtErrorExt; use crate::infer::outlives::env::OutlivesEnvironment; diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index da1045b664a..c9fb2a757e1 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -1,162 +1,85 @@ -use std::collections::BTreeMap; +use std::collections::{BTreeMap, VecDeque}; -use rustc_data_structures::fx::FxIndexMap; -use rustc_errors::Diag; +use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_hir::def_id::DefId; use rustc_infer::infer::InferCtxt; pub use rustc_infer::traits::util::*; use rustc_middle::bug; use rustc_middle::ty::{ - self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, Upcast, + self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, }; use rustc_span::Span; use smallvec::{SmallVec, smallvec}; use tracing::debug; -/////////////////////////////////////////////////////////////////////////// -// `TraitAliasExpander` iterator -/////////////////////////////////////////////////////////////////////////// - -/// "Trait alias expansion" is the process of expanding a sequence of trait -/// references into another sequence by transitively following all trait -/// aliases. e.g. If you have bounds like `Foo + Send`, a trait alias -/// `trait Foo = Bar + Sync;`, and another trait alias -/// `trait Bar = Read + Write`, then the bounds would expand to -/// `Read + Write + Sync + Send`. -/// Expansion is done via a DFS (depth-first search), and the `visited` field -/// is used to avoid cycles. -pub struct TraitAliasExpander<'tcx> { - tcx: TyCtxt<'tcx>, - stack: Vec<TraitAliasExpansionInfo<'tcx>>, -} - -/// Stores information about the expansion of a trait via a path of zero or more trait aliases. -#[derive(Debug, Clone)] -pub struct TraitAliasExpansionInfo<'tcx> { - pub path: SmallVec<[(ty::PolyTraitRef<'tcx>, Span); 4]>, -} - -impl<'tcx> TraitAliasExpansionInfo<'tcx> { - fn new(trait_ref: ty::PolyTraitRef<'tcx>, span: Span) -> Self { - Self { path: smallvec![(trait_ref, span)] } - } - - /// Adds diagnostic labels to `diag` for the expansion path of a trait through all intermediate - /// trait aliases. - pub fn label_with_exp_info( - &self, - diag: &mut Diag<'_>, - top_label: &'static str, - use_desc: &str, - ) { - diag.span_label(self.top().1, top_label); - if self.path.len() > 1 { - for (_, sp) in self.path.iter().rev().skip(1).take(self.path.len() - 2) { - diag.span_label(*sp, format!("referenced here ({use_desc})")); - } - } - if self.top().1 != self.bottom().1 { - // When the trait object is in a return type these two spans match, we don't want - // redundant labels. - diag.span_label( - self.bottom().1, - format!("trait alias used in trait object type ({use_desc})"), - ); - } - } - - pub fn trait_ref(&self) -> ty::PolyTraitRef<'tcx> { - self.top().0 - } - - pub fn top(&self) -> &(ty::PolyTraitRef<'tcx>, Span) { - self.path.last().unwrap() - } - - pub fn bottom(&self) -> &(ty::PolyTraitRef<'tcx>, Span) { - self.path.first().unwrap() - } - - fn clone_and_push(&self, trait_ref: ty::PolyTraitRef<'tcx>, span: Span) -> Self { - let mut path = self.path.clone(); - path.push((trait_ref, span)); - - Self { path } - } -} - +/// Return the trait and projection predicates that come from eagerly expanding the +/// trait aliases in the list of clauses. For each trait predicate, record a stack +/// of spans that trace from the user-written trait alias bound. For projection predicates, +/// just record the span of the projection itself. +/// +/// For trait aliases, we don't deduplicte the predicates, since we currently do not +/// consider duplicated traits as a single trait for the purposes of our "one trait principal" +/// restriction; however, for projections we do deduplicate them. +/// +/// ```rust,ignore (fails) +/// trait Bar {} +/// trait Foo = Bar + Bar; +/// +/// let not_object_safe: dyn Foo; // bad, two `Bar` principals. +/// ``` pub fn expand_trait_aliases<'tcx>( tcx: TyCtxt<'tcx>, - trait_refs: impl Iterator<Item = (ty::PolyTraitRef<'tcx>, Span)>, -) -> TraitAliasExpander<'tcx> { - let items: Vec<_> = - trait_refs.map(|(trait_ref, span)| TraitAliasExpansionInfo::new(trait_ref, span)).collect(); - TraitAliasExpander { tcx, stack: items } -} - -impl<'tcx> TraitAliasExpander<'tcx> { - /// If `item` is a trait alias and its predicate has not yet been visited, then expands `item` - /// to the definition, pushes the resulting expansion onto `self.stack`, and returns `false`. - /// Otherwise, immediately returns `true` if `item` is a regular trait, or `false` if it is a - /// trait alias. - /// The return value indicates whether `item` should be yielded to the user. - fn expand(&mut self, item: &TraitAliasExpansionInfo<'tcx>) -> bool { - let tcx = self.tcx; - let trait_ref = item.trait_ref(); - let pred = trait_ref.upcast(tcx); - - debug!("expand_trait_aliases: trait_ref={:?}", trait_ref); - - // Don't recurse if this bound is not a trait alias. - let is_alias = tcx.is_trait_alias(trait_ref.def_id()); - if !is_alias { - return true; - } - - // Don't recurse if this trait alias is already on the stack for the DFS search. - let anon_pred = anonymize_predicate(tcx, pred); - if item - .path - .iter() - .rev() - .skip(1) - .any(|&(tr, _)| anonymize_predicate(tcx, tr.upcast(tcx)) == anon_pred) - { - return false; - } - - // Get components of trait alias. - let predicates = tcx.explicit_super_predicates_of(trait_ref.def_id()); - debug!(?predicates); - - let items = predicates.skip_binder().iter().rev().filter_map(|(pred, span)| { - pred.instantiate_supertrait(tcx, trait_ref) - .as_trait_clause() - .map(|trait_ref| item.clone_and_push(trait_ref.map_bound(|t| t.trait_ref), *span)) - }); - debug!("expand_trait_aliases: items={:?}", items.clone().collect::<Vec<_>>()); - - self.stack.extend(items); - - false - } -} - -impl<'tcx> Iterator for TraitAliasExpander<'tcx> { - type Item = TraitAliasExpansionInfo<'tcx>; - - fn size_hint(&self) -> (usize, Option<usize>) { - (self.stack.len(), None) - } - - fn next(&mut self) -> Option<TraitAliasExpansionInfo<'tcx>> { - while let Some(item) = self.stack.pop() { - if self.expand(&item) { - return Some(item); + clauses: impl IntoIterator<Item = (ty::Clause<'tcx>, Span)>, +) -> ( + Vec<(ty::PolyTraitPredicate<'tcx>, SmallVec<[Span; 1]>)>, + Vec<(ty::PolyProjectionPredicate<'tcx>, Span)>, +) { + let mut trait_preds = vec![]; + let mut projection_preds = vec![]; + let mut seen_projection_preds = FxHashSet::default(); + + let mut queue: VecDeque<_> = clauses.into_iter().map(|(p, s)| (p, smallvec![s])).collect(); + + while let Some((clause, spans)) = queue.pop_front() { + match clause.kind().skip_binder() { + ty::ClauseKind::Trait(trait_pred) => { + if tcx.is_trait_alias(trait_pred.def_id()) { + queue.extend( + tcx.explicit_super_predicates_of(trait_pred.def_id()) + .iter_identity_copied() + .map(|(clause, span)| { + let mut spans = spans.clone(); + spans.push(span); + ( + clause.instantiate_supertrait( + tcx, + clause.kind().rebind(trait_pred.trait_ref), + ), + spans, + ) + }), + ); + } else { + trait_preds.push((clause.kind().rebind(trait_pred), spans)); + } } + ty::ClauseKind::Projection(projection_pred) => { + let projection_pred = clause.kind().rebind(projection_pred); + if !seen_projection_preds.insert(tcx.anonymize_bound_vars(projection_pred)) { + continue; + } + projection_preds.push((projection_pred, *spans.last().unwrap())); + } + ty::ClauseKind::RegionOutlives(..) + | ty::ClauseKind::TypeOutlives(..) + | ty::ClauseKind::ConstArgHasType(_, _) + | ty::ClauseKind::WellFormed(_) + | ty::ClauseKind::ConstEvaluatable(_) + | ty::ClauseKind::HostEffect(..) => {} } - None } + + (trait_preds, projection_preds) } /////////////////////////////////////////////////////////////////////////// diff --git a/compiler/rustc_type_ir/src/visit.rs b/compiler/rustc_type_ir/src/visit.rs index 71c3646498b..3213638afb2 100644 --- a/compiler/rustc_type_ir/src/visit.rs +++ b/compiler/rustc_type_ir/src/visit.rs @@ -47,6 +47,7 @@ use std::ops::ControlFlow; use rustc_ast_ir::visit::VisitorResult; use rustc_ast_ir::{try_visit, walk_visitable_list}; use rustc_index::{Idx, IndexVec}; +use smallvec::SmallVec; use thin_vec::ThinVec; use crate::data_structures::Lrc; @@ -192,6 +193,13 @@ impl<I: Interner, T: TypeVisitable<I>> TypeVisitable<I> for ThinVec<T> { } } +impl<I: Interner, T: TypeVisitable<I>, const N: usize> TypeVisitable<I> for SmallVec<[T; N]> { + fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> V::Result { + walk_visitable_list!(visitor, self.iter()); + V::Result::output() + } +} + // `TypeFoldable` isn't impl'd for `&[T]`. It doesn't make sense in the general // case, because we can't return a new slice. But note that there are a couple // of trivial impls of `TypeFoldable` for specific slice types elsewhere. diff --git a/tests/rustdoc-ui/issues/ice-generic-type-alias-105742.stderr b/tests/rustdoc-ui/issues/ice-generic-type-alias-105742.stderr index f9080bf0785..97bd44244f3 100644 --- a/tests/rustdoc-ui/issues/ice-generic-type-alias-105742.stderr +++ b/tests/rustdoc-ui/issues/ice-generic-type-alias-105742.stderr @@ -295,10 +295,10 @@ LL | Output = <Self as SVec>::Item> as SVec>::Item<T>, | +++ error[E0038]: the trait `SVec` cannot be made into an object - --> $DIR/ice-generic-type-alias-105742.rs:5:31 + --> $DIR/ice-generic-type-alias-105742.rs:5:35 | LL | pub fn next<'a, T>(s: &'a mut dyn SVec<Item = T, Output = T>) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `SVec` cannot be made into an object + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ `SVec` cannot be made into an object | note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> --> $DIR/ice-generic-type-alias-105742.rs:15:17 diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_dyn_compatibility.stderr b/tests/ui/const-generics/adt_const_params/const_param_ty_dyn_compatibility.stderr index 84281eb53c9..7cd5754be8a 100644 --- a/tests/ui/const-generics/adt_const_params/const_param_ty_dyn_compatibility.stderr +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_dyn_compatibility.stderr @@ -1,8 +1,8 @@ error[E0038]: the trait `ConstParamTy_` cannot be made into an object - --> $DIR/const_param_ty_dyn_compatibility.rs:6:12 + --> $DIR/const_param_ty_dyn_compatibility.rs:6:16 | LL | fn foo(a: &dyn ConstParamTy_) {} - | ^^^^^^^^^^^^^^^^^ `ConstParamTy_` cannot be made into an object + | ^^^^^^^^^^^^^ `ConstParamTy_` cannot be made into an object | note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> --> $SRC_DIR/core/src/cmp.rs:LL:COL @@ -14,10 +14,10 @@ LL | fn foo(a: &impl ConstParamTy_) {} | ~~~~ error[E0038]: the trait `UnsizedConstParamTy` cannot be made into an object - --> $DIR/const_param_ty_dyn_compatibility.rs:9:12 + --> $DIR/const_param_ty_dyn_compatibility.rs:9:16 | LL | fn bar(a: &dyn UnsizedConstParamTy) {} - | ^^^^^^^^^^^^^^^^^^^^^^^ `UnsizedConstParamTy` cannot be made into an object + | ^^^^^^^^^^^^^^^^^^^ `UnsizedConstParamTy` cannot be made into an object | note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> --> $SRC_DIR/core/src/cmp.rs:LL:COL diff --git a/tests/ui/dyn-compatibility/mentions-Self-in-super-predicates.stderr b/tests/ui/dyn-compatibility/mentions-Self-in-super-predicates.stderr index 7578edce7d1..03e57841b1b 100644 --- a/tests/ui/dyn-compatibility/mentions-Self-in-super-predicates.stderr +++ b/tests/ui/dyn-compatibility/mentions-Self-in-super-predicates.stderr @@ -1,8 +1,8 @@ error[E0038]: the trait `Expr` cannot be made into an object - --> $DIR/mentions-Self-in-super-predicates.rs:12:23 + --> $DIR/mentions-Self-in-super-predicates.rs:12:27 | LL | elements: Vec<Box<dyn Expr + 'x>>, - | ^^^^^^^^^^^^^ `Expr` cannot be made into an object + | ^^^^ `Expr` cannot be made into an object | note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> --> $DIR/mentions-Self-in-super-predicates.rs:5:21 @@ -14,10 +14,10 @@ LL | trait Expr: Debug + PartialEq { = help: only type `SExpr<'x>` implements the trait, consider using it directly instead error[E0038]: the trait `Expr` cannot be made into an object - --> $DIR/mentions-Self-in-super-predicates.rs:38:16 + --> $DIR/mentions-Self-in-super-predicates.rs:38:20 | LL | let a: Box<dyn Expr> = Box::new(SExpr::new()); - | ^^^^^^^^ `Expr` cannot be made into an object + | ^^^^ `Expr` cannot be made into an object | note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> --> $DIR/mentions-Self-in-super-predicates.rs:5:21 @@ -29,10 +29,10 @@ LL | trait Expr: Debug + PartialEq { = help: only type `SExpr<'x>` implements the trait, consider using it directly instead error[E0038]: the trait `Expr` cannot be made into an object - --> $DIR/mentions-Self-in-super-predicates.rs:40:16 + --> $DIR/mentions-Self-in-super-predicates.rs:40:20 | LL | let b: Box<dyn Expr> = Box::new(SExpr::new()); - | ^^^^^^^^ `Expr` cannot be made into an object + | ^^^^ `Expr` cannot be made into an object | note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> --> $DIR/mentions-Self-in-super-predicates.rs:5:21 diff --git a/tests/ui/dyn-compatibility/supertrait-mentions-Self.stderr b/tests/ui/dyn-compatibility/supertrait-mentions-Self.stderr index 6474b115c46..abeafa1967f 100644 --- a/tests/ui/dyn-compatibility/supertrait-mentions-Self.stderr +++ b/tests/ui/dyn-compatibility/supertrait-mentions-Self.stderr @@ -19,10 +19,10 @@ LL | trait Bar<T: ?Sized> { | ++++++++ error[E0038]: the trait `Baz` cannot be made into an object - --> $DIR/supertrait-mentions-Self.rs:16:31 + --> $DIR/supertrait-mentions-Self.rs:16:35 | LL | fn make_baz<T:Baz>(t: &T) -> &dyn Baz { - | ^^^^^^^ `Baz` cannot be made into an object + | ^^^ `Baz` cannot be made into an object | note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> --> $DIR/supertrait-mentions-Self.rs:8:13 diff --git a/tests/ui/error-codes/E0225.stderr b/tests/ui/error-codes/E0225.stderr index a4b33a0b7b4..e6781282c8f 100644 --- a/tests/ui/error-codes/E0225.stderr +++ b/tests/ui/error-codes/E0225.stderr @@ -20,8 +20,8 @@ LL | trait Foo = std::io::Read + std::io::Write; LL | let _: Box<dyn Foo>; | ^^^ | | - | trait alias used in trait object type (additional use) - | trait alias used in trait object type (first use) + | first non-auto trait comes from this alias + | second non-auto trait comes from this alias | = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: std::io::Read + std::io::Write {}` = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits> diff --git a/tests/ui/issues/issue-26056.stderr b/tests/ui/issues/issue-26056.stderr index be5453ec19d..c5ae41200f6 100644 --- a/tests/ui/issues/issue-26056.stderr +++ b/tests/ui/issues/issue-26056.stderr @@ -1,8 +1,8 @@ error[E0038]: the trait `Map` cannot be made into an object - --> $DIR/issue-26056.rs:20:13 + --> $DIR/issue-26056.rs:20:17 | LL | as &dyn Map<Key=u32,MapValue=u32>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Map` cannot be made into an object + | ^^^^^^^^^^^^^^^^^^^^^^^^^ `Map` cannot be made into an object | note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> --> $DIR/issue-26056.rs:9:12 diff --git a/tests/ui/traits/alias/generic-default-in-dyn.rs b/tests/ui/traits/alias/generic-default-in-dyn.rs index d44e1c2a975..b180f0a6803 100644 --- a/tests/ui/traits/alias/generic-default-in-dyn.rs +++ b/tests/ui/traits/alias/generic-default-in-dyn.rs @@ -2,9 +2,9 @@ trait SendEqAlias<T> = PartialEq; //~^ ERROR trait aliases are experimental struct Foo<T>(dyn SendEqAlias<T>); -//~^ ERROR the type parameter `Rhs` must be explicitly specified [E0393] +//~^ ERROR the trait alias `SendEqAlias` cannot be made into an object struct Bar<T>(dyn SendEqAlias<T>, T); -//~^ ERROR the type parameter `Rhs` must be explicitly specified [E0393] +//~^ ERROR the trait alias `SendEqAlias` cannot be made into an object fn main() {} diff --git a/tests/ui/traits/alias/generic-default-in-dyn.stderr b/tests/ui/traits/alias/generic-default-in-dyn.stderr index 50031e184c1..902d18de944 100644 --- a/tests/ui/traits/alias/generic-default-in-dyn.stderr +++ b/tests/ui/traits/alias/generic-default-in-dyn.stderr @@ -8,29 +8,35 @@ LL | trait SendEqAlias<T> = PartialEq; = help: add `#![feature(trait_alias)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error[E0393]: the type parameter `Rhs` must be explicitly specified +error[E0038]: the trait alias `SendEqAlias` cannot be made into an object --> $DIR/generic-default-in-dyn.rs:4:19 | LL | struct Foo<T>(dyn SendEqAlias<T>); - | ^^^^^^^^^^^^^^ missing reference to `Rhs` - --> $SRC_DIR/core/src/cmp.rs:LL:COL + | ^^^^^^^^^^^^^^ `SendEqAlias` cannot be made into an object | - = note: type parameter `Rhs` must be specified for this +note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + --> $DIR/generic-default-in-dyn.rs:1:24 | - = note: because of the default `Self` reference, type parameters must be specified on object types +LL | trait SendEqAlias<T> = PartialEq; + | ----------- ^^^^^^^^^ ...because it uses `Self` as a type parameter + | | + | this trait cannot be made into an object... -error[E0393]: the type parameter `Rhs` must be explicitly specified +error[E0038]: the trait alias `SendEqAlias` cannot be made into an object --> $DIR/generic-default-in-dyn.rs:7:19 | LL | struct Bar<T>(dyn SendEqAlias<T>, T); - | ^^^^^^^^^^^^^^ missing reference to `Rhs` - --> $SRC_DIR/core/src/cmp.rs:LL:COL + | ^^^^^^^^^^^^^^ `SendEqAlias` cannot be made into an object | - = note: type parameter `Rhs` must be specified for this +note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + --> $DIR/generic-default-in-dyn.rs:1:24 | - = note: because of the default `Self` reference, type parameters must be specified on object types +LL | trait SendEqAlias<T> = PartialEq; + | ----------- ^^^^^^^^^ ...because it uses `Self` as a type parameter + | | + | this trait cannot be made into an object... error: aborting due to 3 previous errors -Some errors have detailed explanations: E0393, E0658. -For more information about an error, try `rustc --explain E0393`. +Some errors have detailed explanations: E0038, E0658. +For more information about an error, try `rustc --explain E0038`. diff --git a/tests/ui/traits/alias/no-duplicates.stderr b/tests/ui/traits/alias/no-duplicates.stderr index bf244b97e9b..6a901a80554 100644 --- a/tests/ui/traits/alias/no-duplicates.stderr +++ b/tests/ui/traits/alias/no-duplicates.stderr @@ -4,32 +4,32 @@ error[E0225]: only auto traits can be used as additional traits in a trait objec LL | trait _0 = Obj; | --- | | - | additional non-auto trait | first non-auto trait + | additional non-auto trait ... LL | type _T00 = dyn _0 + _0; - | -- ^^ trait alias used in trait object type (additional use) + | -- ^^ second non-auto trait comes from this alias | | - | trait alias used in trait object type (first use) + | first non-auto trait comes from this alias | = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Obj + Obj {}` = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits> error[E0225]: only auto traits can be used as additional traits in a trait object - --> $DIR/no-duplicates.rs:19:22 + --> $DIR/no-duplicates.rs:19:17 | LL | trait _0 = Obj; | --- | | - | additional non-auto trait | first non-auto trait + | additional non-auto trait LL | trait _1 = _0; - | -- referenced here (first use) + | -- second non-auto trait comes from this alias ... LL | type _T01 = dyn _1 + _0; - | -- ^^ trait alias used in trait object type (additional use) + | ^^ -- first non-auto trait comes from this alias | | - | trait alias used in trait object type (first use) + | second non-auto trait comes from this alias | = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Obj + Obj {}` = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits> @@ -40,18 +40,18 @@ error[E0225]: only auto traits can be used as additional traits in a trait objec LL | trait _0 = Obj; | --- | | - | additional non-auto trait | first non-auto trait + | additional non-auto trait LL | trait _1 = _0; | -- | | - | referenced here (additional use) - | referenced here (first use) + | first non-auto trait comes from this alias + | second non-auto trait comes from this alias ... LL | type _T02 = dyn _1 + _1; - | -- ^^ trait alias used in trait object type (additional use) + | -- ^^ second non-auto trait comes from this alias | | - | trait alias used in trait object type (first use) + | first non-auto trait comes from this alias | = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Obj + Obj {}` = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits> @@ -62,10 +62,10 @@ error[E0225]: only auto traits can be used as additional traits in a trait objec LL | trait _0 = Obj; | --- additional non-auto trait LL | trait _1 = _0; - | -- referenced here (additional use) + | -- second non-auto trait comes from this alias ... LL | type _T03 = dyn Obj + _1; - | --- ^^ trait alias used in trait object type (additional use) + | --- ^^ second non-auto trait comes from this alias | | | first non-auto trait | @@ -73,17 +73,17 @@ LL | type _T03 = dyn Obj + _1; = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits> error[E0225]: only auto traits can be used as additional traits in a trait object - --> $DIR/no-duplicates.rs:28:22 + --> $DIR/no-duplicates.rs:28:17 | LL | trait _0 = Obj; - | --- first non-auto trait + | --- additional non-auto trait LL | trait _1 = _0; - | -- referenced here (first use) + | -- second non-auto trait comes from this alias ... LL | type _T04 = dyn _1 + Obj; - | -- ^^^ additional non-auto trait + | ^^ --- first non-auto trait | | - | trait alias used in trait object type (first use) + | second non-auto trait comes from this alias | = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Obj + Obj {}` = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits> @@ -92,23 +92,17 @@ error[E0225]: only auto traits can be used as additional traits in a trait objec --> $DIR/no-duplicates.rs:37:17 | LL | trait _0 = Obj; - | --- - | | - | additional non-auto trait - | first non-auto trait -LL | trait _1 = _0; - | -- referenced here (additional use) + | --- additional non-auto trait ... LL | trait _2 = _0 + _1; - | -- -- referenced here (additional use) - | | - | referenced here (first use) + | -- second non-auto trait comes from this alias +LL | trait _3 = Obj; + | --- first non-auto trait ... LL | type _T10 = dyn _2 + _3; - | ^^ + | ^^ -- first non-auto trait comes from this alias | | - | trait alias used in trait object type (additional use) - | trait alias used in trait object type (first use) + | second non-auto trait comes from this alias | = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Obj + Obj + Obj {}` = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits> @@ -120,14 +114,14 @@ LL | trait _0 = Obj; | --- additional non-auto trait ... LL | trait _2 = _0 + _1; - | -- referenced here (additional use) + | -- second non-auto trait comes from this alias LL | trait _3 = Obj; | --- first non-auto trait ... LL | type _T11 = dyn _3 + _2; - | -- ^^ trait alias used in trait object type (additional use) + | -- ^^ second non-auto trait comes from this alias | | - | trait alias used in trait object type (first use) + | first non-auto trait comes from this alias | = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Obj + Obj + Obj {}` = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits> @@ -139,10 +133,10 @@ LL | trait _0 = Obj; | --- additional non-auto trait ... LL | trait _2 = _0 + _1; - | -- referenced here (additional use) + | -- second non-auto trait comes from this alias ... LL | type _T12 = dyn Obj + _2; - | --- ^^ trait alias used in trait object type (additional use) + | --- ^^ second non-auto trait comes from this alias | | | first non-auto trait | @@ -153,42 +147,34 @@ error[E0225]: only auto traits can be used as additional traits in a trait objec --> $DIR/no-duplicates.rs:46:17 | LL | trait _0 = Obj; - | --- - | | - | additional non-auto trait - | first non-auto trait -LL | trait _1 = _0; - | -- referenced here (additional use) + | --- additional non-auto trait ... LL | trait _2 = _0 + _1; - | -- -- referenced here (additional use) - | | - | referenced here (first use) + | -- second non-auto trait comes from this alias ... LL | type _T13 = dyn _2 + Obj; - | ^^ + | ^^ --- first non-auto trait | | - | trait alias used in trait object type (additional use) - | trait alias used in trait object type (first use) + | second non-auto trait comes from this alias | = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Obj + Obj + Obj {}` = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits> error[E0225]: only auto traits can be used as additional traits in a trait object - --> $DIR/no-duplicates.rs:49:22 + --> $DIR/no-duplicates.rs:49:17 | LL | trait _0 = Obj; - | --- first non-auto trait + | --- additional non-auto trait LL | trait _1 = _0; - | -- referenced here (first use) + | -- second non-auto trait comes from this alias ... LL | trait _3 = Obj; - | --- additional non-auto trait + | --- first non-auto trait ... LL | type _T14 = dyn _1 + _3; - | -- ^^ trait alias used in trait object type (additional use) + | ^^ -- first non-auto trait comes from this alias | | - | trait alias used in trait object type (first use) + | second non-auto trait comes from this alias | = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Obj + Obj {}` = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits> @@ -199,15 +185,15 @@ error[E0225]: only auto traits can be used as additional traits in a trait objec LL | trait _0 = Obj; | --- additional non-auto trait LL | trait _1 = _0; - | -- referenced here (additional use) + | -- second non-auto trait comes from this alias ... LL | trait _3 = Obj; | --- first non-auto trait ... LL | type _T15 = dyn _3 + _1; - | -- ^^ trait alias used in trait object type (additional use) + | -- ^^ second non-auto trait comes from this alias | | - | trait alias used in trait object type (first use) + | first non-auto trait comes from this alias | = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Obj + Obj {}` = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits> @@ -218,17 +204,17 @@ error[E0225]: only auto traits can be used as additional traits in a trait objec LL | trait _0 = Obj; | --- first non-auto trait LL | trait _1 = _0; - | -- referenced here (first use) + | -- first non-auto trait comes from this alias ... LL | trait _3 = Obj; | --- additional non-auto trait LL | trait _4 = _3; - | -- referenced here (additional use) + | -- second non-auto trait comes from this alias ... LL | type _T16 = dyn _1 + _4; - | -- ^^ trait alias used in trait object type (additional use) + | -- ^^ second non-auto trait comes from this alias | | - | trait alias used in trait object type (first use) + | first non-auto trait comes from this alias | = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Obj + Obj {}` = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits> @@ -239,17 +225,17 @@ error[E0225]: only auto traits can be used as additional traits in a trait objec LL | trait _0 = Obj; | --- additional non-auto trait LL | trait _1 = _0; - | -- referenced here (additional use) + | -- second non-auto trait comes from this alias ... LL | trait _3 = Obj; | --- first non-auto trait LL | trait _4 = _3; - | -- referenced here (first use) + | -- first non-auto trait comes from this alias ... LL | type _T17 = dyn _4 + _1; - | -- ^^ trait alias used in trait object type (additional use) + | -- ^^ second non-auto trait comes from this alias | | - | trait alias used in trait object type (first use) + | first non-auto trait comes from this alias | = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Obj + Obj {}` = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits> @@ -260,13 +246,13 @@ error[E0225]: only auto traits can be used as additional traits in a trait objec LL | trait _5 = Obj + Send; | --- | | - | additional non-auto trait | first non-auto trait + | additional non-auto trait LL | LL | type _T20 = dyn _5 + _5; - | -- ^^ trait alias used in trait object type (additional use) + | -- ^^ second non-auto trait comes from this alias | | - | trait alias used in trait object type (first use) + | first non-auto trait comes from this alias | = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Obj + Obj {}` = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits> @@ -278,7 +264,7 @@ LL | trait _5 = Obj + Send; | --- additional non-auto trait ... LL | type _T21 = dyn Obj + _5; - | --- ^^ trait alias used in trait object type (additional use) + | --- ^^ second non-auto trait comes from this alias | | | first non-auto trait | @@ -286,29 +272,29 @@ LL | type _T21 = dyn Obj + _5; = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits> error[E0225]: only auto traits can be used as additional traits in a trait object - --> $DIR/no-duplicates.rs:71:22 + --> $DIR/no-duplicates.rs:71:17 | LL | trait _5 = Obj + Send; - | --- first non-auto trait + | --- additional non-auto trait ... LL | type _T22 = dyn _5 + Obj; - | -- ^^^ additional non-auto trait + | ^^ --- first non-auto trait | | - | trait alias used in trait object type (first use) + | second non-auto trait comes from this alias | = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Obj + Obj {}` = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits> error[E0225]: only auto traits can be used as additional traits in a trait object - --> $DIR/no-duplicates.rs:74:36 + --> $DIR/no-duplicates.rs:74:17 | LL | trait _5 = Obj + Send; - | --- first non-auto trait + | --- additional non-auto trait ... LL | type _T23 = dyn _5 + Send + Sync + Obj; - | -- ^^^ additional non-auto trait + | ^^ --- first non-auto trait | | - | trait alias used in trait object type (first use) + | second non-auto trait comes from this alias | = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Obj + Obj {}` = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits> @@ -319,19 +305,19 @@ error[E0225]: only auto traits can be used as additional traits in a trait objec LL | trait _5 = Obj + Send; | --- | | - | additional non-auto trait | first non-auto trait + | additional non-auto trait ... LL | trait _6 = _5 + _5; // ==> Obj + Send + Obj + Send - | -- -- referenced here (additional use) + | -- -- second non-auto trait comes from this alias | | - | referenced here (first use) + | first non-auto trait comes from this alias LL | LL | type _T30 = dyn _6; | ^^ | | - | trait alias used in trait object type (additional use) - | trait alias used in trait object type (first use) + | first non-auto trait comes from this alias + | second non-auto trait comes from this alias | = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Obj + Obj {}` = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits> @@ -342,19 +328,19 @@ error[E0225]: only auto traits can be used as additional traits in a trait objec LL | trait _5 = Obj + Send; | --- | | - | additional non-auto trait | first non-auto trait + | additional non-auto trait ... LL | trait _6 = _5 + _5; // ==> Obj + Send + Obj + Send - | -- -- referenced here (additional use) + | -- -- second non-auto trait comes from this alias | | - | referenced here (first use) + | first non-auto trait comes from this alias ... LL | type _T31 = dyn _6 + Send; | ^^ | | - | trait alias used in trait object type (additional use) - | trait alias used in trait object type (first use) + | first non-auto trait comes from this alias + | second non-auto trait comes from this alias | = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Obj + Obj {}` = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits> @@ -365,38 +351,38 @@ error[E0225]: only auto traits can be used as additional traits in a trait objec LL | trait _5 = Obj + Send; | --- | | - | additional non-auto trait | first non-auto trait + | additional non-auto trait ... LL | trait _6 = _5 + _5; // ==> Obj + Send + Obj + Send - | -- -- referenced here (additional use) + | -- -- second non-auto trait comes from this alias | | - | referenced here (first use) + | first non-auto trait comes from this alias ... LL | type _T32 = dyn Send + _6; | ^^ | | - | trait alias used in trait object type (additional use) - | trait alias used in trait object type (first use) + | first non-auto trait comes from this alias + | second non-auto trait comes from this alias | = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Obj + Obj {}` = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits> error[E0225]: only auto traits can be used as additional traits in a trait object - --> $DIR/no-duplicates.rs:95:22 + --> $DIR/no-duplicates.rs:95:17 | LL | trait _5 = Obj + Send; - | --- first non-auto trait + | --- additional non-auto trait ... LL | trait _7 = _5 + Sync; - | -- referenced here (first use) + | -- second non-auto trait comes from this alias LL | trait _8 = Unpin + _7; - | -- referenced here (first use) + | -- second non-auto trait comes from this alias LL | LL | type _T40 = dyn _8 + Obj; - | -- ^^^ additional non-auto trait + | ^^ --- first non-auto trait | | - | trait alias used in trait object type (first use) + | second non-auto trait comes from this alias | = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Obj + Obj {}` = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits> @@ -408,12 +394,12 @@ LL | trait _5 = Obj + Send; | --- additional non-auto trait ... LL | trait _7 = _5 + Sync; - | -- referenced here (additional use) + | -- second non-auto trait comes from this alias LL | trait _8 = Unpin + _7; - | -- referenced here (additional use) + | -- second non-auto trait comes from this alias ... LL | type _T41 = dyn Obj + _8; - | --- ^^ trait alias used in trait object type (additional use) + | --- ^^ second non-auto trait comes from this alias | | | first non-auto trait | @@ -421,25 +407,25 @@ LL | type _T41 = dyn Obj + _8; = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits> error[E0225]: only auto traits can be used as additional traits in a trait object - --> $DIR/no-duplicates.rs:101:22 + --> $DIR/no-duplicates.rs:101:17 | LL | trait _3 = Obj; - | --- additional non-auto trait + | --- first non-auto trait LL | trait _4 = _3; - | -- referenced here (additional use) + | -- first non-auto trait comes from this alias ... LL | trait _5 = Obj + Send; - | --- first non-auto trait + | --- additional non-auto trait ... LL | trait _7 = _5 + Sync; - | -- referenced here (first use) + | -- second non-auto trait comes from this alias LL | trait _8 = Unpin + _7; - | -- referenced here (first use) + | -- second non-auto trait comes from this alias ... LL | type _T42 = dyn _8 + _4; - | -- ^^ trait alias used in trait object type (additional use) + | ^^ -- first non-auto trait comes from this alias | | - | trait alias used in trait object type (first use) + | second non-auto trait comes from this alias | = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Obj + Obj {}` = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits> @@ -450,20 +436,20 @@ error[E0225]: only auto traits can be used as additional traits in a trait objec LL | trait _3 = Obj; | --- first non-auto trait LL | trait _4 = _3; - | -- referenced here (first use) + | -- first non-auto trait comes from this alias ... LL | trait _5 = Obj + Send; | --- additional non-auto trait ... LL | trait _7 = _5 + Sync; - | -- referenced here (additional use) + | -- second non-auto trait comes from this alias LL | trait _8 = Unpin + _7; - | -- referenced here (additional use) + | -- second non-auto trait comes from this alias ... LL | type _T43 = dyn _4 + _8; - | -- ^^ trait alias used in trait object type (additional use) + | -- ^^ second non-auto trait comes from this alias | | - | trait alias used in trait object type (first use) + | first non-auto trait comes from this alias | = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Obj + Obj {}` = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits> @@ -474,20 +460,20 @@ error[E0225]: only auto traits can be used as additional traits in a trait objec LL | trait _3 = Obj; | --- first non-auto trait LL | trait _4 = _3; - | -- referenced here (first use) + | -- first non-auto trait comes from this alias ... LL | trait _5 = Obj + Send; | --- additional non-auto trait ... LL | trait _7 = _5 + Sync; - | -- referenced here (additional use) + | -- second non-auto trait comes from this alias LL | trait _8 = Unpin + _7; - | -- referenced here (additional use) + | -- second non-auto trait comes from this alias ... LL | type _T44 = dyn _4 + Send + Sync + _8; - | -- ^^ trait alias used in trait object type (additional use) + | -- ^^ second non-auto trait comes from this alias | | - | trait alias used in trait object type (first use) + | first non-auto trait comes from this alias | = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Obj + Obj {}` = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits> @@ -500,9 +486,9 @@ LL | trait _9 = for<'a> ObjL<'a>; LL | trait _10 = for<'b> ObjL<'b>; | ---------------- additional non-auto trait LL | type _T50 = dyn _9 + _10; - | -- ^^^ trait alias used in trait object type (additional use) + | -- ^^^ second non-auto trait comes from this alias | | - | trait alias used in trait object type (first use) + | first non-auto trait comes from this alias | = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: for<'a> ObjL<'a> + for<'b> ObjL<'b> {}` = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits> @@ -515,9 +501,9 @@ LL | trait _11 = ObjT<for<'a> fn(&'a u8)>; LL | trait _12 = ObjT<for<'b> fn(&'b u8)>; | ------------------------ additional non-auto trait LL | type _T60 = dyn _11 + _12; - | --- ^^^ trait alias used in trait object type (additional use) + | --- ^^^ second non-auto trait comes from this alias | | - | trait alias used in trait object type (first use) + | first non-auto trait comes from this alias | = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjT<for<'a> fn(&'a u8)> + ObjT<for<'b> fn(&'b u8)> {}` = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits> diff --git a/tests/ui/traits/alias/no-extra-traits.stderr b/tests/ui/traits/alias/no-extra-traits.stderr index 4b1ddf6843c..fcdb4937ff5 100644 --- a/tests/ui/traits/alias/no-extra-traits.stderr +++ b/tests/ui/traits/alias/no-extra-traits.stderr @@ -1,15 +1,15 @@ error[E0225]: only auto traits can be used as additional traits in a trait object - --> $DIR/no-extra-traits.rs:16:22 + --> $DIR/no-extra-traits.rs:16:17 | LL | trait _0 = ObjA; - | ---- first non-auto trait + | ---- additional non-auto trait ... LL | type _T00 = dyn _0 + ObjB; - | -- ^^^^ additional non-auto trait + | ^^ ---- first non-auto trait | | - | trait alias used in trait object type (first use) + | second non-auto trait comes from this alias | - = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjA + ObjB {}` + = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjB + ObjA {}` = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits> error[E0225]: only auto traits can be used as additional traits in a trait object @@ -19,7 +19,7 @@ LL | trait _0 = ObjA; | ---- additional non-auto trait ... LL | type _T01 = dyn ObjB + _0; - | ---- ^^ trait alias used in trait object type (additional use) + | ---- ^^ second non-auto trait comes from this alias | | | first non-auto trait | @@ -32,10 +32,10 @@ error[E0225]: only auto traits can be used as additional traits in a trait objec LL | trait _0 = ObjA; | ---- additional non-auto trait LL | trait _1 = _0; - | -- referenced here (additional use) + | -- second non-auto trait comes from this alias ... LL | type _T02 = dyn ObjB + _1; - | ---- ^^ trait alias used in trait object type (additional use) + | ---- ^^ second non-auto trait comes from this alias | | | first non-auto trait | @@ -43,19 +43,19 @@ LL | type _T02 = dyn ObjB + _1; = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits> error[E0225]: only auto traits can be used as additional traits in a trait object - --> $DIR/no-extra-traits.rs:25:22 + --> $DIR/no-extra-traits.rs:25:17 | LL | trait _0 = ObjA; - | ---- first non-auto trait + | ---- additional non-auto trait LL | trait _1 = _0; - | -- referenced here (first use) + | -- second non-auto trait comes from this alias ... LL | type _T03 = dyn _1 + ObjB; - | -- ^^^^ additional non-auto trait + | ^^ ---- first non-auto trait | | - | trait alias used in trait object type (first use) + | second non-auto trait comes from this alias | - = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjA + ObjB {}` + = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjB + ObjA {}` = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits> error[E0225]: only auto traits can be used as additional traits in a trait object @@ -64,34 +64,34 @@ error[E0225]: only auto traits can be used as additional traits in a trait objec LL | trait _2 = ObjB; | ---- | | - | additional non-auto trait | first non-auto trait + | additional non-auto trait LL | trait _3 = _2; - | -- referenced here (additional use) + | -- second non-auto trait comes from this alias ... LL | type _T10 = dyn _2 + _3; - | -- ^^ trait alias used in trait object type (additional use) + | -- ^^ second non-auto trait comes from this alias | | - | trait alias used in trait object type (first use) + | first non-auto trait comes from this alias | = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjB + ObjB {}` = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits> error[E0225]: only auto traits can be used as additional traits in a trait object - --> $DIR/no-extra-traits.rs:37:22 + --> $DIR/no-extra-traits.rs:37:17 | LL | trait _2 = ObjB; | ---- | | - | additional non-auto trait | first non-auto trait + | additional non-auto trait LL | trait _3 = _2; - | -- referenced here (first use) + | -- second non-auto trait comes from this alias ... LL | type _T11 = dyn _3 + _2; - | -- ^^ trait alias used in trait object type (additional use) + | ^^ -- first non-auto trait comes from this alias | | - | trait alias used in trait object type (first use) + | second non-auto trait comes from this alias | = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjB + ObjB {}` = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits> @@ -102,38 +102,38 @@ error[E0225]: only auto traits can be used as additional traits in a trait objec LL | trait _2 = ObjB; | ---- | | - | additional non-auto trait | first non-auto trait + | additional non-auto trait LL | trait _3 = _2; - | -- referenced here (additional use) + | -- second non-auto trait comes from this alias LL | trait _4 = _3; - | -- referenced here (additional use) + | -- second non-auto trait comes from this alias ... LL | type _T12 = dyn _2 + _4; - | -- ^^ trait alias used in trait object type (additional use) + | -- ^^ second non-auto trait comes from this alias | | - | trait alias used in trait object type (first use) + | first non-auto trait comes from this alias | = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjB + ObjB {}` = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits> error[E0225]: only auto traits can be used as additional traits in a trait object - --> $DIR/no-extra-traits.rs:43:22 + --> $DIR/no-extra-traits.rs:43:17 | LL | trait _2 = ObjB; | ---- | | - | additional non-auto trait | first non-auto trait + | additional non-auto trait LL | trait _3 = _2; - | -- referenced here (first use) + | -- second non-auto trait comes from this alias LL | trait _4 = _3; - | -- referenced here (first use) + | -- second non-auto trait comes from this alias ... LL | type _T13 = dyn _4 + _2; - | -- ^^ trait alias used in trait object type (additional use) + | ^^ -- first non-auto trait comes from this alias | | - | trait alias used in trait object type (first use) + | second non-auto trait comes from this alias | = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjB + ObjB {}` = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits> @@ -144,50 +144,50 @@ error[E0225]: only auto traits can be used as additional traits in a trait objec LL | trait _0 = ObjA; | ---- additional non-auto trait LL | trait _1 = _0; - | -- referenced here (additional use) + | -- second non-auto trait comes from this alias ... LL | trait _5 = Sync + ObjB + Send; | ---- first non-auto trait LL | LL | type _T20 = dyn _5 + _1; - | -- ^^ trait alias used in trait object type (additional use) + | -- ^^ second non-auto trait comes from this alias | | - | trait alias used in trait object type (first use) + | first non-auto trait comes from this alias | = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjB + ObjA {}` = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits> error[E0225]: only auto traits can be used as additional traits in a trait object - --> $DIR/no-extra-traits.rs:53:22 + --> $DIR/no-extra-traits.rs:53:17 | LL | trait _0 = ObjA; - | ---- first non-auto trait + | ---- additional non-auto trait LL | trait _1 = _0; - | -- referenced here (first use) + | -- second non-auto trait comes from this alias ... LL | trait _5 = Sync + ObjB + Send; - | ---- additional non-auto trait + | ---- first non-auto trait ... LL | type _T21 = dyn _1 + _5; - | -- ^^ trait alias used in trait object type (additional use) + | ^^ -- first non-auto trait comes from this alias | | - | trait alias used in trait object type (first use) + | second non-auto trait comes from this alias | - = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjA + ObjB {}` + = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjB + ObjA {}` = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits> error[E0225]: only auto traits can be used as additional traits in a trait object - --> $DIR/no-extra-traits.rs:56:22 + --> $DIR/no-extra-traits.rs:56:17 | LL | trait _5 = Sync + ObjB + Send; - | ---- first non-auto trait + | ---- additional non-auto trait ... LL | type _T22 = dyn _5 + ObjA; - | -- ^^^^ additional non-auto trait + | ^^ ---- first non-auto trait | | - | trait alias used in trait object type (first use) + | second non-auto trait comes from this alias | - = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjB + ObjA {}` + = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjA + ObjB {}` = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits> error[E0225]: only auto traits can be used as additional traits in a trait object @@ -197,7 +197,7 @@ LL | trait _5 = Sync + ObjB + Send; | ---- additional non-auto trait ... LL | type _T23 = dyn ObjA + _5; - | ---- ^^ trait alias used in trait object type (additional use) + | ---- ^^ second non-auto trait comes from this alias | | | first non-auto trait | @@ -210,50 +210,50 @@ error[E0225]: only auto traits can be used as additional traits in a trait objec LL | trait _0 = ObjA; | ---- additional non-auto trait LL | trait _1 = _0; - | -- referenced here (additional use) + | -- second non-auto trait comes from this alias ... LL | trait _5 = Sync + ObjB + Send; | ---- first non-auto trait ... LL | type _T24 = dyn Send + _5 + _1 + Sync; - | -- ^^ trait alias used in trait object type (additional use) + | -- ^^ second non-auto trait comes from this alias | | - | trait alias used in trait object type (first use) + | first non-auto trait comes from this alias | = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjB + ObjA {}` = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits> error[E0225]: only auto traits can be used as additional traits in a trait object - --> $DIR/no-extra-traits.rs:65:29 + --> $DIR/no-extra-traits.rs:65:17 | LL | trait _0 = ObjA; - | ---- first non-auto trait + | ---- additional non-auto trait LL | trait _1 = _0; - | -- referenced here (first use) + | -- second non-auto trait comes from this alias ... LL | trait _5 = Sync + ObjB + Send; - | ---- additional non-auto trait + | ---- first non-auto trait ... LL | type _T25 = dyn _1 + Sync + _5 + Send; - | -- ^^ trait alias used in trait object type (additional use) + | ^^ -- first non-auto trait comes from this alias | | - | trait alias used in trait object type (first use) + | second non-auto trait comes from this alias | - = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjA + ObjB {}` + = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjB + ObjA {}` = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits> error[E0225]: only auto traits can be used as additional traits in a trait object - --> $DIR/no-extra-traits.rs:68:36 + --> $DIR/no-extra-traits.rs:68:31 | LL | trait _5 = Sync + ObjB + Send; - | ---- first non-auto trait + | ---- additional non-auto trait ... LL | type _T26 = dyn Sync + Send + _5 + ObjA; - | -- ^^^^ additional non-auto trait + | ^^ ---- first non-auto trait | | - | trait alias used in trait object type (first use) + | second non-auto trait comes from this alias | - = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjB + ObjA {}` + = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjA + ObjB {}` = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits> error[E0225]: only auto traits can be used as additional traits in a trait object @@ -263,7 +263,7 @@ LL | trait _5 = Sync + ObjB + Send; | ---- additional non-auto trait ... LL | type _T27 = dyn Send + Sync + ObjA + _5; - | ---- ^^ trait alias used in trait object type (additional use) + | ---- ^^ second non-auto trait comes from this alias | | | first non-auto trait | @@ -274,199 +274,199 @@ error[E0225]: only auto traits can be used as additional traits in a trait objec --> $DIR/no-extra-traits.rs:80:17 | LL | trait _0 = ObjA; - | ---- first non-auto trait + | ---- additional non-auto trait LL | trait _1 = _0; - | -- referenced here (first use) + | -- second non-auto trait comes from this alias ... LL | trait _5 = Sync + ObjB + Send; - | ---- additional non-auto trait + | ---- first non-auto trait ... LL | trait _6 = _1 + _5; - | -- -- referenced here (additional use) + | -- -- first non-auto trait comes from this alias | | - | referenced here (first use) + | second non-auto trait comes from this alias ... LL | type _T30 = dyn _6; | ^^ | | - | trait alias used in trait object type (additional use) - | trait alias used in trait object type (first use) + | first non-auto trait comes from this alias + | second non-auto trait comes from this alias | - = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjA + ObjB {}` + = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjB + ObjA {}` = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits> error[E0225]: only auto traits can be used as additional traits in a trait object --> $DIR/no-extra-traits.rs:83:17 | LL | trait _0 = ObjA; - | ---- first non-auto trait + | ---- additional non-auto trait LL | trait _1 = _0; - | -- referenced here (first use) + | -- second non-auto trait comes from this alias ... LL | trait _5 = Sync + ObjB + Send; - | ---- additional non-auto trait + | ---- first non-auto trait ... LL | trait _6 = _1 + _5; - | -- -- referenced here (additional use) + | -- -- first non-auto trait comes from this alias | | - | referenced here (first use) + | second non-auto trait comes from this alias ... LL | type _T31 = dyn _6 + Send; | ^^ | | - | trait alias used in trait object type (additional use) - | trait alias used in trait object type (first use) + | first non-auto trait comes from this alias + | second non-auto trait comes from this alias | - = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjA + ObjB {}` + = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjB + ObjA {}` = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits> error[E0225]: only auto traits can be used as additional traits in a trait object --> $DIR/no-extra-traits.rs:86:24 | LL | trait _0 = ObjA; - | ---- first non-auto trait + | ---- additional non-auto trait LL | trait _1 = _0; - | -- referenced here (first use) + | -- second non-auto trait comes from this alias ... LL | trait _5 = Sync + ObjB + Send; - | ---- additional non-auto trait + | ---- first non-auto trait ... LL | trait _6 = _1 + _5; - | -- -- referenced here (additional use) + | -- -- first non-auto trait comes from this alias | | - | referenced here (first use) + | second non-auto trait comes from this alias ... LL | type _T32 = dyn Send + _6; | ^^ | | - | trait alias used in trait object type (additional use) - | trait alias used in trait object type (first use) + | first non-auto trait comes from this alias + | second non-auto trait comes from this alias | - = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjA + ObjB {}` + = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjB + ObjA {}` = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits> error[E0225]: only auto traits can be used as additional traits in a trait object --> $DIR/no-extra-traits.rs:89:17 | LL | trait _0 = ObjA; - | ---- first non-auto trait + | ---- additional non-auto trait LL | trait _1 = _0; - | -- referenced here (first use) + | -- second non-auto trait comes from this alias ... LL | trait _5 = Sync + ObjB + Send; - | ---- additional non-auto trait + | ---- first non-auto trait ... LL | trait _6 = _1 + _5; - | -- -- referenced here (additional use) + | -- -- first non-auto trait comes from this alias | | - | referenced here (first use) + | second non-auto trait comes from this alias LL | trait _7 = _6; | -- | | - | referenced here (additional use) - | referenced here (first use) + | first non-auto trait comes from this alias + | second non-auto trait comes from this alias LL | trait _8 = _7; | -- | | - | referenced here (additional use) - | referenced here (first use) + | first non-auto trait comes from this alias + | second non-auto trait comes from this alias ... LL | type _T33 = dyn _8; | ^^ | | - | trait alias used in trait object type (additional use) - | trait alias used in trait object type (first use) + | first non-auto trait comes from this alias + | second non-auto trait comes from this alias | - = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjA + ObjB {}` + = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjB + ObjA {}` = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits> error[E0225]: only auto traits can be used as additional traits in a trait object --> $DIR/no-extra-traits.rs:92:17 | LL | trait _0 = ObjA; - | ---- first non-auto trait + | ---- additional non-auto trait LL | trait _1 = _0; - | -- referenced here (first use) + | -- second non-auto trait comes from this alias ... LL | trait _5 = Sync + ObjB + Send; - | ---- additional non-auto trait + | ---- first non-auto trait ... LL | trait _6 = _1 + _5; - | -- -- referenced here (additional use) + | -- -- first non-auto trait comes from this alias | | - | referenced here (first use) + | second non-auto trait comes from this alias LL | trait _7 = _6; | -- | | - | referenced here (additional use) - | referenced here (first use) + | first non-auto trait comes from this alias + | second non-auto trait comes from this alias LL | trait _8 = _7; | -- | | - | referenced here (additional use) - | referenced here (first use) + | first non-auto trait comes from this alias + | second non-auto trait comes from this alias ... LL | type _T34 = dyn _8 + Send; | ^^ | | - | trait alias used in trait object type (additional use) - | trait alias used in trait object type (first use) + | first non-auto trait comes from this alias + | second non-auto trait comes from this alias | - = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjA + ObjB {}` + = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjB + ObjA {}` = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits> error[E0225]: only auto traits can be used as additional traits in a trait object --> $DIR/no-extra-traits.rs:95:24 | LL | trait _0 = ObjA; - | ---- first non-auto trait + | ---- additional non-auto trait LL | trait _1 = _0; - | -- referenced here (first use) + | -- second non-auto trait comes from this alias ... LL | trait _5 = Sync + ObjB + Send; - | ---- additional non-auto trait + | ---- first non-auto trait ... LL | trait _6 = _1 + _5; - | -- -- referenced here (additional use) + | -- -- first non-auto trait comes from this alias | | - | referenced here (first use) + | second non-auto trait comes from this alias LL | trait _7 = _6; | -- | | - | referenced here (additional use) - | referenced here (first use) + | first non-auto trait comes from this alias + | second non-auto trait comes from this alias LL | trait _8 = _7; | -- | | - | referenced here (additional use) - | referenced here (first use) + | first non-auto trait comes from this alias + | second non-auto trait comes from this alias ... LL | type _T35 = dyn Send + _8; | ^^ | | - | trait alias used in trait object type (additional use) - | trait alias used in trait object type (first use) + | first non-auto trait comes from this alias + | second non-auto trait comes from this alias | - = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjA + ObjB {}` + = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjB + ObjA {}` = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits> error[E0225]: only auto traits can be used as additional traits in a trait object - --> $DIR/no-extra-traits.rs:103:23 + --> $DIR/no-extra-traits.rs:103:17 | LL | trait _5 = Sync + ObjB + Send; - | ---- first non-auto trait + | ---- additional non-auto trait ... LL | trait _9 = _5 + Sync; - | -- referenced here (first use) + | -- second non-auto trait comes from this alias LL | trait _10 = Unpin + _9; - | -- referenced here (first use) + | -- second non-auto trait comes from this alias LL | LL | type _T40 = dyn _10 + ObjA; - | --- ^^^^ additional non-auto trait + | ^^^ ---- first non-auto trait | | - | trait alias used in trait object type (first use) + | second non-auto trait comes from this alias | - = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjB + ObjA {}` + = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjA + ObjB {}` = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits> error[E0225]: only auto traits can be used as additional traits in a trait object @@ -476,12 +476,12 @@ LL | trait _5 = Sync + ObjB + Send; | ---- additional non-auto trait ... LL | trait _9 = _5 + Sync; - | -- referenced here (additional use) + | -- second non-auto trait comes from this alias LL | trait _10 = Unpin + _9; - | -- referenced here (additional use) + | -- second non-auto trait comes from this alias ... LL | type _T41 = dyn ObjA + _10; - | ---- ^^^ trait alias used in trait object type (additional use) + | ---- ^^^ second non-auto trait comes from this alias | | | first non-auto trait | @@ -489,46 +489,46 @@ LL | type _T41 = dyn ObjA + _10; = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits> error[E0225]: only auto traits can be used as additional traits in a trait object - --> $DIR/no-extra-traits.rs:109:23 + --> $DIR/no-extra-traits.rs:109:17 | LL | trait _0 = ObjA; - | ---- additional non-auto trait + | ---- first non-auto trait LL | trait _1 = _0; - | -- referenced here (additional use) + | -- first non-auto trait comes from this alias ... LL | trait _5 = Sync + ObjB + Send; - | ---- first non-auto trait + | ---- additional non-auto trait ... LL | trait _9 = _5 + Sync; - | -- referenced here (first use) + | -- second non-auto trait comes from this alias LL | trait _10 = Unpin + _9; - | -- referenced here (first use) + | -- second non-auto trait comes from this alias ... LL | type _T42 = dyn _10 + _1; - | --- ^^ trait alias used in trait object type (additional use) + | ^^^ -- first non-auto trait comes from this alias | | - | trait alias used in trait object type (first use) + | second non-auto trait comes from this alias | - = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjB + ObjA {}` + = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjA + ObjB {}` = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits> error[E0225]: only auto traits can be used as additional traits in a trait object - --> $DIR/no-extra-traits.rs:112:37 + --> $DIR/no-extra-traits.rs:112:24 | LL | trait _5 = Sync + ObjB + Send; - | ---- first non-auto trait + | ---- additional non-auto trait ... LL | trait _9 = _5 + Sync; - | -- referenced here (first use) + | -- second non-auto trait comes from this alias LL | trait _10 = Unpin + _9; - | -- referenced here (first use) + | -- second non-auto trait comes from this alias ... LL | type _T43 = dyn Send + _10 + Sync + ObjA; - | --- ^^^^ additional non-auto trait + | ^^^ ---- first non-auto trait | | - | trait alias used in trait object type (first use) + | second non-auto trait comes from this alias | - = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjB + ObjA {}` + = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjA + ObjB {}` = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits> error[E0225]: only auto traits can be used as additional traits in a trait object @@ -538,12 +538,12 @@ LL | trait _5 = Sync + ObjB + Send; | ---- additional non-auto trait ... LL | trait _9 = _5 + Sync; - | -- referenced here (additional use) + | -- second non-auto trait comes from this alias LL | trait _10 = Unpin + _9; - | -- referenced here (additional use) + | -- second non-auto trait comes from this alias ... LL | type _T44 = dyn ObjA + _10 + Send + Sync; - | ---- ^^^ trait alias used in trait object type (additional use) + | ---- ^^^ second non-auto trait comes from this alias | | | first non-auto trait | @@ -551,27 +551,27 @@ LL | type _T44 = dyn ObjA + _10 + Send + Sync; = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits> error[E0225]: only auto traits can be used as additional traits in a trait object - --> $DIR/no-extra-traits.rs:118:37 + --> $DIR/no-extra-traits.rs:118:31 | LL | trait _0 = ObjA; - | ---- additional non-auto trait + | ---- first non-auto trait LL | trait _1 = _0; - | -- referenced here (additional use) + | -- first non-auto trait comes from this alias ... LL | trait _5 = Sync + ObjB + Send; - | ---- first non-auto trait + | ---- additional non-auto trait ... LL | trait _9 = _5 + Sync; - | -- referenced here (first use) + | -- second non-auto trait comes from this alias LL | trait _10 = Unpin + _9; - | -- referenced here (first use) + | -- second non-auto trait comes from this alias ... LL | type _T45 = dyn Sync + Send + _10 + _1; - | --- ^^ trait alias used in trait object type (additional use) + | ^^^ -- first non-auto trait comes from this alias | | - | trait alias used in trait object type (first use) + | second non-auto trait comes from this alias | - = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjB + ObjA {}` + = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: ObjA + ObjB {}` = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits> error: aborting due to 28 previous errors diff --git a/tests/ui/traits/alias/object-fail.rs b/tests/ui/traits/alias/object-fail.rs index 5c753ff207c..38da7b8eef4 100644 --- a/tests/ui/traits/alias/object-fail.rs +++ b/tests/ui/traits/alias/object-fail.rs @@ -5,7 +5,7 @@ trait IteratorAlias = Iterator; fn main() { let _: &dyn EqAlias = &123; - //~^ ERROR the trait `Eq` cannot be made into an object [E0038] + //~^ ERROR the trait alias `EqAlias` cannot be made into an object [E0038] let _: &dyn IteratorAlias = &vec![123].into_iter(); //~^ ERROR must be specified } diff --git a/tests/ui/traits/alias/object-fail.stderr b/tests/ui/traits/alias/object-fail.stderr index 1b89b87db9f..e4968ee2adc 100644 --- a/tests/ui/traits/alias/object-fail.stderr +++ b/tests/ui/traits/alias/object-fail.stderr @@ -1,13 +1,18 @@ -error[E0038]: the trait `Eq` cannot be made into an object - --> $DIR/object-fail.rs:7:13 +error[E0038]: the trait alias `EqAlias` cannot be made into an object + --> $DIR/object-fail.rs:7:17 | LL | let _: &dyn EqAlias = &123; - | ^^^^^^^^^^^ `Eq` cannot be made into an object + | ^^^^^^^ `EqAlias` cannot be made into an object | note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> --> $SRC_DIR/core/src/cmp.rs:LL:COL | - = note: the trait cannot be made into an object because it uses `Self` as a type parameter + = note: ...because it uses `Self` as a type parameter + | + ::: $DIR/object-fail.rs:3:7 + | +LL | trait EqAlias = Eq; + | ------- this trait cannot be made into an object... error[E0191]: the value of the associated type `Item` in `Iterator` must be specified --> $DIR/object-fail.rs:9:17 diff --git a/tests/ui/traits/alias/self-in-const-generics.stderr b/tests/ui/traits/alias/self-in-const-generics.stderr index 3de31b64c8b..6dd6fabe7b2 100644 --- a/tests/ui/traits/alias/self-in-const-generics.stderr +++ b/tests/ui/traits/alias/self-in-const-generics.stderr @@ -2,9 +2,19 @@ error[E0038]: the trait alias `BB` cannot be made into an object --> $DIR/self-in-const-generics.rs:9:16 | LL | fn foo(x: &dyn BB) {} - | ^^ + | ^^ `BB` cannot be made into an object | - = note: it cannot use `Self` as a type parameter in a supertrait or `where`-clause +note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + --> $DIR/self-in-const-generics.rs:7:12 + | +LL | trait BB = Bar<{ 2 + 1 }>; + | -- ^^^^^^^^^^^^^^ ...because it uses `Self` as a type parameter + | | + | this trait cannot be made into an object... +help: consider using an opaque type instead + | +LL | fn foo(x: &impl BB) {} + | ~~~~ error: aborting due to 1 previous error diff --git a/tests/ui/traits/alias/self-in-generics.stderr b/tests/ui/traits/alias/self-in-generics.stderr index ffc0a00ad7d..4fbd979e5f5 100644 --- a/tests/ui/traits/alias/self-in-generics.stderr +++ b/tests/ui/traits/alias/self-in-generics.stderr @@ -2,9 +2,21 @@ error[E0038]: the trait alias `SelfInput` cannot be made into an object --> $DIR/self-in-generics.rs:8:19 | LL | pub fn f(_f: &dyn SelfInput) {} - | ^^^^^^^^^ + | ^^^^^^^^^ `SelfInput` cannot be made into an object | - = note: it cannot use `Self` as a type parameter in a supertrait or `where`-clause +note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + --> $DIR/self-in-generics.rs:6:23 + | +LL | pub trait SelfInput = Fn(&mut Self); + | --------- ^^^^^^^^^^^^^ + | | | + | | ...because it uses `Self` as a type parameter + | | ...because it uses `Self` as a type parameter + | this trait cannot be made into an object... +help: consider using an opaque type instead + | +LL | pub fn f(_f: &impl SelfInput) {} + | ~~~~ error: aborting due to 1 previous error diff --git a/tests/ui/traits/bad-sized.stderr b/tests/ui/traits/bad-sized.stderr index 0e82867ef03..21718cf0951 100644 --- a/tests/ui/traits/bad-sized.stderr +++ b/tests/ui/traits/bad-sized.stderr @@ -1,12 +1,12 @@ error[E0225]: only auto traits can be used as additional traits in a trait object - --> $DIR/bad-sized.rs:4:28 + --> $DIR/bad-sized.rs:4:20 | LL | let x: Vec<dyn Trait + Sized> = Vec::new(); - | ----- ^^^^^ additional non-auto trait + | ^^^^^ ----- first non-auto trait | | - | first non-auto trait + | additional non-auto trait | - = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Trait + Sized {}` + = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Sized + Trait {}` = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits> error: aborting due to 1 previous error diff --git a/tests/ui/traits/issue-28576.stderr b/tests/ui/traits/issue-28576.stderr index 23581f2ee51..cb0d55dce59 100644 --- a/tests/ui/traits/issue-28576.stderr +++ b/tests/ui/traits/issue-28576.stderr @@ -19,9 +19,10 @@ LL | pub trait Foo<RHS: ?Sized=Self> { | ++++++++ error[E0038]: the trait `Bar` cannot be made into an object - --> $DIR/issue-28576.rs:9:12 + --> $DIR/issue-28576.rs:9:16 | -LL | / dyn Bar +LL | dyn Bar + | ________________^ LL | | <Assoc=()> | |________________________^ `Bar` cannot be made into an object | diff --git a/tests/ui/traits/issue-38404.stderr b/tests/ui/traits/issue-38404.stderr index 145eeb88dd5..98d49fa3cba 100644 --- a/tests/ui/traits/issue-38404.stderr +++ b/tests/ui/traits/issue-38404.stderr @@ -1,8 +1,8 @@ error[E0038]: the trait `B` cannot be made into an object - --> $DIR/issue-38404.rs:3:15 + --> $DIR/issue-38404.rs:3:19 | LL | trait C<T>: A<dyn B<T, Output = usize>> {} - | ^^^^^^^^^^^^^^^^^^^^^^^^ `B` cannot be made into an object + | ^^^^^^^^^^^^^^^^^^^^ `B` cannot be made into an object | note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> --> $DIR/issue-38404.rs:1:13 @@ -13,10 +13,10 @@ LL | trait B<T>: A<T> {} | - this trait cannot be made into an object... error[E0038]: the trait `B` cannot be made into an object - --> $DIR/issue-38404.rs:3:15 + --> $DIR/issue-38404.rs:3:19 | LL | trait C<T>: A<dyn B<T, Output = usize>> {} - | ^^^^^^^^^^^^^^^^^^^^^^^^ `B` cannot be made into an object + | ^^^^^^^^^^^^^^^^^^^^ `B` cannot be made into an object | note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> --> $DIR/issue-38404.rs:1:13 @@ -28,10 +28,10 @@ LL | trait B<T>: A<T> {} = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0038]: the trait `B` cannot be made into an object - --> $DIR/issue-38404.rs:3:15 + --> $DIR/issue-38404.rs:3:19 | LL | trait C<T>: A<dyn B<T, Output = usize>> {} - | ^^^^^^^^^^^^^^^^^^^^^^^^ `B` cannot be made into an object + | ^^^^^^^^^^^^^^^^^^^^ `B` cannot be made into an object | note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> --> $DIR/issue-38404.rs:1:13 diff --git a/tests/ui/traits/object/canonicalize-fresh-infer-vars-issue-103626.rs b/tests/ui/traits/object/canonicalize-fresh-infer-vars-issue-103626.rs index 4aadd45c49c..3af299e5b11 100644 --- a/tests/ui/traits/object/canonicalize-fresh-infer-vars-issue-103626.rs +++ b/tests/ui/traits/object/canonicalize-fresh-infer-vars-issue-103626.rs @@ -10,7 +10,6 @@ fn w<'a, T: 'a, F: Fn(&'a T)>() { let b: &dyn FromResidual = &(); //~^ ERROR: the trait `FromResidual` cannot be made into an object //~| ERROR: the trait `FromResidual` cannot be made into an object - //~| ERROR: the trait `FromResidual` cannot be made into an object } fn main() {} diff --git a/tests/ui/traits/object/canonicalize-fresh-infer-vars-issue-103626.stderr b/tests/ui/traits/object/canonicalize-fresh-infer-vars-issue-103626.stderr index c67a8c05379..a131227e78e 100644 --- a/tests/ui/traits/object/canonicalize-fresh-infer-vars-issue-103626.stderr +++ b/tests/ui/traits/object/canonicalize-fresh-infer-vars-issue-103626.stderr @@ -1,12 +1,4 @@ error[E0038]: the trait `FromResidual` cannot be made into an object - --> $DIR/canonicalize-fresh-infer-vars-issue-103626.rs:10:17 - | -LL | let b: &dyn FromResidual = &(); - | ^^^^^^^^^^^^ - | - = note: it cannot use `Self` as a type parameter in a supertrait or `where`-clause - -error[E0038]: the trait `FromResidual` cannot be made into an object --> $DIR/canonicalize-fresh-infer-vars-issue-103626.rs:10:32 | LL | let b: &dyn FromResidual = &(); @@ -51,6 +43,6 @@ help: alternatively, consider constraining `from_residual` so it does not apply LL | fn from_residual(residual: R) -> Self where Self: Sized; | +++++++++++++++++ -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0038`. |
