Skip to content

Commit 98d08ff

Browse files
Make sure to account for the right item universal regions in borrowck
1 parent c8bb4e8 commit 98d08ff

16 files changed

+97
-6
lines changed

compiler/rustc_borrowck/src/universal_regions.rs

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -969,13 +969,28 @@ fn for_each_late_bound_region_in_item<'tcx>(
969969
mir_def_id: LocalDefId,
970970
mut f: impl FnMut(ty::Region<'tcx>),
971971
) {
972-
if !tcx.def_kind(mir_def_id).is_fn_like() {
973-
return;
974-
}
972+
let bound_vars = match tcx.def_kind(mir_def_id) {
973+
DefKind::Fn | DefKind::AssocFn => {
974+
tcx.late_bound_vars(tcx.local_def_id_to_hir_id(mir_def_id))
975+
}
976+
// We extract the bound vars from the deduced closure signature, since we may have
977+
// only deduced that a param in the closure signature is late-bound from a constraint
978+
// that we discover during typeck.
979+
DefKind::Closure => {
980+
let ty = tcx.type_of(mir_def_id).instantiate_identity();
981+
match *ty.kind() {
982+
ty::Closure(_, args) => args.as_closure().sig().bound_vars(),
983+
ty::CoroutineClosure(_, args) => {
984+
args.as_coroutine_closure().coroutine_closure_sig().bound_vars()
985+
}
986+
ty::Coroutine(_, _) | ty::Error(_) => return,
987+
_ => unreachable!("unexpected type for closure: {ty}"),
988+
}
989+
}
990+
_ => return,
991+
};
975992

976-
for (idx, bound_var) in
977-
tcx.late_bound_vars(tcx.local_def_id_to_hir_id(mir_def_id)).iter().enumerate()
978-
{
993+
for (idx, bound_var) in bound_vars.iter().enumerate() {
979994
if let ty::BoundVariableKind::Region(kind) = bound_var {
980995
let kind = ty::LateParamRegionKind::from_bound(ty::BoundVar::from_usize(idx), kind);
981996
let liberated_region = ty::Region::new_late_param(tcx, mir_def_id.to_def_id(), kind);
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Regression test for <https://github.com/rust-lang/rust/issues/144608>.
2+
3+
fn example<T: Copy>(x: T) -> impl FnMut(&mut ()) {
4+
move |_: &mut ()| {
5+
move || needs_static_lifetime(x);
6+
//~^ ERROR the parameter type `T` may not live long enough
7+
}
8+
}
9+
10+
fn needs_static_lifetime<T: 'static>(obj: T) {}
11+
12+
fn main() {}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
error[E0310]: the parameter type `T` may not live long enough
2+
--> $DIR/liberated-region-from-outer-closure.rs:5:17
3+
|
4+
LL | move || needs_static_lifetime(x);
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^
6+
| |
7+
| the parameter type `T` must be valid for the static lifetime...
8+
| ...so that the type `T` will meet its required lifetime bounds
9+
|
10+
help: consider adding an explicit lifetime bound
11+
|
12+
LL | fn example<T: Copy + 'static>(x: T) -> impl FnMut(&mut ()) {
13+
| +++++++++
14+
15+
error: aborting due to 1 previous error
16+
17+
For more information about this error, try `rustc --explain E0310`.

tests/ui/nll/closure-requirements/escape-argument-callee.stderr

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ LL | let mut closure = expect_sig(|p, y| *p = y);
99
for<Region(BrAnon), Region(BrAnon), Region(BrAnon)> extern "rust-call" fn((&'^0 mut &'^1 i32, &'^2 i32)),
1010
(),
1111
]
12+
= note: late-bound region is '?1
13+
= note: late-bound region is '?2
14+
= note: late-bound region is '?3
1215

1316
error: lifetime may not live long enough
1417
--> $DIR/escape-argument-callee.rs:26:45

tests/ui/nll/closure-requirements/escape-argument.stderr

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ LL | let mut closure = expect_sig(|p, y| *p = y);
99
for<Region(BrAnon), Region(BrAnon)> extern "rust-call" fn((&'^0 mut &'^1 i32, &'^1 i32)),
1010
(),
1111
]
12+
= note: late-bound region is '?1
13+
= note: late-bound region is '?2
1214

1315
note: no external requirements
1416
--> $DIR/escape-argument.rs:20:1

tests/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ LL | |_outlives1, _outlives2, _outlives3, x, y| {
99
for<Region(BrAnon), Region(BrAnon)> extern "rust-call" fn((std::cell::Cell<&'?1 &'^0 u32>, std::cell::Cell<&'?2 &'^0 u32>, std::cell::Cell<&'^1 &'?3 u32>, std::cell::Cell<&'^0 u32>, std::cell::Cell<&'^1 u32>)),
1010
(),
1111
]
12+
= note: late-bound region is '?7
13+
= note: late-bound region is '?8
1214
= note: late-bound region is '?4
1315
= note: late-bound region is '?5
1416
= note: late-bound region is '?6

tests/ui/nll/closure-requirements/propagate-approximated-ref.stderr

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@ LL | establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y
99
for<Region(BrAnon), Region(BrAnon), Region(BrAnon), Region(BrAnon), Region(BrAnon), Region(BrAnon)> extern "rust-call" fn((&'^0 std::cell::Cell<&'?1 &'^1 u32>, &'^2 std::cell::Cell<&'^3 &'?2 u32>, &'^4 std::cell::Cell<&'^1 u32>, &'^5 std::cell::Cell<&'^3 u32>)),
1010
(),
1111
]
12+
= note: late-bound region is '?5
13+
= note: late-bound region is '?6
14+
= note: late-bound region is '?7
15+
= note: late-bound region is '?8
16+
= note: late-bound region is '?9
17+
= note: late-bound region is '?10
1218
= note: late-bound region is '?3
1319
= note: late-bound region is '?4
1420
= note: number of external vids: 5

tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ LL | foo(cell, |cell_a, cell_x| {
99
for<Region(BrAnon)> extern "rust-call" fn((std::cell::Cell<&'?1 u32>, std::cell::Cell<&'^0 u32>)),
1010
(),
1111
]
12+
= note: late-bound region is '?2
1213

1314
error[E0521]: borrowed data escapes outside of closure
1415
--> $DIR/propagate-approximated-shorter-to-static-comparing-against-free.rs:22:9
@@ -43,6 +44,7 @@ LL | foo(cell, |cell_a, cell_x| {
4344
for<Region(BrAnon)> extern "rust-call" fn((std::cell::Cell<&'?1 u32>, std::cell::Cell<&'^0 u32>)),
4445
(),
4546
]
47+
= note: late-bound region is '?2
4648
= note: number of external vids: 2
4749
= note: where '?1: '?0
4850

tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@ LL | establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
99
for<Region(BrAnon), Region(BrAnon), Region(BrAnon), Region(BrAnon), Region(BrAnon)> extern "rust-call" fn((&'^0 std::cell::Cell<&'?1 &'^1 u32>, &'^2 std::cell::Cell<&'^1 u32>, &'^3 std::cell::Cell<&'^4 u32>)),
1010
(),
1111
]
12+
= note: late-bound region is '?4
13+
= note: late-bound region is '?5
14+
= note: late-bound region is '?6
15+
= note: late-bound region is '?7
16+
= note: late-bound region is '?8
1217
= note: late-bound region is '?2
1318
= note: late-bound region is '?3
1419
= note: number of external vids: 4

tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@ LL | establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y
99
for<Region(BrAnon), Region(BrAnon), Region(BrAnon), Region(BrAnon), Region(BrAnon), Region(BrAnon)> extern "rust-call" fn((&'^0 std::cell::Cell<&'?1 &'^1 u32>, &'^2 std::cell::Cell<&'?2 &'^3 u32>, &'^4 std::cell::Cell<&'^1 u32>, &'^5 std::cell::Cell<&'^3 u32>)),
1010
(),
1111
]
12+
= note: late-bound region is '?5
13+
= note: late-bound region is '?6
14+
= note: late-bound region is '?7
15+
= note: late-bound region is '?8
16+
= note: late-bound region is '?9
17+
= note: late-bound region is '?10
1218
= note: late-bound region is '?3
1319
= note: late-bound region is '?4
1420
= note: number of external vids: 5

0 commit comments

Comments
 (0)