diff options
| author | Stuart Cook <Zalathar@users.noreply.github.com> | 2025-07-30 17:59:40 +1000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-07-30 17:59:40 +1000 |
| commit | 08e26fc67813470739e171be117cf76c4d96b9a9 (patch) | |
| tree | 8a5dbb582a15c2401520268a6ac6350e60e7d8cf /tests | |
| parent | ba8295019ec8fcd838bcf8ac0575138ddb91203c (diff) | |
| parent | 98d08ff014840a15244374178e8b9ed02da3d4ca (diff) | |
| download | rust-08e26fc67813470739e171be117cf76c4d96b9a9.tar.gz rust-08e26fc67813470739e171be117cf76c4d96b9a9.zip | |
Rollup merge of #144666 - compiler-errors:correct-late, r=lqd
Make sure to account for the right item universal regions in borrowck Fixes https://github.com/rust-lang/rust/issues/144608. The ICE comes from a mismatch between the liberated late bound regions (i.e. "`ReLateParam`"s) that come from promoting closure outlives, and the regions we have in our region vid mapping from `UniversalRegions`. When building `UniversalRegions`, we end up using the liberated regions from the binder of the closure's signature: https://github.com/rust-lang/rust/blob/c8bb4e8a126cf38cff70cea488a3a423a5321954/compiler/rustc_borrowck/src/universal_regions.rs#L521 Notably, this signature may be anonymized if the closure signature being deduced comes from an external constraints: https://github.com/rust-lang/rust/blob/c8bb4e8a126cf38cff70cea488a3a423a5321954/compiler/rustc_hir_typeck/src/closure.rs#L759-L762 This is true in the test file I committed, where the signature is influenced by the `impl FnMut(&mut ())` RPIT. However, when promoting a type outlives constraint we end up creating a late bound lifetime mapping that disagrees with those liberated late bound regions we constructed in `UniversalRegions`: https://github.com/rust-lang/rust/blob/c8bb4e8a126cf38cff70cea488a3a423a5321954/compiler/rustc_borrowck/src/universal_regions.rs#L299 Specifically, in `for_each_late_bound_region_in_item` (which is called by `for_each_late_bound_region_in_recursive_scope`), we were using `tcx.late_bound_vars` which uses the late bound regions *from the HIR*. This query both undercounts the late bound regions (e.g. those that end up being deduced from bounds), and also doesn't account for the fact that we anonymize them in the signature as mentioned above. https://github.com/rust-lang/rust/blob/c8bb4e8a126cf38cff70cea488a3a423a5321954/compiler/rustc_borrowck/src/universal_regions.rs#L977 This PR fixes that function to use the *correct signature*, which properly considers the bound vars that come from deducing the signature of the closure, and which comes from the closure's args from the `type_of` query.
Diffstat (limited to 'tests')
15 files changed, 76 insertions, 0 deletions
diff --git a/tests/ui/borrowck/liberated-region-from-outer-closure.rs b/tests/ui/borrowck/liberated-region-from-outer-closure.rs new file mode 100644 index 00000000000..dcc6370b4a1 --- /dev/null +++ b/tests/ui/borrowck/liberated-region-from-outer-closure.rs @@ -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() {} diff --git a/tests/ui/borrowck/liberated-region-from-outer-closure.stderr b/tests/ui/borrowck/liberated-region-from-outer-closure.stderr new file mode 100644 index 00000000000..98b45ac499d --- /dev/null +++ b/tests/ui/borrowck/liberated-region-from-outer-closure.stderr @@ -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`. diff --git a/tests/ui/nll/closure-requirements/escape-argument-callee.stderr b/tests/ui/nll/closure-requirements/escape-argument-callee.stderr index a445534c8d8..2742162c821 100644 --- a/tests/ui/nll/closure-requirements/escape-argument-callee.stderr +++ b/tests/ui/nll/closure-requirements/escape-argument-callee.stderr @@ -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 diff --git a/tests/ui/nll/closure-requirements/escape-argument.stderr b/tests/ui/nll/closure-requirements/escape-argument.stderr index 7fd1cd8c3e4..22cb0367ad8 100644 --- a/tests/ui/nll/closure-requirements/escape-argument.stderr +++ b/tests/ui/nll/closure-requirements/escape-argument.stderr @@ -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 diff --git a/tests/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr b/tests/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr index 60087ec992b..134ce99014d 100644 --- a/tests/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr +++ b/tests/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr @@ -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 diff --git a/tests/ui/nll/closure-requirements/propagate-approximated-ref.stderr b/tests/ui/nll/closure-requirements/propagate-approximated-ref.stderr index 7325a9de8b2..f5527eeb2cd 100644 --- a/tests/ui/nll/closure-requirements/propagate-approximated-ref.stderr +++ b/tests/ui/nll/closure-requirements/propagate-approximated-ref.stderr @@ -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 diff --git a/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr b/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr index 621c1ea083b..e13653f3423 100644 --- a/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr +++ b/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr @@ -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 diff --git a/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr b/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr index b9365c94a1b..9e9eae98597 100644 --- a/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr +++ b/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr @@ -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 diff --git a/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr b/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr index e5d2867103c..303fcd4cdfc 100644 --- a/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr +++ b/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr @@ -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 diff --git a/tests/ui/nll/closure-requirements/propagate-approximated-val.stderr b/tests/ui/nll/closure-requirements/propagate-approximated-val.stderr index a14bfb06e83..aa75b4c811c 100644 --- a/tests/ui/nll/closure-requirements/propagate-approximated-val.stderr +++ b/tests/ui/nll/closure-requirements/propagate-approximated-val.stderr @@ -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 diff --git a/tests/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr b/tests/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr index 49c65d77ddd..30ee259d3dc 100644 --- a/tests/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr +++ b/tests/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr @@ -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 diff --git a/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr b/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr index f48ed2823dd..6b04e346c69 100644 --- a/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr +++ b/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr @@ -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 diff --git a/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr b/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr index a090e94593f..ae2129c65f2 100644 --- a/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr +++ b/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr @@ -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 diff --git a/tests/ui/nll/closure-requirements/return-wrong-bound-region.stderr b/tests/ui/nll/closure-requirements/return-wrong-bound-region.stderr index bc5c04a27a3..1f1cce1e885 100644 --- a/tests/ui/nll/closure-requirements/return-wrong-bound-region.stderr +++ b/tests/ui/nll/closure-requirements/return-wrong-bound-region.stderr @@ -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 diff --git a/tests/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr b/tests/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr index e58764354c0..396e149554c 100644 --- a/tests/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr +++ b/tests/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr @@ -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 |
