@@ -13,6 +13,7 @@ use rustc_middle::ty::{
1313use rustc_span:: { ErrorGuaranteed , Span } ;
1414use rustc_trait_selection:: error_reporting:: traits:: report_object_safety_error;
1515use rustc_trait_selection:: traits:: { self , hir_ty_lowering_object_safety_violations} ;
16+ use rustc_type_ir:: elaborate:: ClauseWithSupertraitSpan ;
1617use smallvec:: { smallvec, SmallVec } ;
1718use tracing:: { debug, instrument} ;
1819
@@ -124,16 +125,19 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
124125 . into_iter ( )
125126 . filter ( |( trait_ref, _) | !tcx. trait_is_auto ( trait_ref. def_id ( ) ) ) ;
126127
127- for ( base_trait_ref, span ) in regular_traits_refs_spans {
128+ for ( base_trait_ref, original_span ) in regular_traits_refs_spans {
128129 let base_pred: ty:: Predicate < ' tcx > = base_trait_ref. upcast ( tcx) ;
129- for pred in traits:: elaborate ( tcx, [ base_pred] ) . filter_only_self ( ) {
130+ for ClauseWithSupertraitSpan { pred, original_span, supertrait_span } in
131+ traits:: elaborate ( tcx, [ ClauseWithSupertraitSpan :: new ( base_pred, original_span) ] )
132+ . filter_only_self ( )
133+ {
130134 debug ! ( "observing object predicate `{pred:?}`" ) ;
131135
132136 let bound_predicate = pred. kind ( ) ;
133137 match bound_predicate. skip_binder ( ) {
134138 ty:: PredicateKind :: Clause ( ty:: ClauseKind :: Trait ( pred) ) => {
135139 let pred = bound_predicate. rebind ( pred) ;
136- associated_types. entry ( span ) . or_default ( ) . extend (
140+ associated_types. entry ( original_span ) . or_default ( ) . extend (
137141 tcx. associated_items ( pred. def_id ( ) )
138142 . in_definition_order ( )
139143 . filter ( |item| item. kind == ty:: AssocKind :: Type )
@@ -172,8 +176,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
172176 // the discussion in #56288 for alternatives.
173177 if !references_self {
174178 // Include projections defined on supertraits.
175- projection_bounds. push ( ( pred, span ) ) ;
179+ projection_bounds. push ( ( pred, original_span ) ) ;
176180 }
181+
182+ self . check_elaborated_projection_mentions_input_lifetimes (
183+ pred,
184+ original_span,
185+ supertrait_span,
186+ ) ;
177187 }
178188 _ => ( ) ,
179189 }
@@ -358,6 +368,56 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
358368
359369 Ty :: new_dynamic ( tcx, existential_predicates, region_bound, representation)
360370 }
371+
372+ /// Check that elaborating the principal of a trait ref doesn't lead to projections
373+ /// that are unconstrained. This can happen because an otherwise unconstrained
374+ /// *type variable* can be substituted with a type that has late-bound regions. See
375+ /// `elaborated-predicates-unconstrained-late-bound.rs` for a test.
376+ fn check_elaborated_projection_mentions_input_lifetimes (
377+ & self ,
378+ pred : ty:: PolyProjectionPredicate < ' tcx > ,
379+ span : Span ,
380+ supertrait_span : Span ,
381+ ) {
382+ let tcx = self . tcx ( ) ;
383+
384+ // Find any late-bound regions declared in `ty` that are not
385+ // declared in the trait-ref or assoc_item. These are not well-formed.
386+ //
387+ // Example:
388+ //
389+ // for<'a> <T as Iterator>::Item = &'a str // <-- 'a is bad
390+ // for<'a> <T as FnMut<(&'a u32,)>>::Output = &'a str // <-- 'a is ok
391+ let late_bound_in_projection_term =
392+ tcx. collect_constrained_late_bound_regions ( pred. map_bound ( |pred| pred. projection_term ) ) ;
393+ let late_bound_in_term =
394+ tcx. collect_referenced_late_bound_regions ( pred. map_bound ( |pred| pred. term ) ) ;
395+ debug ! ( ?late_bound_in_projection_term) ;
396+ debug ! ( ?late_bound_in_term) ;
397+
398+ // FIXME: point at the type params that don't have appropriate lifetimes:
399+ // struct S1<F: for<'a> Fn(&i32, &i32) -> &'a i32>(F);
400+ // ---- ---- ^^^^^^^
401+ // NOTE(associated_const_equality): This error should be impossible to trigger
402+ // with associated const equality constraints.
403+ self . validate_late_bound_regions (
404+ late_bound_in_projection_term,
405+ late_bound_in_term,
406+ |br_name| {
407+ let item_name = tcx. item_name ( pred. projection_def_id ( ) ) ;
408+ struct_span_code_err ! (
409+ self . dcx( ) ,
410+ span,
411+ E0582 ,
412+ "binding for associated type `{}` references {}, \
413+ which does not appear in the trait input types",
414+ item_name,
415+ br_name
416+ )
417+ . with_span_label ( supertrait_span, "due to this supertrait" )
418+ } ,
419+ ) ;
420+ }
361421}
362422
363423fn replace_dummy_self_with_error < ' tcx , T : TypeFoldable < TyCtxt < ' tcx > > > (
0 commit comments