about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_borrowck/src/universal_regions.rs27
-rw-r--r--tests/ui/borrowck/liberated-region-from-outer-closure.rs12
-rw-r--r--tests/ui/borrowck/liberated-region-from-outer-closure.stderr17
-rw-r--r--tests/ui/nll/closure-requirements/escape-argument-callee.stderr3
-rw-r--r--tests/ui/nll/closure-requirements/escape-argument.stderr2
-rw-r--r--tests/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr2
-rw-r--r--tests/ui/nll/closure-requirements/propagate-approximated-ref.stderr6
-rw-r--r--tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr2
-rw-r--r--tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr5
-rw-r--r--tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr6
-rw-r--r--tests/ui/nll/closure-requirements/propagate-approximated-val.stderr2
-rw-r--r--tests/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr2
-rw-r--r--tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr5
-rw-r--r--tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr6
-rw-r--r--tests/ui/nll/closure-requirements/return-wrong-bound-region.stderr2
-rw-r--r--tests/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr4
16 files changed, 97 insertions, 6 deletions
diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs
index f138f265320..240c9a5223b 100644
--- a/compiler/rustc_borrowck/src/universal_regions.rs
+++ b/compiler/rustc_borrowck/src/universal_regions.rs
@@ -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);
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