@@ -24,6 +24,8 @@ use rustc_span::symbol::{sym, Ident};
2424use rustc_span:: Span ;
2525use std:: fmt;
2626
27+ use crate :: errors;
28+
2729trait RegionExt {
2830 fn early ( param : & GenericParam < ' _ > ) -> ( LocalDefId , ResolvedArg ) ;
2931
@@ -161,6 +163,15 @@ enum Scope<'a> {
161163 s : ScopeRef < ' a > ,
162164 } ,
163165
166+ /// Disallows capturing non-lifetime binders from parent scopes.
167+ ///
168+ /// This is necessary for something like `for<T> [(); { /* references T */ }]:`,
169+ /// since we don't do something more correct like replacing any captured
170+ /// late-bound vars with early-bound params in the const's own generics.
171+ AnonConstBoundary {
172+ s : ScopeRef < ' a > ,
173+ } ,
174+
164175 Root {
165176 opt_parent_item : Option < LocalDefId > ,
166177 } ,
@@ -211,6 +222,7 @@ impl<'a> fmt::Debug for TruncatedScopeDebug<'a> {
211222 . field ( "s" , & ".." )
212223 . finish ( ) ,
213224 Scope :: TraitRefBoundary { s : _ } => f. debug_struct ( "TraitRefBoundary" ) . finish ( ) ,
225+ Scope :: AnonConstBoundary { s : _ } => f. debug_struct ( "AnonConstBoundary" ) . finish ( ) ,
214226 Scope :: Root { opt_parent_item } => {
215227 f. debug_struct ( "Root" ) . field ( "opt_parent_item" , & opt_parent_item) . finish ( )
216228 }
@@ -312,7 +324,9 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
312324 break ( vec ! [ ] , BinderScopeType :: Normal ) ;
313325 }
314326
315- Scope :: Elision { s, .. } | Scope :: ObjectLifetimeDefault { s, .. } => {
327+ Scope :: Elision { s, .. }
328+ | Scope :: ObjectLifetimeDefault { s, .. }
329+ | Scope :: AnonConstBoundary { s } => {
316330 scope = s;
317331 }
318332
@@ -1029,6 +1043,12 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
10291043 fn visit_poly_trait_ref ( & mut self , trait_ref : & ' tcx hir:: PolyTraitRef < ' tcx > ) {
10301044 self . visit_poly_trait_ref_inner ( trait_ref, NonLifetimeBinderAllowed :: Allow ) ;
10311045 }
1046+
1047+ fn visit_anon_const ( & mut self , c : & ' tcx hir:: AnonConst ) {
1048+ self . with ( Scope :: AnonConstBoundary { s : self . scope } , |this| {
1049+ intravisit:: walk_anon_const ( this, c) ;
1050+ } ) ;
1051+ }
10321052}
10331053
10341054fn object_lifetime_default ( tcx : TyCtxt < ' _ > , param_def_id : DefId ) -> ObjectLifetimeDefault {
@@ -1267,7 +1287,8 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
12671287 Scope :: Elision { s, .. }
12681288 | Scope :: ObjectLifetimeDefault { s, .. }
12691289 | Scope :: Supertrait { s, .. }
1270- | Scope :: TraitRefBoundary { s, .. } => {
1290+ | Scope :: TraitRefBoundary { s, .. }
1291+ | Scope :: AnonConstBoundary { s } => {
12711292 scope = s;
12721293 }
12731294 }
@@ -1332,7 +1353,8 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
13321353 | Scope :: Elision { s, .. }
13331354 | Scope :: ObjectLifetimeDefault { s, .. }
13341355 | Scope :: Supertrait { s, .. }
1335- | Scope :: TraitRefBoundary { s, .. } => {
1356+ | Scope :: TraitRefBoundary { s, .. }
1357+ | Scope :: AnonConstBoundary { s } => {
13361358 scope = s;
13371359 }
13381360 }
@@ -1351,6 +1373,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
13511373 // search.
13521374 let mut late_depth = 0 ;
13531375 let mut scope = self . scope ;
1376+ let mut crossed_anon_const = false ;
13541377 let result = loop {
13551378 match * scope {
13561379 Scope :: Body { s, .. } => {
@@ -1384,10 +1407,36 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
13841407 | Scope :: TraitRefBoundary { s, .. } => {
13851408 scope = s;
13861409 }
1410+
1411+ Scope :: AnonConstBoundary { s } => {
1412+ crossed_anon_const = true ;
1413+ scope = s;
1414+ }
13871415 }
13881416 } ;
13891417
13901418 if let Some ( def) = result {
1419+ if let ResolvedArg :: LateBound ( ..) = def && crossed_anon_const {
1420+ let use_span = self . tcx . hir ( ) . span ( hir_id) ;
1421+ let def_span = self . tcx . def_span ( param_def_id) ;
1422+ match self . tcx . def_kind ( param_def_id) {
1423+ DefKind :: ConstParam => {
1424+ self . tcx . sess . emit_err ( errors:: CannotCaptureLateBoundInAnonConst :: Const {
1425+ use_span,
1426+ def_span,
1427+ } ) ;
1428+ }
1429+ DefKind :: TyParam => {
1430+ self . tcx . sess . emit_err ( errors:: CannotCaptureLateBoundInAnonConst :: Type {
1431+ use_span,
1432+ def_span,
1433+ } ) ;
1434+ }
1435+ _ => unreachable ! ( ) ,
1436+ }
1437+ return ;
1438+ }
1439+
13911440 self . map . defs . insert ( hir_id, def) ;
13921441 return ;
13931442 }
@@ -1465,7 +1514,8 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
14651514 | Scope :: Elision { s, .. }
14661515 | Scope :: ObjectLifetimeDefault { s, .. }
14671516 | Scope :: Supertrait { s, .. }
1468- | Scope :: TraitRefBoundary { s, .. } => {
1517+ | Scope :: TraitRefBoundary { s, .. }
1518+ | Scope :: AnonConstBoundary { s } => {
14691519 scope = s;
14701520 }
14711521 }
@@ -1701,7 +1751,9 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
17011751
17021752 Scope :: ObjectLifetimeDefault { lifetime : Some ( l) , .. } => break l,
17031753
1704- Scope :: Supertrait { s, .. } | Scope :: TraitRefBoundary { s, .. } => {
1754+ Scope :: Supertrait { s, .. }
1755+ | Scope :: TraitRefBoundary { s, .. }
1756+ | Scope :: AnonConstBoundary { s } => {
17051757 scope = s;
17061758 }
17071759 }
0 commit comments