Make sure to account for the right item universal regions in borrowck

This commit is contained in:
Michael Goulet 2025-07-30 03:39:16 +00:00
parent c8bb4e8a12
commit 98d08ff014
16 changed files with 97 additions and 6 deletions

View File

@ -969,13 +969,28 @@ fn for_each_late_bound_region_in_item<'tcx>(
mir_def_id: LocalDefId,
mut f: impl FnMut(ty::Region<'tcx>),
) {
if !tcx.def_kind(mir_def_id).is_fn_like() {
return;
}
let bound_vars = match tcx.def_kind(mir_def_id) {
DefKind::Fn | DefKind::AssocFn => {
tcx.late_bound_vars(tcx.local_def_id_to_hir_id(mir_def_id))
}
// We extract the bound vars from the deduced closure signature, since we may have
// only deduced that a param in the closure signature is late-bound from a constraint
// that we discover during typeck.
DefKind::Closure => {
let ty = tcx.type_of(mir_def_id).instantiate_identity();
match *ty.kind() {
ty::Closure(_, args) => args.as_closure().sig().bound_vars(),
ty::CoroutineClosure(_, args) => {
args.as_coroutine_closure().coroutine_closure_sig().bound_vars()
}
ty::Coroutine(_, _) | ty::Error(_) => return,
_ => unreachable!("unexpected type for closure: {ty}"),
}
}
_ => return,
};
for (idx, bound_var) in
tcx.late_bound_vars(tcx.local_def_id_to_hir_id(mir_def_id)).iter().enumerate()
{
for (idx, bound_var) in bound_vars.iter().enumerate() {
if let ty::BoundVariableKind::Region(kind) = bound_var {
let kind = ty::LateParamRegionKind::from_bound(ty::BoundVar::from_usize(idx), kind);
let liberated_region = ty::Region::new_late_param(tcx, mir_def_id.to_def_id(), kind);

View File

@ -0,0 +1,12 @@
// Regression test for <https://github.com/rust-lang/rust/issues/144608>.
fn example<T: Copy>(x: T) -> impl FnMut(&mut ()) {
move |_: &mut ()| {
move || needs_static_lifetime(x);
//~^ ERROR the parameter type `T` may not live long enough
}
}
fn needs_static_lifetime<T: 'static>(obj: T) {}
fn main() {}

View File

@ -0,0 +1,17 @@
error[E0310]: the parameter type `T` may not live long enough
--> $DIR/liberated-region-from-outer-closure.rs:5:17
|
LL | move || needs_static_lifetime(x);
| ^^^^^^^^^^^^^^^^^^^^^^^^
| |
| the parameter type `T` must be valid for the static lifetime...
| ...so that the type `T` will meet its required lifetime bounds
|
help: consider adding an explicit lifetime bound
|
LL | fn example<T: Copy + 'static>(x: T) -> impl FnMut(&mut ()) {
| +++++++++
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0310`.

View File

@ -9,6 +9,9 @@ LL | let mut closure = expect_sig(|p, y| *p = y);
for<Region(BrAnon), Region(BrAnon), Region(BrAnon)> extern "rust-call" fn((&'^0 mut &'^1 i32, &'^2 i32)),
(),
]
= note: late-bound region is '?1
= note: late-bound region is '?2
= note: late-bound region is '?3
error: lifetime may not live long enough
--> $DIR/escape-argument-callee.rs:26:45

View File

@ -9,6 +9,8 @@ LL | let mut closure = expect_sig(|p, y| *p = y);
for<Region(BrAnon), Region(BrAnon)> extern "rust-call" fn((&'^0 mut &'^1 i32, &'^1 i32)),
(),
]
= note: late-bound region is '?1
= note: late-bound region is '?2
note: no external requirements
--> $DIR/escape-argument.rs:20:1

View File

@ -9,6 +9,8 @@ LL | |_outlives1, _outlives2, _outlives3, x, y| {
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>)),
(),
]
= note: late-bound region is '?7
= note: late-bound region is '?8
= note: late-bound region is '?4
= note: late-bound region is '?5
= note: late-bound region is '?6

View File

@ -9,6 +9,12 @@ LL | establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y
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>)),
(),
]
= note: late-bound region is '?5
= note: late-bound region is '?6
= note: late-bound region is '?7
= note: late-bound region is '?8
= note: late-bound region is '?9
= note: late-bound region is '?10
= note: late-bound region is '?3
= note: late-bound region is '?4
= note: number of external vids: 5

View File

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

View File

@ -9,6 +9,11 @@ LL | establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
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>)),
(),
]
= note: late-bound region is '?4
= note: late-bound region is '?5
= note: late-bound region is '?6
= note: late-bound region is '?7
= note: late-bound region is '?8
= note: late-bound region is '?2
= note: late-bound region is '?3
= note: number of external vids: 4

View File

@ -9,6 +9,12 @@ LL | establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y
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>)),
(),
]
= note: late-bound region is '?5
= note: late-bound region is '?6
= note: late-bound region is '?7
= note: late-bound region is '?8
= note: late-bound region is '?9
= note: late-bound region is '?10
= note: late-bound region is '?3
= note: late-bound region is '?4
= note: number of external vids: 5

View File

@ -9,6 +9,8 @@ LL | establish_relationships(cell_a, cell_b, |outlives1, outlives2, x, y| {
for<Region(BrAnon), Region(BrAnon)> extern "rust-call" fn((std::cell::Cell<&'?1 &'^0 u32>, std::cell::Cell<&'^1 &'?2 u32>, std::cell::Cell<&'^0 u32>, std::cell::Cell<&'^1 u32>)),
(),
]
= note: late-bound region is '?5
= note: late-bound region is '?6
= note: late-bound region is '?3
= note: late-bound region is '?4
= note: number of external vids: 5

View File

@ -9,6 +9,8 @@ LL | |_outlives1, _outlives2, x, y| {
for<Region(BrAnon), Region(BrAnon)> extern "rust-call" fn((std::cell::Cell<&'?1 &'^0 u32>, std::cell::Cell<&'^1 &'?2 u32>, std::cell::Cell<&'^0 u32>, std::cell::Cell<&'^1 u32>)),
(),
]
= note: late-bound region is '?4
= note: late-bound region is '?5
= note: late-bound region is '?3
= note: number of external vids: 4
= note: where '?1: '?2

View File

@ -9,6 +9,11 @@ LL | establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
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<&'^3 u32>, &'^4 std::cell::Cell<&'^1 u32>)),
(),
]
= note: late-bound region is '?4
= note: late-bound region is '?5
= note: late-bound region is '?6
= note: late-bound region is '?7
= note: late-bound region is '?8
= note: late-bound region is '?2
= note: late-bound region is '?3

View File

@ -9,6 +9,12 @@ LL | establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y
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>)),
(),
]
= note: late-bound region is '?5
= note: late-bound region is '?6
= note: late-bound region is '?7
= note: late-bound region is '?8
= note: late-bound region is '?9
= note: late-bound region is '?10
= note: late-bound region is '?3
= note: late-bound region is '?4

View File

@ -9,6 +9,8 @@ LL | expect_sig(|a, b| b); // ought to return `a`
for<Region(BrAnon), Region(BrAnon)> extern "rust-call" fn((&'^0 i32, &'^1 i32)) -> &'^0 i32,
(),
]
= note: late-bound region is '?1
= note: late-bound region is '?2
error: lifetime may not live long enough
--> $DIR/return-wrong-bound-region.rs:11:23

View File

@ -9,6 +9,8 @@ LL | twice(cell, value, |a, b| invoke(a, b));
for<Region(BrAnon), Region(BrAnon)> extern "rust-call" fn((std::option::Option<std::cell::Cell<&'?1 &'^0 ()>>, &'^1 T)),
(),
]
= note: late-bound region is '?2
= note: late-bound region is '?3
= note: number of external vids: 2
= note: where T: '?1
@ -31,6 +33,8 @@ LL | twice(cell, value, |a, b| invoke(a, b));
for<Region(BrAnon), Region(BrAnon)> extern "rust-call" fn((std::option::Option<std::cell::Cell<&'?1 &'^0 ()>>, &'^1 T)),
(),
]
= note: late-bound region is '?3
= note: late-bound region is '?4
= note: late-bound region is '?2
= note: number of external vids: 3
= note: where T: '?1