@@ -13,6 +13,7 @@ use rustc_middle::ty::{
13
13
use rustc_span:: { ErrorGuaranteed , Span } ;
14
14
use rustc_trait_selection:: error_reporting:: traits:: report_dyn_incompatibility;
15
15
use rustc_trait_selection:: traits:: { self , hir_ty_lowering_dyn_compatibility_violations} ;
16
+ use rustc_type_ir:: elaborate:: ClauseWithSupertraitSpan ;
16
17
use smallvec:: { SmallVec , smallvec} ;
17
18
use tracing:: { debug, instrument} ;
18
19
@@ -124,16 +125,19 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
124
125
. into_iter ( )
125
126
. filter ( |( trait_ref, _) | !tcx. trait_is_auto ( trait_ref. def_id ( ) ) ) ;
126
127
127
- for ( base_trait_ref, span ) in regular_traits_refs_spans {
128
+ for ( base_trait_ref, original_span ) in regular_traits_refs_spans {
128
129
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
+ {
130
134
debug ! ( "observing object predicate `{pred:?}`" ) ;
131
135
132
136
let bound_predicate = pred. kind ( ) ;
133
137
match bound_predicate. skip_binder ( ) {
134
138
ty:: PredicateKind :: Clause ( ty:: ClauseKind :: Trait ( pred) ) => {
135
139
let pred = bound_predicate. rebind ( pred) ;
136
- associated_types. entry ( span ) . or_default ( ) . extend (
140
+ associated_types. entry ( original_span ) . or_default ( ) . extend (
137
141
tcx. associated_items ( pred. def_id ( ) )
138
142
. in_definition_order ( )
139
143
. filter ( |item| item. kind == ty:: AssocKind :: Type )
@@ -172,8 +176,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
172
176
// the discussion in #56288 for alternatives.
173
177
if !references_self {
174
178
// Include projections defined on supertraits.
175
- projection_bounds. push ( ( pred, span ) ) ;
179
+ projection_bounds. push ( ( pred, original_span ) ) ;
176
180
}
181
+
182
+ self . check_elaborated_projection_mentions_input_lifetimes (
183
+ pred,
184
+ original_span,
185
+ supertrait_span,
186
+ ) ;
177
187
}
178
188
_ => ( ) ,
179
189
}
@@ -360,6 +370,56 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
360
370
361
371
Ty :: new_dynamic ( tcx, existential_predicates, region_bound, representation)
362
372
}
373
+
374
+ /// Check that elaborating the principal of a trait ref doesn't lead to projections
375
+ /// that are unconstrained. This can happen because an otherwise unconstrained
376
+ /// *type variable* can be substituted with a type that has late-bound regions. See
377
+ /// `elaborated-predicates-unconstrained-late-bound.rs` for a test.
378
+ fn check_elaborated_projection_mentions_input_lifetimes (
379
+ & self ,
380
+ pred : ty:: PolyProjectionPredicate < ' tcx > ,
381
+ span : Span ,
382
+ supertrait_span : Span ,
383
+ ) {
384
+ let tcx = self . tcx ( ) ;
385
+
386
+ // Find any late-bound regions declared in `ty` that are not
387
+ // declared in the trait-ref or assoc_item. These are not well-formed.
388
+ //
389
+ // Example:
390
+ //
391
+ // for<'a> <T as Iterator>::Item = &'a str // <-- 'a is bad
392
+ // for<'a> <T as FnMut<(&'a u32,)>>::Output = &'a str // <-- 'a is ok
393
+ let late_bound_in_projection_term =
394
+ tcx. collect_constrained_late_bound_regions ( pred. map_bound ( |pred| pred. projection_term ) ) ;
395
+ let late_bound_in_term =
396
+ tcx. collect_referenced_late_bound_regions ( pred. map_bound ( |pred| pred. term ) ) ;
397
+ debug ! ( ?late_bound_in_projection_term) ;
398
+ debug ! ( ?late_bound_in_term) ;
399
+
400
+ // FIXME: point at the type params that don't have appropriate lifetimes:
401
+ // struct S1<F: for<'a> Fn(&i32, &i32) -> &'a i32>(F);
402
+ // ---- ---- ^^^^^^^
403
+ // NOTE(associated_const_equality): This error should be impossible to trigger
404
+ // with associated const equality constraints.
405
+ self . validate_late_bound_regions (
406
+ late_bound_in_projection_term,
407
+ late_bound_in_term,
408
+ |br_name| {
409
+ let item_name = tcx. item_name ( pred. projection_def_id ( ) ) ;
410
+ struct_span_code_err ! (
411
+ self . dcx( ) ,
412
+ span,
413
+ E0582 ,
414
+ "binding for associated type `{}` references {}, \
415
+ which does not appear in the trait input types",
416
+ item_name,
417
+ br_name
418
+ )
419
+ . with_span_label ( supertrait_span, "due to this supertrait" )
420
+ } ,
421
+ ) ;
422
+ }
363
423
}
364
424
365
425
fn replace_dummy_self_with_error < ' tcx , T : TypeFoldable < TyCtxt < ' tcx > > > (
0 commit comments