From 30e608285361e12da5aeac73b2fbe57362341042 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 2 Jun 2026 13:03:09 +0200 Subject: [PATCH 1/3] Generalize where bound handling --- .../src/collect/item_bounds.rs | 4 ++ .../src/collect/predicates_of.rs | 16 ++++-- .../src/hir_ty_lowering/bounds.rs | 49 ++++++++++++------- .../src/hir_ty_lowering/dyn_trait.rs | 1 + .../src/hir_ty_lowering/mod.rs | 5 +- 5 files changed, 52 insertions(+), 23 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs index 46007503539ca..625c1ce3fa610 100644 --- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs +++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs @@ -59,6 +59,7 @@ fn associated_type_bounds<'tcx>( &mut bounds, item_ty, hir_bounds, + &[], ImpliedBoundsContext::AssociatedTypeOrImplTrait, span, ); @@ -66,6 +67,7 @@ fn associated_type_bounds<'tcx>( &mut bounds, item_ty, hir_bounds, + &[], ImpliedBoundsContext::AssociatedTypeOrImplTrait, span, ); @@ -386,6 +388,7 @@ fn opaque_type_bounds<'tcx>( &mut bounds, item_ty, hir_bounds, + &[], ImpliedBoundsContext::AssociatedTypeOrImplTrait, span, ); @@ -393,6 +396,7 @@ fn opaque_type_bounds<'tcx>( &mut bounds, item_ty, hir_bounds, + &[], ImpliedBoundsContext::AssociatedTypeOrImplTrait, span, ); diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index e1798c24838d1..7cbfea65bc63d 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -200,6 +200,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen &mut bounds, tcx.types.self_param, self_bounds, + &[], ImpliedBoundsContext::TraitDef(def_id), span, ); @@ -207,6 +208,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen &mut bounds, tcx.types.self_param, self_bounds, + &[], ImpliedBoundsContext::TraitDef(def_id), span, ); @@ -239,14 +241,16 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen &mut bounds, param_ty, &[], - ImpliedBoundsContext::TyParam(param.def_id, hir_generics.predicates), + hir_generics.predicates, + ImpliedBoundsContext::TyParam(param.def_id), param.span, ); icx.lowerer().add_default_traits( &mut bounds, param_ty, &[], - ImpliedBoundsContext::TyParam(param.def_id, hir_generics.predicates), + hir_generics.predicates, + ImpliedBoundsContext::TyParam(param.def_id), param.span, ); trace!(?bounds); @@ -691,6 +695,7 @@ pub(super) fn implied_predicates_with_filter<'tcx>( &mut bounds, self_param_ty, superbounds, + &[], ImpliedBoundsContext::TraitDef(trait_def_id), item.span, ); @@ -698,6 +703,7 @@ pub(super) fn implied_predicates_with_filter<'tcx>( &mut bounds, self_param_ty, superbounds, + &[], ImpliedBoundsContext::TraitDef(trait_def_id), item.span, ); @@ -993,14 +999,16 @@ impl<'tcx> ItemCtxt<'tcx> { &mut bounds, param_ty, &[], - ImpliedBoundsContext::TyParam(param.def_id, hir_generics.predicates), + hir_generics.predicates, + ImpliedBoundsContext::TyParam(param.def_id), param.span, ); self.lowerer().add_default_traits( &mut bounds, param_ty, &[], - ImpliedBoundsContext::TyParam(param.def_id, hir_generics.predicates), + hir_generics.predicates, + ImpliedBoundsContext::TyParam(param.def_id), param.span, ); } diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs index 810e14a7d6d0b..7f3af0f07ed29 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs @@ -59,7 +59,8 @@ impl CollectedSizednessBounds { fn search_bounds_for<'tcx>( hir_bounds: &'tcx [hir::GenericBound<'tcx>], - context: ImpliedBoundsContext<'tcx>, + where_bounds: &'tcx [hir::WherePredicate<'tcx>], + context: ImpliedBoundsContext, mut f: impl FnMut(&'tcx PolyTraitRef<'tcx>), ) { let mut search_bounds = |hir_bounds: &'tcx [hir::GenericBound<'tcx>]| { @@ -73,8 +74,8 @@ fn search_bounds_for<'tcx>( }; search_bounds(hir_bounds); - if let ImpliedBoundsContext::TyParam(self_ty, where_clause) = context { - for clause in where_clause { + if let ImpliedBoundsContext::TyParam(self_ty) = context { + for clause in where_bounds { if let hir::WherePredicateKind::BoundPredicate(pred) = clause.kind && pred.is_param_bound(self_ty.to_def_id()) { @@ -86,11 +87,12 @@ fn search_bounds_for<'tcx>( fn collect_bounds<'a, 'tcx>( hir_bounds: &'a [hir::GenericBound<'tcx>], - context: ImpliedBoundsContext<'tcx>, + where_bounds: &'tcx [hir::WherePredicate<'tcx>], + context: ImpliedBoundsContext, target_did: DefId, ) -> CollectedBound { let mut collect_into = CollectedBound::default(); - search_bounds_for(hir_bounds, context, |ptr| { + search_bounds_for(hir_bounds, where_bounds, context, |ptr| { if !matches!(ptr.trait_ref.path.res, Res::Def(DefKind::Trait, did) if did == target_did) { return; } @@ -107,17 +109,18 @@ fn collect_bounds<'a, 'tcx>( fn collect_sizedness_bounds<'tcx>( tcx: TyCtxt<'tcx>, hir_bounds: &'tcx [hir::GenericBound<'tcx>], - context: ImpliedBoundsContext<'tcx>, + where_bounds: &'tcx [hir::WherePredicate<'tcx>], + context: ImpliedBoundsContext, span: Span, ) -> CollectedSizednessBounds { let sized_did = tcx.require_lang_item(hir::LangItem::Sized, span); - let sized = collect_bounds(hir_bounds, context, sized_did); + let sized = collect_bounds(hir_bounds, where_bounds, context, sized_did); let meta_sized_did = tcx.require_lang_item(hir::LangItem::MetaSized, span); - let meta_sized = collect_bounds(hir_bounds, context, meta_sized_did); + let meta_sized = collect_bounds(hir_bounds, where_bounds, context, meta_sized_did); let pointee_sized_did = tcx.require_lang_item(hir::LangItem::PointeeSized, span); - let pointee_sized = collect_bounds(hir_bounds, context, pointee_sized_did); + let pointee_sized = collect_bounds(hir_bounds, where_bounds, context, pointee_sized_did); CollectedSizednessBounds { sized, meta_sized, pointee_sized } } @@ -150,7 +153,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { bounds: &mut Vec<(ty::Clause<'tcx>, Span)>, self_ty: Ty<'tcx>, hir_bounds: &'tcx [hir::GenericBound<'tcx>], - context: ImpliedBoundsContext<'tcx>, + where_bounds: &'tcx [hir::WherePredicate<'tcx>], + context: ImpliedBoundsContext, span: Span, ) { let tcx = self.tcx(); @@ -180,7 +184,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ImpliedBoundsContext::TyParam(..) | ImpliedBoundsContext::AssociatedTypeOrImplTrait => { } } - let collected = collect_sizedness_bounds(tcx, hir_bounds, context, span); + let collected = collect_sizedness_bounds(tcx, hir_bounds, where_bounds, context, span); if let Some(span) = collected.sized.maybe.or(collected.sized.negative) && collected.sized.positive.is_none() && !collected.meta_sized.any() @@ -212,11 +216,20 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { bounds: &mut Vec<(ty::Clause<'tcx>, Span)>, self_ty: Ty<'tcx>, hir_bounds: &[hir::GenericBound<'tcx>], - context: ImpliedBoundsContext<'tcx>, + where_bounds: &'tcx [hir::WherePredicate<'tcx>], + context: ImpliedBoundsContext, span: Span, ) { self.tcx().default_traits().iter().for_each(|default_trait| { - self.add_default_trait(*default_trait, bounds, self_ty, hir_bounds, context, span); + self.add_default_trait( + *default_trait, + bounds, + self_ty, + hir_bounds, + where_bounds, + context, + span, + ); }); } @@ -229,7 +242,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { bounds: &mut Vec<(ty::Clause<'tcx>, Span)>, self_ty: Ty<'tcx>, hir_bounds: &[hir::GenericBound<'tcx>], - context: ImpliedBoundsContext<'tcx>, + where_bounds: &'tcx [hir::WherePredicate<'tcx>], + context: ImpliedBoundsContext, span: Span, ) { let tcx = self.tcx(); @@ -243,7 +257,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } if let Some(trait_did) = tcx.lang_items().get(trait_) - && self.should_add_default_traits(trait_did, hir_bounds, context) + && self.should_add_default_traits(trait_did, hir_bounds, where_bounds, context) { add_trait_bound(tcx, bounds, self_ty, trait_did, span); } @@ -254,9 +268,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { &self, trait_def_id: DefId, hir_bounds: &'a [hir::GenericBound<'tcx>], - context: ImpliedBoundsContext<'tcx>, + where_bounds: &'tcx [hir::WherePredicate<'tcx>], + context: ImpliedBoundsContext, ) -> bool { - let collected = collect_bounds(hir_bounds, context, trait_def_id); + let collected = collect_bounds(hir_bounds, where_bounds, context, trait_def_id); !find_attr!(self.tcx(), crate, RustcNoImplicitBounds) && !collected.any() } diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs index f9ff76e293614..69fd46c418647 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs @@ -83,6 +83,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { .iter() .map(|&trait_ref| hir::GenericBound::Trait(trait_ref)) .collect::>(), + &[], ImpliedBoundsContext::AssociatedTypeOrImplTrait, span, ); diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index baa9fddc2a651..a0c74444e47a5 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -59,12 +59,12 @@ use crate::{NoVariantNamed, check_c_variadic_abi}; /// The context in which an implied bound is being added to a item being lowered (i.e. a sizedness /// trait or a default trait) #[derive(Clone, Copy)] -pub(crate) enum ImpliedBoundsContext<'tcx> { +pub(crate) enum ImpliedBoundsContext { /// An implied bound is added to a trait definition (i.e. a new supertrait), used when adding /// a default `MetaSized` supertrait TraitDef(LocalDefId), /// An implied bound is added to a type parameter - TyParam(LocalDefId, &'tcx [hir::WherePredicate<'tcx>]), + TyParam(LocalDefId), /// An implied bound being added in any other context AssociatedTypeOrImplTrait, } @@ -3174,6 +3174,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { &mut bounds, self_ty, hir_bounds, + &[], ImpliedBoundsContext::AssociatedTypeOrImplTrait, hir_ty.span, ); From 57ca019d3df7538cd446a28a659cf3fcf70353e3 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 2 Jun 2026 10:28:51 +0200 Subject: [PATCH 2/3] Exhaustively match on `DesugaringKind` --- compiler/rustc_span/src/hygiene.rs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs index 1c742052783cd..a2537939ff8ad 100644 --- a/compiler/rustc_span/src/hygiene.rs +++ b/compiler/rustc_span/src/hygiene.rs @@ -928,7 +928,17 @@ impl SyntaxContext { | DesugaringKind::Async | DesugaringKind::Await, ) => false, - ExpnKind::AstPass(_) | ExpnKind::Desugaring(_) => true, // well, it's "external" + ExpnKind::AstPass(_) + | ExpnKind::Desugaring( + DesugaringKind::BoundModifier + | DesugaringKind::QuestionMark + | DesugaringKind::TryBlock + | DesugaringKind::Contract + | DesugaringKind::RangeExpr + | DesugaringKind::PatTyRange + | DesugaringKind::FormatLiteral { .. } + | DesugaringKind::YeetExpr, + ) => true, // well, it's "external" ExpnKind::Macro(MacroKind::Bang, _) => { // Dummy span for the `def_site` means it's an external macro. expn_data.def_site.is_dummy() || sm.is_imported(expn_data.def_site) From 281145159ee65b968f0eefdedd9b5cc1d50f64e7 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 2 Jun 2026 10:16:10 +0200 Subject: [PATCH 3/3] Add expansion info to default bounds --- .../src/delegation/generics.rs | 1 + compiler/rustc_ast_lowering/src/lib.rs | 20 ++++++++++++++--- compiler/rustc_hir/src/hir.rs | 1 + compiler/rustc_hir/src/intravisit.rs | 1 + .../rustc_hir_analysis/src/check/check.rs | 6 +++-- .../src/collect/predicates_of.rs | 8 +++---- .../rustc_hir_typeck/src/method/suggest.rs | 8 +++---- compiler/rustc_span/src/hygiene.rs | 10 +++++++++ .../src/error_reporting/traits/suggestions.rs | 22 ++++++++----------- tests/ui/box/into-boxed-slice-fail.stderr | 4 ++-- tests/ui/closures/unsized_value_move.stderr | 2 +- tests/ui/coherence/deep-bad-copy-reason.rs | 1 + .../ui/coherence/deep-bad-copy-reason.stderr | 6 ++--- tests/ui/dst/dst-rvalue.stderr | 4 ++-- tests/ui/stats/input-stats.stderr | 4 ++-- .../enum-unit-variant-trait-bound.stderr | 2 +- 16 files changed, 63 insertions(+), 37 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/delegation/generics.rs b/compiler/rustc_ast_lowering/src/delegation/generics.rs index 79a3961c22a53..bdf0d82097601 100644 --- a/compiler/rustc_ast_lowering/src/delegation/generics.rs +++ b/compiler/rustc_ast_lowering/src/delegation/generics.rs @@ -518,6 +518,7 @@ impl<'hir> LoweringContext<'_, 'hir> { pure_wrt_drop: p.pure_wrt_drop, source: hir::GenericParamSource::Generics, span, + implicit_bounds_span: span, }) })); diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 06e83a7486100..3c4fa85a92b74 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -1068,15 +1068,17 @@ impl<'hir> LoweringContext<'_, 'hir> { let hir_id = self.lower_node_id(node_id); let def_id = self.local_def_id(node_id); + let span = self.lower_span(ident.span); hir::GenericParam { hir_id, def_id, name: hir::ParamName::Fresh, - span: self.lower_span(ident.span), + span, pure_wrt_drop: false, kind: hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Elided(kind) }, colon_span: None, source, + implicit_bounds_span: span, } } @@ -2206,15 +2208,26 @@ impl<'hir> LoweringContext<'_, 'hir> { let hir_id = self.lower_node_id(param.id); let param_attrs = ¶m.attrs; let param_span = param.span(); + let def_id = self.local_def_id(param.id); + let span = self.lower_span(param.span()); let param = hir::GenericParam { hir_id, - def_id: self.local_def_id(param.id), + def_id, name, - span: self.lower_span(param.span()), + span, pure_wrt_drop: attr::contains_name(¶m.attrs, sym::may_dangle), kind, colon_span: param.colon_span.map(|s| self.lower_span(s)), source, + implicit_bounds_span: match kind { + hir::GenericParamKind::Lifetime { .. } => span, + hir::GenericParamKind::Type { .. } => self.mark_span_with_reason( + DesugaringKind::DefaultBound { def_id: def_id.into() }, + span, + None, + ), + hir::GenericParamKind::Const { .. } => span, + }, }; self.lower_attrs(hir_id, param_attrs, param_span, Target::from_generic_param(¶m)); param @@ -2482,6 +2495,7 @@ impl<'hir> LoweringContext<'_, 'hir> { kind: hir::GenericParamKind::Type { default: None, synthetic: true }, colon_span: None, source: hir::GenericParamSource::Generics, + implicit_bounds_span: span, }; let preds = self.lower_generic_bound_predicate( diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index f429d14e3a51c..416f0ed90665f 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -834,6 +834,7 @@ pub struct GenericParam<'hir> { #[stable_hash(ignore)] pub hir_id: HirId, pub def_id: LocalDefId, + pub implicit_bounds_span: Span, pub name: ParamName, pub span: Span, pub pure_wrt_drop: bool, diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 9e0eaef596420..5f0fb06a88da8 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -1133,6 +1133,7 @@ pub fn walk_generic_param<'v, V: Visitor<'v>>( kind, colon_span: _, source: _, + implicit_bounds_span: _, } = param; try_visit!(visitor.visit_id(*hir_id)); match *name { diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index e98307c7c7b18..4b57b40a268da 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -24,7 +24,7 @@ use rustc_middle::ty::{ TypeVisitable, TypeVisitableExt, Unnormalized, fold_regions, }; use rustc_session::lint::builtin::UNINHABITED_STATIC; -use rustc_span::sym; +use rustc_span::{DesugaringKind, sym}; use rustc_target::spec::{AbiMap, AbiMapping}; use rustc_trait_selection::error_reporting::InferCtxtErrorExt; use rustc_trait_selection::traits; @@ -2117,7 +2117,9 @@ fn check_type_alias_type_params_are_used<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalD // * check for emptiness to detect lone user-written `?Sized` bounds // * compare the param span to the pred span to detect lone user-written `Sized` bounds let has_explicit_bounds = bounded_params.is_empty() - || (*bounded_params).get(¶m.index).is_some_and(|&&pred_sp| pred_sp != span); + || (*bounded_params).get(¶m.index).is_some_and(|&&pred_sp| { + !pred_sp.is_desugaring(DesugaringKind::DefaultBound { def_id: param.def_id }) + }); let const_param_help = !has_explicit_bounds; let mut diag = tcx.dcx().create_err(diagnostics::UnusedGenericParameter { diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index 7cbfea65bc63d..f7717d17229c4 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -243,7 +243,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen &[], hir_generics.predicates, ImpliedBoundsContext::TyParam(param.def_id), - param.span, + param.implicit_bounds_span, ); icx.lowerer().add_default_traits( &mut bounds, @@ -251,7 +251,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen &[], hir_generics.predicates, ImpliedBoundsContext::TyParam(param.def_id), - param.span, + param.implicit_bounds_span, ); trace!(?bounds); predicates.extend(bounds); @@ -1001,7 +1001,7 @@ impl<'tcx> ItemCtxt<'tcx> { &[], hir_generics.predicates, ImpliedBoundsContext::TyParam(param.def_id), - param.span, + param.implicit_bounds_span, ); self.lowerer().add_default_traits( &mut bounds, @@ -1009,7 +1009,7 @@ impl<'tcx> ItemCtxt<'tcx> { &[], hir_generics.predicates, ImpliedBoundsContext::TyParam(param.def_id), - param.span, + param.implicit_bounds_span, ); } hir::GenericParamKind::Lifetime { .. } diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index e7116b7492584..f5d373cc6854d 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -34,8 +34,8 @@ use rustc_middle::ty::print::{ use rustc_middle::ty::{self, GenericArgKind, IsSuggestable, Ty, TyCtxt, TypeVisitableExt}; use rustc_span::def_id::DefIdSet; use rustc_span::{ - DUMMY_SP, ErrorGuaranteed, ExpnKind, FileName, Ident, MacroKind, Span, Symbol, edit_distance, - kw, sym, + DUMMY_SP, DesugaringKind, ErrorGuaranteed, ExpnKind, FileName, Ident, MacroKind, Span, Symbol, + edit_distance, kw, sym, }; use rustc_trait_selection::error_reporting::traits::DefIdOrName; use rustc_trait_selection::infer::InferCtxtExt; @@ -1952,8 +1952,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => false, } }); - for param in generics.params { - if param.span == cause_span && sized_pred { + if sized_pred && let Some(DesugaringKind::DefaultBound { def_id: def }) = cause_span.desugaring_kind() { + if let Some(param) = generics.params.iter().find(|p| p.def_id.to_def_id() == def) { let (sp, sugg) = match param.colon_span { Some(sp) => (sp.shrink_to_hi(), " ?Sized +"), None => (param.span.shrink_to_hi(), ": ?Sized"), diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs index a2537939ff8ad..69d21f7a0df26 100644 --- a/compiler/rustc_span/src/hygiene.rs +++ b/compiler/rustc_span/src/hygiene.rs @@ -926,6 +926,7 @@ impl SyntaxContext { | DesugaringKind::WhileLoop | DesugaringKind::OpaqueTy | DesugaringKind::Async + | DesugaringKind::DefaultBound { .. } | DesugaringKind::Await, ) => false, ExpnKind::AstPass(_) @@ -1235,6 +1236,13 @@ pub enum DesugaringKind { source: bool, }, RangeExpr, + /// Implicit `Sized` or `MetaSized` bounds. The actual source location points to just the + /// param or item for which the implicit bound was generated. + DefaultBound { + /// The definition this implied bound was added to. + /// So far only supports params, but may be used for super trait bounds and assoc ty bounds in the future + def_id: DefId, + }, } impl DesugaringKind { @@ -1257,6 +1265,7 @@ impl DesugaringKind { "expression that expanded into a format string literal" } DesugaringKind::RangeExpr => "range expression", + DesugaringKind::DefaultBound { .. } => "implied bound", } } @@ -1277,6 +1286,7 @@ impl DesugaringKind { DesugaringKind::PatTyRange => value == "PatTyRange", DesugaringKind::FormatLiteral { .. } => value == "FormatLiteral", DesugaringKind::RangeExpr => value == "RangeExpr", + DesugaringKind::DefaultBound { .. } => value == "ImpliedBound", } } } diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index d7dfce166742b..b482fe512fad6 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -3599,12 +3599,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { tcx.visible_parent_map(()).get(&def_id).is_some() }; if tcx.is_lang_item(def_id, LangItem::Sized) { - // Check if this is an implicit bound, even in foreign crates. - if tcx - .generics_of(item_def_id) - .own_params - .iter() - .any(|param| tcx.def_span(param.def_id) == span) + if let Some(DesugaringKind::DefaultBound { .. }) = + span.desugaring_kind() { a = "an implicit `Sized`"; this = @@ -4218,12 +4214,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // implicit, mention it as such. if let Some(pred) = predicate.as_trait_clause() && self.tcx.is_lang_item(pred.def_id(), LangItem::Sized) - && self - .tcx - .generics_of(data.impl_or_alias_def_id) - .own_params - .iter() - .any(|param| self.tcx.def_span(param.def_id) == data.span) + && let Some(DesugaringKind::DefaultBound { .. }) = + data.span.desugaring_kind() { spans.push_span_label( data.span, @@ -5914,7 +5906,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let sized_trait = self.tcx.lang_items().sized_trait(); debug!(?generics.params); debug!(?generics.predicates); - let Some(param) = generics.params.iter().find(|param| param.span == span) else { + let Some(DesugaringKind::DefaultBound { def_id }) = span.desugaring_kind() else { + return; + }; + let Some(param) = generics.params.iter().find(|param| param.def_id.to_def_id() == def_id) + else { return; }; // Check that none of the explicit trait bounds is `Sized`. Assume that an explicit diff --git a/tests/ui/box/into-boxed-slice-fail.stderr b/tests/ui/box/into-boxed-slice-fail.stderr index f102f666dc276..2d57c4b75e751 100644 --- a/tests/ui/box/into-boxed-slice-fail.stderr +++ b/tests/ui/box/into-boxed-slice-fail.stderr @@ -7,7 +7,7 @@ LL | let _ = Box::into_boxed_slice(boxed_slice); | required by a bound introduced by this call | = help: the trait `Sized` is not implemented for `[u8]` -note: required by a bound in `Box::::into_boxed_slice` +note: required by an implicit `Sized` bound in `Box::::into_boxed_slice` --> $SRC_DIR/alloc/src/boxed.rs:LL:COL error[E0277]: the size for values of type `[u8]` cannot be known at compilation time @@ -28,7 +28,7 @@ LL | let _ = Box::into_boxed_slice(boxed_trait); | required by a bound introduced by this call | = help: the trait `Sized` is not implemented for `dyn Debug` -note: required by a bound in `Box::::into_boxed_slice` +note: required by an implicit `Sized` bound in `Box::::into_boxed_slice` --> $SRC_DIR/alloc/src/boxed.rs:LL:COL error[E0277]: the size for values of type `dyn Debug` cannot be known at compilation time diff --git a/tests/ui/closures/unsized_value_move.stderr b/tests/ui/closures/unsized_value_move.stderr index a9a26a42d1675..4c7273c3a0060 100644 --- a/tests/ui/closures/unsized_value_move.stderr +++ b/tests/ui/closures/unsized_value_move.stderr @@ -7,7 +7,7 @@ LL | (|| Box::new(*(&[0][..])))(); | required by a bound introduced by this call | = help: the trait `Sized` is not implemented for `[{integer}]` -note: required by a bound in `Box::::new` +note: required by an implicit `Sized` bound in `Box::::new` --> $SRC_DIR/alloc/src/boxed.rs:LL:COL help: references are always `Sized`, even if they point to unsized data; consider not dereferencing the expression | diff --git a/tests/ui/coherence/deep-bad-copy-reason.rs b/tests/ui/coherence/deep-bad-copy-reason.rs index f1c2698bad5cc..dbc33c009e542 100644 --- a/tests/ui/coherence/deep-bad-copy-reason.rs +++ b/tests/ui/coherence/deep-bad-copy-reason.rs @@ -14,6 +14,7 @@ pub struct ListS { pub struct Interned<'a, T>(&'a T); //~^ NOTE: required by an implicit `Sized` //~| NOTE: required by the implicit `Sized` +//~| NOTE: in this expansion of desugaring of implied bound impl<'a, T> Clone for Interned<'a, T> { fn clone(&self) -> Self { diff --git a/tests/ui/coherence/deep-bad-copy-reason.stderr b/tests/ui/coherence/deep-bad-copy-reason.stderr index 534f26c39c2d4..131796a6c05b0 100644 --- a/tests/ui/coherence/deep-bad-copy-reason.stderr +++ b/tests/ui/coherence/deep-bad-copy-reason.stderr @@ -1,5 +1,5 @@ error[E0204]: the trait `Copy` cannot be implemented for this type - --> $DIR/deep-bad-copy-reason.rs:38:24 + --> $DIR/deep-bad-copy-reason.rs:39:24 | LL | pub struct List<'tcx, T>(Interned<'tcx, ListS>); | ------------------------ this field does not implement `Copy` @@ -8,13 +8,13 @@ LL | impl<'tcx, T> Copy for List<'tcx, T> {} | ^^^^^^^^^^^^^ | note: the `Copy` impl for `Interned<'tcx, ListS>` requires that `OpaqueListContents: Sized` - --> $DIR/deep-bad-copy-reason.rs:26:26 + --> $DIR/deep-bad-copy-reason.rs:27:26 | LL | pub struct List<'tcx, T>(Interned<'tcx, ListS>); | ^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: the size for values of type `OpaqueListContents` cannot be known at compilation time - --> $DIR/deep-bad-copy-reason.rs:26:26 + --> $DIR/deep-bad-copy-reason.rs:27:26 | LL | pub struct List<'tcx, T>(Interned<'tcx, ListS>); | ^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time diff --git a/tests/ui/dst/dst-rvalue.stderr b/tests/ui/dst/dst-rvalue.stderr index d8c529617f75f..b452311f70a56 100644 --- a/tests/ui/dst/dst-rvalue.stderr +++ b/tests/ui/dst/dst-rvalue.stderr @@ -7,7 +7,7 @@ LL | let _x: Box = Box::new(*"hello world"); | required by a bound introduced by this call | = help: the trait `Sized` is not implemented for `str` -note: required by a bound in `Box::::new` +note: required by an implicit `Sized` bound in `Box::::new` --> $SRC_DIR/alloc/src/boxed.rs:LL:COL help: references are always `Sized`, even if they point to unsized data; consider not dereferencing the expression | @@ -24,7 +24,7 @@ LL | let _x: Box<[isize]> = Box::new(*array); | required by a bound introduced by this call | = help: the trait `Sized` is not implemented for `[isize]` -note: required by a bound in `Box::::new` +note: required by an implicit `Sized` bound in `Box::::new` --> $SRC_DIR/alloc/src/boxed.rs:LL:COL help: references are always `Sized`, even if they point to unsized data; consider not dereferencing the expression | diff --git a/tests/ui/stats/input-stats.stderr b/tests/ui/stats/input-stats.stderr index b4d8277a46c00..43c8ede1d37ff 100644 --- a/tests/ui/stats/input-stats.stderr +++ b/tests/ui/stats/input-stats.stderr @@ -85,11 +85,11 @@ hir-stats - Ptr 48 (NN.N%) 1 hir-stats - Ref 48 (NN.N%) 1 hir-stats - Path 624 (NN.N%) 13 hir-stats Generics 560 (NN.N%) 10 56 +hir-stats GenericParam 440 (NN.N%) 5 88 hir-stats Pat 400 (NN.N%) 5 80 hir-stats - Struct 80 (NN.N%) 1 hir-stats - Wild 80 (NN.N%) 1 hir-stats - Binding 240 (NN.N%) 3 -hir-stats GenericParam 400 (NN.N%) 5 80 hir-stats Block 288 (NN.N%) 6 48 hir-stats GenericBound 256 (NN.N%) 4 64 hir-stats - Trait 256 (NN.N%) 4 @@ -119,5 +119,5 @@ hir-stats TraitItemId 8 (NN.N%) 2 4 hir-stats ImplItemId 8 (NN.N%) 2 4 hir-stats ForeignItemId 4 (NN.N%) 1 4 hir-stats ---------------------------------------------------------------- -hir-stats Total 8_576 172 +hir-stats Total 8_616 172 hir-stats ================================================================ diff --git a/tests/ui/trait-bounds/enum-unit-variant-trait-bound.stderr b/tests/ui/trait-bounds/enum-unit-variant-trait-bound.stderr index 9a3bcaa0c4aa4..7402129cddeac 100644 --- a/tests/ui/trait-bounds/enum-unit-variant-trait-bound.stderr +++ b/tests/ui/trait-bounds/enum-unit-variant-trait-bound.stderr @@ -5,7 +5,7 @@ LL | let _ = Option::<[u8]>::None; | ^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `[u8]` -note: required by a bound in `None` +note: required by an implicit `Sized` bound in `None` --> $SRC_DIR/core/src/option.rs:LL:COL error: aborting due to 1 previous error