@@ -24,6 +24,8 @@ use rustc_span::symbol::{sym, Ident};
24
24
use rustc_span:: Span ;
25
25
use std:: fmt;
26
26
27
+ use crate :: errors;
28
+
27
29
trait RegionExt {
28
30
fn early ( param : & GenericParam < ' _ > ) -> ( LocalDefId , ResolvedArg ) ;
29
31
@@ -161,6 +163,15 @@ enum Scope<'a> {
161
163
s : ScopeRef < ' a > ,
162
164
} ,
163
165
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
+
164
175
Root {
165
176
opt_parent_item : Option < LocalDefId > ,
166
177
} ,
@@ -211,6 +222,7 @@ impl<'a> fmt::Debug for TruncatedScopeDebug<'a> {
211
222
. field ( "s" , & ".." )
212
223
. finish ( ) ,
213
224
Scope :: TraitRefBoundary { s : _ } => f. debug_struct ( "TraitRefBoundary" ) . finish ( ) ,
225
+ Scope :: AnonConstBoundary { s : _ } => f. debug_struct ( "AnonConstBoundary" ) . finish ( ) ,
214
226
Scope :: Root { opt_parent_item } => {
215
227
f. debug_struct ( "Root" ) . field ( "opt_parent_item" , & opt_parent_item) . finish ( )
216
228
}
@@ -312,7 +324,9 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
312
324
break ( vec ! [ ] , BinderScopeType :: Normal ) ;
313
325
}
314
326
315
- Scope :: Elision { s, .. } | Scope :: ObjectLifetimeDefault { s, .. } => {
327
+ Scope :: Elision { s, .. }
328
+ | Scope :: ObjectLifetimeDefault { s, .. }
329
+ | Scope :: AnonConstBoundary { s } => {
316
330
scope = s;
317
331
}
318
332
@@ -1029,6 +1043,12 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
1029
1043
fn visit_poly_trait_ref ( & mut self , trait_ref : & ' tcx hir:: PolyTraitRef < ' tcx > ) {
1030
1044
self . visit_poly_trait_ref_inner ( trait_ref, NonLifetimeBinderAllowed :: Allow ) ;
1031
1045
}
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
+ }
1032
1052
}
1033
1053
1034
1054
fn object_lifetime_default ( tcx : TyCtxt < ' _ > , param_def_id : DefId ) -> ObjectLifetimeDefault {
@@ -1275,7 +1295,8 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
1275
1295
Scope :: Elision { s, .. }
1276
1296
| Scope :: ObjectLifetimeDefault { s, .. }
1277
1297
| Scope :: Supertrait { s, .. }
1278
- | Scope :: TraitRefBoundary { s, .. } => {
1298
+ | Scope :: TraitRefBoundary { s, .. }
1299
+ | Scope :: AnonConstBoundary { s } => {
1279
1300
scope = s;
1280
1301
}
1281
1302
}
@@ -1340,7 +1361,8 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
1340
1361
| Scope :: Elision { s, .. }
1341
1362
| Scope :: ObjectLifetimeDefault { s, .. }
1342
1363
| Scope :: Supertrait { s, .. }
1343
- | Scope :: TraitRefBoundary { s, .. } => {
1364
+ | Scope :: TraitRefBoundary { s, .. }
1365
+ | Scope :: AnonConstBoundary { s } => {
1344
1366
scope = s;
1345
1367
}
1346
1368
}
@@ -1359,6 +1381,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
1359
1381
// search.
1360
1382
let mut late_depth = 0 ;
1361
1383
let mut scope = self . scope ;
1384
+ let mut crossed_anon_const = false ;
1362
1385
let result = loop {
1363
1386
match * scope {
1364
1387
Scope :: Body { s, .. } => {
@@ -1392,10 +1415,36 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
1392
1415
| Scope :: TraitRefBoundary { s, .. } => {
1393
1416
scope = s;
1394
1417
}
1418
+
1419
+ Scope :: AnonConstBoundary { s } => {
1420
+ crossed_anon_const = true ;
1421
+ scope = s;
1422
+ }
1395
1423
}
1396
1424
} ;
1397
1425
1398
1426
if let Some ( def) = result {
1427
+ if let ResolvedArg :: LateBound ( ..) = def && crossed_anon_const {
1428
+ let use_span = self . tcx . hir ( ) . span ( hir_id) ;
1429
+ let def_span = self . tcx . def_span ( param_def_id) ;
1430
+ match self . tcx . def_kind ( param_def_id) {
1431
+ DefKind :: ConstParam => {
1432
+ self . tcx . sess . emit_err ( errors:: CannotCaptureLateBoundInAnonConst :: Const {
1433
+ use_span,
1434
+ def_span,
1435
+ } ) ;
1436
+ }
1437
+ DefKind :: TyParam => {
1438
+ self . tcx . sess . emit_err ( errors:: CannotCaptureLateBoundInAnonConst :: Type {
1439
+ use_span,
1440
+ def_span,
1441
+ } ) ;
1442
+ }
1443
+ _ => unreachable ! ( ) ,
1444
+ }
1445
+ return ;
1446
+ }
1447
+
1399
1448
self . map . defs . insert ( hir_id, def) ;
1400
1449
return ;
1401
1450
}
@@ -1474,7 +1523,8 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
1474
1523
| Scope :: Elision { s, .. }
1475
1524
| Scope :: ObjectLifetimeDefault { s, .. }
1476
1525
| Scope :: Supertrait { s, .. }
1477
- | Scope :: TraitRefBoundary { s, .. } => {
1526
+ | Scope :: TraitRefBoundary { s, .. }
1527
+ | Scope :: AnonConstBoundary { s } => {
1478
1528
scope = s;
1479
1529
}
1480
1530
}
@@ -1710,7 +1760,9 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
1710
1760
1711
1761
Scope :: ObjectLifetimeDefault { lifetime : Some ( l) , .. } => break l,
1712
1762
1713
- Scope :: Supertrait { s, .. } | Scope :: TraitRefBoundary { s, .. } => {
1763
+ Scope :: Supertrait { s, .. }
1764
+ | Scope :: TraitRefBoundary { s, .. }
1765
+ | Scope :: AnonConstBoundary { s } => {
1714
1766
scope = s;
1715
1767
}
1716
1768
}
0 commit comments