@@ -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 {
@@ -1267,7 +1287,8 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
1267
1287
Scope::Elision { s, .. }
1268
1288
| Scope::ObjectLifetimeDefault { s, .. }
1269
1289
| Scope::Supertrait { s, .. }
1270
- | Scope::TraitRefBoundary { s, .. } => {
1290
+ | Scope::TraitRefBoundary { s, .. }
1291
+ | Scope::AnonConstBoundary { s } => {
1271
1292
scope = s;
1272
1293
}
1273
1294
}
@@ -1332,7 +1353,8 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
1332
1353
| Scope::Elision { s, .. }
1333
1354
| Scope::ObjectLifetimeDefault { s, .. }
1334
1355
| Scope::Supertrait { s, .. }
1335
- | Scope::TraitRefBoundary { s, .. } => {
1356
+ | Scope::TraitRefBoundary { s, .. }
1357
+ | Scope::AnonConstBoundary { s } => {
1336
1358
scope = s;
1337
1359
}
1338
1360
}
@@ -1351,6 +1373,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
1351
1373
// search.
1352
1374
let mut late_depth = 0;
1353
1375
let mut scope = self.scope;
1376
+ let mut crossed_anon_const = false;
1354
1377
let result = loop {
1355
1378
match *scope {
1356
1379
Scope::Body { s, .. } => {
@@ -1384,10 +1407,36 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
1384
1407
| Scope::TraitRefBoundary { s, .. } => {
1385
1408
scope = s;
1386
1409
}
1410
+
1411
+ Scope::AnonConstBoundary { s } => {
1412
+ crossed_anon_const = true;
1413
+ scope = s;
1414
+ }
1387
1415
}
1388
1416
};
1389
1417
1390
1418
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
+
1391
1440
self.map.defs.insert(hir_id, def);
1392
1441
return;
1393
1442
}
@@ -1465,7 +1514,8 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
1465
1514
| Scope::Elision { s, .. }
1466
1515
| Scope::ObjectLifetimeDefault { s, .. }
1467
1516
| Scope::Supertrait { s, .. }
1468
- | Scope::TraitRefBoundary { s, .. } => {
1517
+ | Scope::TraitRefBoundary { s, .. }
1518
+ | Scope::AnonConstBoundary { s } => {
1469
1519
scope = s;
1470
1520
}
1471
1521
}
@@ -1701,7 +1751,9 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
1701
1751
1702
1752
Scope::ObjectLifetimeDefault { lifetime: Some(l), .. } => break l,
1703
1753
1704
- Scope::Supertrait { s, .. } | Scope::TraitRefBoundary { s, .. } => {
1754
+ Scope::Supertrait { s, .. }
1755
+ | Scope::TraitRefBoundary { s, .. }
1756
+ | Scope::AnonConstBoundary { s } => {
1705
1757
scope = s;
1706
1758
}
1707
1759
}
0 commit comments