@@ -230,6 +230,13 @@ enum Scope<'a> {
230230 /// In some cases not allowing late bounds allows us to avoid ICEs.
231231 /// This is almost ways set to true.
232232 allow_late_bound : bool ,
233+
234+ /// If this binder comes from a where clause, specify how it was created.
235+ /// This is used to diagnose inaccessible lifetimes in APIT:
236+ /// ```ignore (illustrative)
237+ /// fn foo(x: impl for<'a> Trait<'a, Assoc = impl Copy + 'a>) {}
238+ /// ```
239+ where_bound_origin : Option < hir:: PredicateOrigin > ,
233240 } ,
234241
235242 /// Lifetimes introduced by a fn are scoped to the call-site for that fn,
@@ -301,8 +308,9 @@ impl<'a> fmt::Debug for TruncatedScopeDebug<'a> {
301308 opaque_type_parent,
302309 scope_type,
303310 hir_id,
304- s : _,
305311 allow_late_bound,
312+ where_bound_origin,
313+ s : _,
306314 } => f
307315 . debug_struct ( "Binder" )
308316 . field ( "lifetimes" , lifetimes)
@@ -311,8 +319,9 @@ impl<'a> fmt::Debug for TruncatedScopeDebug<'a> {
311319 . field ( "opaque_type_parent" , opaque_type_parent)
312320 . field ( "scope_type" , scope_type)
313321 . field ( "hir_id" , hir_id)
314- . field ( "s" , & ".." )
315322 . field ( "allow_late_bound" , allow_late_bound)
323+ . field ( "where_bound_origin" , where_bound_origin)
324+ . field ( "s" , & ".." )
316325 . finish ( ) ,
317326 Scope :: Body { id, s : _ } => {
318327 f. debug_struct ( "Body" ) . field ( "id" , id) . field ( "s" , & ".." ) . finish ( )
@@ -701,6 +710,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
701710 opaque_type_parent : false ,
702711 scope_type : BinderScopeType :: Normal ,
703712 allow_late_bound : true ,
713+ where_bound_origin : None ,
704714 } ;
705715 self . with ( scope, move |_old_scope, this| {
706716 intravisit:: walk_fn ( this, fk, fd, b, s, hir_id)
@@ -829,6 +839,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
829839 scope_type : BinderScopeType :: Normal ,
830840 s : ROOT_SCOPE ,
831841 allow_late_bound : false ,
842+ where_bound_origin : None ,
832843 } ;
833844 self . with ( scope, |old_scope, this| {
834845 this. check_lifetime_params ( old_scope, & generics. params ) ;
@@ -896,6 +907,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
896907 opaque_type_parent : false ,
897908 scope_type : BinderScopeType :: Normal ,
898909 allow_late_bound : true ,
910+ where_bound_origin : None ,
899911 } ;
900912 self . with ( scope, |old_scope, this| {
901913 // a bare fn has no bounds, so everything
@@ -1091,6 +1103,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
10911103 opaque_type_parent : false ,
10921104 scope_type : BinderScopeType :: Normal ,
10931105 allow_late_bound : false ,
1106+ where_bound_origin : None ,
10941107 } ;
10951108 this. with ( scope, |_old_scope, this| {
10961109 this. visit_generics ( generics) ;
@@ -1112,6 +1125,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
11121125 opaque_type_parent : false ,
11131126 scope_type : BinderScopeType :: Normal ,
11141127 allow_late_bound : false ,
1128+ where_bound_origin : None ,
11151129 } ;
11161130 self . with ( scope, |_old_scope, this| {
11171131 let scope = Scope :: TraitRefBoundary { s : this. scope } ;
@@ -1172,6 +1186,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
11721186 opaque_type_parent : true ,
11731187 scope_type : BinderScopeType :: Normal ,
11741188 allow_late_bound : false ,
1189+ where_bound_origin : None ,
11751190 } ;
11761191 self . with ( scope, |old_scope, this| {
11771192 this. check_lifetime_params ( old_scope, & generics. params ) ;
@@ -1242,6 +1257,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
12421257 opaque_type_parent : true ,
12431258 scope_type : BinderScopeType :: Normal ,
12441259 allow_late_bound : true ,
1260+ where_bound_origin : None ,
12451261 } ;
12461262 self . with ( scope, |old_scope, this| {
12471263 this. check_lifetime_params ( old_scope, & generics. params ) ;
@@ -1356,6 +1372,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
13561372 ref bounded_ty,
13571373 bounds,
13581374 ref bound_generic_params,
1375+ origin,
13591376 ..
13601377 } ) => {
13611378 let ( lifetimes, binders) : ( FxIndexMap < hir:: ParamName , Region > , Vec < _ > ) =
@@ -1387,6 +1404,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
13871404 opaque_type_parent : false ,
13881405 scope_type : BinderScopeType :: Normal ,
13891406 allow_late_bound : true ,
1407+ where_bound_origin : Some ( origin) ,
13901408 } ;
13911409 this. with ( scope, |old_scope, this| {
13921410 this. check_lifetime_params ( old_scope, & bound_generic_params) ;
@@ -1461,6 +1479,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
14611479 opaque_type_parent : false ,
14621480 scope_type,
14631481 allow_late_bound : true ,
1482+ where_bound_origin : None ,
14641483 } ;
14651484 self . with ( scope, |_, this| {
14661485 intravisit:: walk_param_bound ( this, bound) ;
@@ -1514,6 +1533,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
15141533 opaque_type_parent : false ,
15151534 scope_type,
15161535 allow_late_bound : true ,
1536+ where_bound_origin : None ,
15171537 } ;
15181538 self . with ( scope, |old_scope, this| {
15191539 this. check_lifetime_params ( old_scope, & trait_ref. bound_generic_params ) ;
@@ -2207,6 +2227,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
22072227 track_lifetime_uses : false ,
22082228 scope_type : BinderScopeType :: Normal ,
22092229 allow_late_bound : true ,
2230+ where_bound_origin : None ,
22102231 } ;
22112232 self . with ( scope, move |old_scope, this| {
22122233 this. check_lifetime_params ( old_scope, & generics. params ) ;
@@ -2321,12 +2342,48 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
23212342 }
23222343
23232344 self . insert_lifetime ( lifetime_ref, def) ;
2324- } else {
2325- self . tcx . sess . delay_span_bug (
2326- lifetime_ref. span ,
2327- & format ! ( "Could not resolve {:?} in scope {:#?}" , lifetime_ref, self . scope, ) ,
2328- ) ;
2345+ return ;
23292346 }
2347+
2348+ // We may fail to resolve higher-ranked lifetimes that are mentionned by APIT.
2349+ // AST-based resolution does not care for impl-trait desugaring, which are the
2350+ // responibility of lowering. This may create a mismatch between the resolution
2351+ // AST found (`region_def_id`) which points to HRTB, and what HIR allows.
2352+ // ```
2353+ // fn foo(x: impl for<'a> Trait<'a, Assoc = impl Copy + 'a>) {}
2354+ // ```
2355+ //
2356+ // In such case, walk back the binders to diagnose it properly.
2357+ let mut scope = self . scope ;
2358+ loop {
2359+ match * scope {
2360+ Scope :: Binder {
2361+ where_bound_origin : Some ( hir:: PredicateOrigin :: ImplTrait ) , ..
2362+ } => {
2363+ let mut err = self . tcx . sess . struct_span_err (
2364+ lifetime_ref. span ,
2365+ "`impl Trait` can only mention lifetimes bound at the fn or impl level" ,
2366+ ) ;
2367+ err. span_note ( self . tcx . def_span ( region_def_id) , "lifetime declared here" ) ;
2368+ err. emit ( ) ;
2369+ return ;
2370+ }
2371+ Scope :: Root => break ,
2372+ Scope :: Binder { s, .. }
2373+ | Scope :: Body { s, .. }
2374+ | Scope :: Elision { s, .. }
2375+ | Scope :: ObjectLifetimeDefault { s, .. }
2376+ | Scope :: Supertrait { s, .. }
2377+ | Scope :: TraitRefBoundary { s, .. } => {
2378+ scope = s;
2379+ }
2380+ }
2381+ }
2382+
2383+ self . tcx . sess . delay_span_bug (
2384+ lifetime_ref. span ,
2385+ & format ! ( "Could not resolve {:?} in scope {:#?}" , lifetime_ref, self . scope, ) ,
2386+ ) ;
23302387 }
23312388
23322389 fn visit_segment_args (
0 commit comments