@@ -207,6 +207,13 @@ enum Scope<'a> {
207207 /// In some cases not allowing late bounds allows us to avoid ICEs.
208208 /// This is almost ways set to true.
209209 allow_late_bound : bool ,
210+
211+ /// If this binder comes from a where clause, specify how it was created.
212+ /// This is used to diagnose inaccessible lifetimes in APIT:
213+ /// ```ignore (illustrative)
214+ /// fn foo(x: impl for<'a> Trait<'a, Assoc = impl Copy + 'a>) {}
215+ /// ```
216+ where_bound_origin : Option < hir:: PredicateOrigin > ,
210217 } ,
211218
212219 /// Lifetimes introduced by a fn are scoped to the call-site for that fn,
@@ -277,17 +284,19 @@ impl<'a> fmt::Debug for TruncatedScopeDebug<'a> {
277284 opaque_type_parent,
278285 scope_type,
279286 hir_id,
280- s : _,
281287 allow_late_bound,
288+ where_bound_origin,
289+ s : _,
282290 } => f
283291 . debug_struct ( "Binder" )
284292 . field ( "lifetimes" , lifetimes)
285293 . field ( "next_early_index" , next_early_index)
286294 . field ( "opaque_type_parent" , opaque_type_parent)
287295 . field ( "scope_type" , scope_type)
288296 . field ( "hir_id" , hir_id)
289- . field ( "s" , & ".." )
290297 . field ( "allow_late_bound" , allow_late_bound)
298+ . field ( "where_bound_origin" , where_bound_origin)
299+ . field ( "s" , & ".." )
291300 . finish ( ) ,
292301 Scope :: Body { id, s : _ } => {
293302 f. debug_struct ( "Body" ) . field ( "id" , id) . field ( "s" , & ".." ) . finish ( )
@@ -638,6 +647,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
638647 opaque_type_parent : false ,
639648 scope_type : BinderScopeType :: Normal ,
640649 allow_late_bound : true ,
650+ where_bound_origin : None ,
641651 } ;
642652 self . with ( scope, move |this| intravisit:: walk_fn ( this, fk, fd, b, s, hir_id) ) ;
643653 }
@@ -753,6 +763,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
753763 scope_type : BinderScopeType :: Normal ,
754764 s : ROOT_SCOPE ,
755765 allow_late_bound : false ,
766+ where_bound_origin : None ,
756767 } ;
757768 self . with ( scope, |this| {
758769 let scope = Scope :: TraitRefBoundary { s : this. scope } ;
@@ -818,6 +829,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
818829 opaque_type_parent : false ,
819830 scope_type : BinderScopeType :: Normal ,
820831 allow_late_bound : true ,
832+ where_bound_origin : None ,
821833 } ;
822834 self . with ( scope, |this| {
823835 // a bare fn has no bounds, so everything
@@ -1006,6 +1018,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
10061018 opaque_type_parent : false ,
10071019 scope_type : BinderScopeType :: Normal ,
10081020 allow_late_bound : false ,
1021+ where_bound_origin : None ,
10091022 } ;
10101023 this. with ( scope, |this| {
10111024 this. visit_generics ( generics) ;
@@ -1026,6 +1039,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
10261039 opaque_type_parent : false ,
10271040 scope_type : BinderScopeType :: Normal ,
10281041 allow_late_bound : false ,
1042+ where_bound_origin : None ,
10291043 } ;
10301044 self . with ( scope, |this| {
10311045 let scope = Scope :: TraitRefBoundary { s : this. scope } ;
@@ -1084,6 +1098,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
10841098 opaque_type_parent : true ,
10851099 scope_type : BinderScopeType :: Normal ,
10861100 allow_late_bound : false ,
1101+ where_bound_origin : None ,
10871102 } ;
10881103 self . with ( scope, |this| {
10891104 let scope = Scope :: TraitRefBoundary { s : this. scope } ;
@@ -1151,6 +1166,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
11511166 opaque_type_parent : true ,
11521167 scope_type : BinderScopeType :: Normal ,
11531168 allow_late_bound : true ,
1169+ where_bound_origin : None ,
11541170 } ;
11551171 self . with ( scope, |this| {
11561172 let scope = Scope :: TraitRefBoundary { s : this. scope } ;
@@ -1266,6 +1282,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
12661282 ref bounded_ty,
12671283 bounds,
12681284 ref bound_generic_params,
1285+ origin,
12691286 ..
12701287 } ) => {
12711288 let ( lifetimes, binders) : ( FxIndexMap < LocalDefId , Region > , Vec < _ > ) =
@@ -1296,6 +1313,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
12961313 opaque_type_parent : false ,
12971314 scope_type : BinderScopeType :: Normal ,
12981315 allow_late_bound : true ,
1316+ where_bound_origin : Some ( origin) ,
12991317 } ;
13001318 this. with ( scope, |this| {
13011319 this. visit_ty ( & bounded_ty) ;
@@ -1368,6 +1386,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
13681386 opaque_type_parent : false ,
13691387 scope_type,
13701388 allow_late_bound : true ,
1389+ where_bound_origin : None ,
13711390 } ;
13721391 self . with ( scope, |this| {
13731392 intravisit:: walk_param_bound ( this, bound) ;
@@ -1420,6 +1439,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
14201439 opaque_type_parent : false ,
14211440 scope_type,
14221441 allow_late_bound : true ,
1442+ where_bound_origin : None ,
14231443 } ;
14241444 self . with ( scope, |this| {
14251445 walk_list ! ( this, visit_generic_param, trait_ref. bound_generic_params) ;
@@ -1680,6 +1700,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
16801700 opaque_type_parent : true ,
16811701 scope_type : BinderScopeType :: Normal ,
16821702 allow_late_bound : true ,
1703+ where_bound_origin : None ,
16831704 } ;
16841705 self . with ( scope, walk) ;
16851706 }
@@ -1783,12 +1804,48 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
17831804 }
17841805
17851806 self . insert_lifetime ( lifetime_ref, def) ;
1786- } else {
1787- self . tcx . sess . delay_span_bug (
1788- lifetime_ref. span ,
1789- & format ! ( "Could not resolve {:?} in scope {:#?}" , lifetime_ref, self . scope, ) ,
1790- ) ;
1807+ return ;
17911808 }
1809+
1810+ // We may fail to resolve higher-ranked lifetimes that are mentionned by APIT.
1811+ // AST-based resolution does not care for impl-trait desugaring, which are the
1812+ // responibility of lowering. This may create a mismatch between the resolution
1813+ // AST found (`region_def_id`) which points to HRTB, and what HIR allows.
1814+ // ```
1815+ // fn foo(x: impl for<'a> Trait<'a, Assoc = impl Copy + 'a>) {}
1816+ // ```
1817+ //
1818+ // In such case, walk back the binders to diagnose it properly.
1819+ let mut scope = self . scope ;
1820+ loop {
1821+ match * scope {
1822+ Scope :: Binder {
1823+ where_bound_origin : Some ( hir:: PredicateOrigin :: ImplTrait ) , ..
1824+ } => {
1825+ let mut err = self . tcx . sess . struct_span_err (
1826+ lifetime_ref. span ,
1827+ "`impl Trait` can only mention lifetimes bound at the fn or impl level" ,
1828+ ) ;
1829+ err. span_note ( self . tcx . def_span ( region_def_id) , "lifetime declared here" ) ;
1830+ err. emit ( ) ;
1831+ return ;
1832+ }
1833+ Scope :: Root => break ,
1834+ Scope :: Binder { s, .. }
1835+ | Scope :: Body { s, .. }
1836+ | Scope :: Elision { s, .. }
1837+ | Scope :: ObjectLifetimeDefault { s, .. }
1838+ | Scope :: Supertrait { s, .. }
1839+ | Scope :: TraitRefBoundary { s, .. } => {
1840+ scope = s;
1841+ }
1842+ }
1843+ }
1844+
1845+ self . tcx . sess . delay_span_bug (
1846+ lifetime_ref. span ,
1847+ & format ! ( "Could not resolve {:?} in scope {:#?}" , lifetime_ref, self . scope, ) ,
1848+ ) ;
17921849 }
17931850
17941851 fn visit_segment_args (
0 commit comments