@@ -158,13 +158,14 @@ enum Scope<'a> {
158158 s : ScopeRef < ' a > ,
159159 } ,
160160
161- /// Disallows capturing non-lifetime binders from parent scopes.
161+ /// Disallows capturing late-bound vars from parent scopes.
162162 ///
163163 /// This is necessary for something like `for<T> [(); { /* references T */ }]:`,
164164 /// since we don't do something more correct like replacing any captured
165165 /// late-bound vars with early-bound params in the const's own generics.
166- AnonConstBoundary {
166+ LateBoundary {
167167 s : ScopeRef < ' a > ,
168+ what : & ' static str ,
168169 } ,
169170
170171 Root {
@@ -216,7 +217,9 @@ impl<'a> fmt::Debug for TruncatedScopeDebug<'a> {
216217 . field ( "s" , & ".." )
217218 . finish ( ) ,
218219 Scope :: TraitRefBoundary { s : _ } => f. debug_struct ( "TraitRefBoundary" ) . finish ( ) ,
219- Scope :: AnonConstBoundary { s : _ } => f. debug_struct ( "AnonConstBoundary" ) . finish ( ) ,
220+ Scope :: LateBoundary { s : _, what } => {
221+ f. debug_struct ( "LateBoundary" ) . field ( "what" , what) . finish ( )
222+ }
220223 Scope :: Root { opt_parent_item } => {
221224 f. debug_struct ( "Root" ) . field ( "opt_parent_item" , & opt_parent_item) . finish ( )
222225 }
@@ -318,7 +321,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
318321 break ( vec ! [ ] , BinderScopeType :: Normal ) ;
319322 }
320323
321- Scope :: ObjectLifetimeDefault { s, .. } | Scope :: AnonConstBoundary { s } => {
324+ Scope :: ObjectLifetimeDefault { s, .. } | Scope :: LateBoundary { s, .. } => {
322325 scope = s;
323326 }
324327
@@ -697,9 +700,12 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
697700 } ) => {
698701 intravisit:: walk_ty ( self , ty) ;
699702
700- // Elided lifetimes are not allowed in non-return
701- // position impl Trait
702- let scope = Scope :: TraitRefBoundary { s : self . scope } ;
703+ // Elided lifetimes and late-bound lifetimes (from the parent)
704+ // are not allowed in non-return position impl Trait
705+ let scope = Scope :: LateBoundary {
706+ s : & Scope :: TraitRefBoundary { s : self . scope } ,
707+ what : "type alias impl trait" ,
708+ } ;
703709 self . with ( scope, |this| intravisit:: walk_item ( this, opaque_ty) ) ;
704710
705711 return ;
@@ -979,7 +985,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
979985 }
980986
981987 fn visit_anon_const ( & mut self , c : & ' tcx hir:: AnonConst ) {
982- self . with ( Scope :: AnonConstBoundary { s : self . scope } , |this| {
988+ self . with ( Scope :: LateBoundary { s : self . scope , what : "constant" } , |this| {
983989 intravisit:: walk_anon_const ( this, c) ;
984990 } ) ;
985991 }
@@ -1174,6 +1180,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
11741180 let mut late_depth = 0 ;
11751181 let mut scope = self . scope ;
11761182 let mut outermost_body = None ;
1183+ let mut crossed_late_boundary = None ;
11771184 let result = loop {
11781185 match * scope {
11791186 Scope :: Body { id, s } => {
@@ -1258,8 +1265,12 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
12581265
12591266 Scope :: ObjectLifetimeDefault { s, .. }
12601267 | Scope :: Supertrait { s, .. }
1261- | Scope :: TraitRefBoundary { s, .. }
1262- | Scope :: AnonConstBoundary { s } => {
1268+ | Scope :: TraitRefBoundary { s, .. } => {
1269+ scope = s;
1270+ }
1271+
1272+ Scope :: LateBoundary { s, what } => {
1273+ crossed_late_boundary = Some ( what) ;
12631274 scope = s;
12641275 }
12651276 }
@@ -1268,6 +1279,22 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
12681279 if let Some ( mut def) = result {
12691280 if let ResolvedArg :: EarlyBound ( ..) = def {
12701281 // Do not free early-bound regions, only late-bound ones.
1282+ } else if let ResolvedArg :: LateBound ( _, _, param_def_id) = def
1283+ && let Some ( what) = crossed_late_boundary
1284+ {
1285+ let use_span = lifetime_ref. ident . span ;
1286+ let def_span = self . tcx . def_span ( param_def_id) ;
1287+ let guar = match self . tcx . def_kind ( param_def_id) {
1288+ DefKind :: LifetimeParam => {
1289+ self . tcx . sess . emit_err ( errors:: CannotCaptureLateBound :: Lifetime {
1290+ use_span,
1291+ def_span,
1292+ what,
1293+ } )
1294+ }
1295+ _ => unreachable ! ( ) ,
1296+ } ;
1297+ def = ResolvedArg :: Error ( guar) ;
12711298 } else if let Some ( body_id) = outermost_body {
12721299 let fn_id = self . tcx . hir ( ) . body_owner ( body_id) ;
12731300 match self . tcx . hir ( ) . get ( fn_id) {
@@ -1322,7 +1349,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
13221349 | Scope :: ObjectLifetimeDefault { s, .. }
13231350 | Scope :: Supertrait { s, .. }
13241351 | Scope :: TraitRefBoundary { s, .. }
1325- | Scope :: AnonConstBoundary { s } => {
1352+ | Scope :: LateBoundary { s, .. } => {
13261353 scope = s;
13271354 }
13281355 }
@@ -1341,7 +1368,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
13411368 // search.
13421369 let mut late_depth = 0 ;
13431370 let mut scope = self . scope ;
1344- let mut crossed_anon_const = false ;
1371+ let mut crossed_late_boundary = None ;
13451372
13461373 let result = loop {
13471374 match * scope {
@@ -1376,28 +1403,32 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
13761403 scope = s;
13771404 }
13781405
1379- Scope :: AnonConstBoundary { s } => {
1380- crossed_anon_const = true ;
1406+ Scope :: LateBoundary { s, what } => {
1407+ crossed_late_boundary = Some ( what ) ;
13811408 scope = s;
13821409 }
13831410 }
13841411 } ;
13851412
13861413 if let Some ( def) = result {
1387- if let ResolvedArg :: LateBound ( ..) = def && crossed_anon_const {
1414+ if let ResolvedArg :: LateBound ( ..) = def
1415+ && let Some ( what) = crossed_late_boundary
1416+ {
13881417 let use_span = self . tcx . hir ( ) . span ( hir_id) ;
13891418 let def_span = self . tcx . def_span ( param_def_id) ;
13901419 let guar = match self . tcx . def_kind ( param_def_id) {
13911420 DefKind :: ConstParam => {
1392- self . tcx . sess . emit_err ( errors:: CannotCaptureLateBoundInAnonConst :: Const {
1421+ self . tcx . sess . emit_err ( errors:: CannotCaptureLateBound :: Const {
13931422 use_span,
13941423 def_span,
1424+ what,
13951425 } )
13961426 }
13971427 DefKind :: TyParam => {
1398- self . tcx . sess . emit_err ( errors:: CannotCaptureLateBoundInAnonConst :: Type {
1428+ self . tcx . sess . emit_err ( errors:: CannotCaptureLateBound :: Type {
13991429 use_span,
14001430 def_span,
1431+ what,
14011432 } )
14021433 }
14031434 _ => unreachable ! ( ) ,
@@ -1446,7 +1477,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
14461477 | Scope :: ObjectLifetimeDefault { s, .. }
14471478 | Scope :: Supertrait { s, .. }
14481479 | Scope :: TraitRefBoundary { s, .. }
1449- | Scope :: AnonConstBoundary { s } => {
1480+ | Scope :: LateBoundary { s, .. } => {
14501481 scope = s;
14511482 }
14521483 }
@@ -1526,7 +1557,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
15261557 | Scope :: ObjectLifetimeDefault { s, .. }
15271558 | Scope :: Supertrait { s, .. }
15281559 | Scope :: TraitRefBoundary { s, .. }
1529- | Scope :: AnonConstBoundary { s } => {
1560+ | Scope :: LateBoundary { s, .. } => {
15301561 scope = s;
15311562 }
15321563 }
@@ -1831,7 +1862,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
18311862
18321863 Scope :: Supertrait { s, .. }
18331864 | Scope :: TraitRefBoundary { s, .. }
1834- | Scope :: AnonConstBoundary { s } => {
1865+ | Scope :: LateBoundary { s, .. } => {
18351866 scope = s;
18361867 }
18371868 }
0 commit comments