about summary refs log tree commit diff
path: root/tests
diff options
context:
space:
mode:
authorMatthias Krüger <476013+matthiaskrgr@users.noreply.github.com>2025-05-22 16:02:26 +0200
committerGitHub <noreply@github.com>2025-05-22 16:02:26 +0200
commit706dc7091628735e29c9061df6ecfdb38c55b651 (patch)
treeccc5b6dcc93e9359ce03e6e6cd3508573db65b02 /tests
parent4c6aee567df528e7861a6949150fcc6351358007 (diff)
parentc57ef293eb5c628b5a96253868c4ca171416780a (diff)
downloadrust-706dc7091628735e29c9061df6ecfdb38c55b651.tar.gz
rust-706dc7091628735e29c9061df6ecfdb38c55b651.zip
Rollup merge of #139668 - matthewjasper:upper-bound-fix, r=compiler-errors
Handle regions equivalent to 'static in non_local_bounds

`non_local_bounds` would only find non local bounds that strictly bound a given region, but it's possible that a local region is equated to 'static when showing a type referencing a locally bound lifetime, such as `dyn Any + 'a` in the tests added, is well-formed. In this case we should return 'static.

closes #122704
closes #139004
Diffstat (limited to 'tests')
-rw-r--r--tests/crashes/122704.rs14
-rw-r--r--tests/ui/borrowck/unconstrained-closure-lifetime-generic.rs22
-rw-r--r--tests/ui/borrowck/unconstrained-closure-lifetime-generic.stderr119
-rw-r--r--tests/ui/borrowck/unconstrained-closure-lifetime-trait-object.rs11
-rw-r--r--tests/ui/borrowck/unconstrained-closure-lifetime-trait-object.stderr17
5 files changed, 169 insertions, 14 deletions
diff --git a/tests/crashes/122704.rs b/tests/crashes/122704.rs
deleted file mode 100644
index d6c07be8318..00000000000
--- a/tests/crashes/122704.rs
+++ /dev/null
@@ -1,14 +0,0 @@
-//@ known-bug: #122704
-use std::any::Any;
-
-pub struct Foo {
-    bar: Box<dyn for<'a> Fn(&'a usize) -> Box<dyn Any + 'a>>,
-}
-
-impl Foo {
-    pub fn ack<I>(&mut self, f: impl for<'a> Fn(&'a usize) -> Box<I>) {
-        self.bar = Box::new(|baz| Box::new(f(baz)));
-    }
-}
-
-fn main() {}
diff --git a/tests/ui/borrowck/unconstrained-closure-lifetime-generic.rs b/tests/ui/borrowck/unconstrained-closure-lifetime-generic.rs
new file mode 100644
index 00000000000..4fdf5470fea
--- /dev/null
+++ b/tests/ui/borrowck/unconstrained-closure-lifetime-generic.rs
@@ -0,0 +1,22 @@
+// Regression test for #122704
+use std::any::Any;
+
+pub struct Foo {
+    bar: Box<dyn for<'a> Fn(&'a usize) -> Box<dyn Any + 'a>>,
+}
+
+impl Foo {
+    pub fn ack<I>(&mut self, f: impl for<'a> Fn(&'a usize) -> Box<I>) {
+        self.bar = Box::new(|baz| Box::new(f(baz)));
+        //~^ ERROR the parameter type `impl for<'a> Fn(&'a usize) -> Box<I>` may not live long enough
+        //~| ERROR the parameter type `impl for<'a> Fn(&'a usize) -> Box<I>` may not live long enough
+        //~| ERROR the parameter type `impl for<'a> Fn(&'a usize) -> Box<I>` may not live long enough
+        //~| ERROR the parameter type `impl for<'a> Fn(&'a usize) -> Box<I>` may not live long enough
+        //~| ERROR the parameter type `I` may not live long enough
+        //~| ERROR the parameter type `I` may not live long enough
+        //~| ERROR the parameter type `I` may not live long enough
+        //~| ERROR `f` does not live long enough
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/borrowck/unconstrained-closure-lifetime-generic.stderr b/tests/ui/borrowck/unconstrained-closure-lifetime-generic.stderr
new file mode 100644
index 00000000000..df86ce79f09
--- /dev/null
+++ b/tests/ui/borrowck/unconstrained-closure-lifetime-generic.stderr
@@ -0,0 +1,119 @@
+error[E0310]: the parameter type `impl for<'a> Fn(&'a usize) -> Box<I>` may not live long enough
+  --> $DIR/unconstrained-closure-lifetime-generic.rs:10:9
+   |
+LL |         self.bar = Box::new(|baz| Box::new(f(baz)));
+   |         ^^^^^^^^
+   |         |
+   |         the parameter type `impl for<'a> Fn(&'a usize) -> Box<I>` must be valid for the static lifetime...
+   |         ...so that the type `impl for<'a> Fn(&'a usize) -> Box<I>` will meet its required lifetime bounds
+   |
+help: consider adding an explicit lifetime bound
+   |
+LL |     pub fn ack<I>(&mut self, f: impl for<'a> Fn(&'a usize) -> Box<I> + 'static) {
+   |                                                                      +++++++++
+
+error[E0310]: the parameter type `impl for<'a> Fn(&'a usize) -> Box<I>` may not live long enough
+  --> $DIR/unconstrained-closure-lifetime-generic.rs:10:9
+   |
+LL |         self.bar = Box::new(|baz| Box::new(f(baz)));
+   |         ^^^^^^^^
+   |         |
+   |         the parameter type `impl for<'a> Fn(&'a usize) -> Box<I>` must be valid for the static lifetime...
+   |         ...so that the type `impl for<'a> Fn(&'a usize) -> Box<I>` will meet its required lifetime bounds
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+help: consider adding an explicit lifetime bound
+   |
+LL |     pub fn ack<I>(&mut self, f: impl for<'a> Fn(&'a usize) -> Box<I> + 'static) {
+   |                                                                      +++++++++
+
+error[E0310]: the parameter type `impl for<'a> Fn(&'a usize) -> Box<I>` may not live long enough
+  --> $DIR/unconstrained-closure-lifetime-generic.rs:10:20
+   |
+LL |         self.bar = Box::new(|baz| Box::new(f(baz)));
+   |                    ^^^^^^^^
+   |                    |
+   |                    the parameter type `impl for<'a> Fn(&'a usize) -> Box<I>` must be valid for the static lifetime...
+   |                    ...so that the type `impl for<'a> Fn(&'a usize) -> Box<I>` will meet its required lifetime bounds
+   |
+help: consider adding an explicit lifetime bound
+   |
+LL |     pub fn ack<I>(&mut self, f: impl for<'a> Fn(&'a usize) -> Box<I> + 'static) {
+   |                                                                      +++++++++
+
+error[E0310]: the parameter type `impl for<'a> Fn(&'a usize) -> Box<I>` may not live long enough
+  --> $DIR/unconstrained-closure-lifetime-generic.rs:10:20
+   |
+LL |         self.bar = Box::new(|baz| Box::new(f(baz)));
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                    |
+   |                    the parameter type `impl for<'a> Fn(&'a usize) -> Box<I>` must be valid for the static lifetime...
+   |                    ...so that the type `impl for<'a> Fn(&'a usize) -> Box<I>` will meet its required lifetime bounds
+   |
+help: consider adding an explicit lifetime bound
+   |
+LL |     pub fn ack<I>(&mut self, f: impl for<'a> Fn(&'a usize) -> Box<I> + 'static) {
+   |                                                                      +++++++++
+
+error[E0310]: the parameter type `I` may not live long enough
+  --> $DIR/unconstrained-closure-lifetime-generic.rs:10:35
+   |
+LL |         self.bar = Box::new(|baz| Box::new(f(baz)));
+   |                                   ^^^^^^^^^^^^^^^^
+   |                                   |
+   |                                   the parameter type `I` must be valid for the static lifetime...
+   |                                   ...so that the type `I` will meet its required lifetime bounds
+   |
+help: consider adding an explicit lifetime bound
+   |
+LL |     pub fn ack<I: 'static>(&mut self, f: impl for<'a> Fn(&'a usize) -> Box<I>) {
+   |                 +++++++++
+
+error[E0310]: the parameter type `I` may not live long enough
+  --> $DIR/unconstrained-closure-lifetime-generic.rs:10:35
+   |
+LL |         self.bar = Box::new(|baz| Box::new(f(baz)));
+   |                                   ^^^^^^^^^^^^^^^^
+   |                                   |
+   |                                   the parameter type `I` must be valid for the static lifetime...
+   |                                   ...so that the type `I` will meet its required lifetime bounds
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+help: consider adding an explicit lifetime bound
+   |
+LL |     pub fn ack<I: 'static>(&mut self, f: impl for<'a> Fn(&'a usize) -> Box<I>) {
+   |                 +++++++++
+
+error[E0311]: the parameter type `I` may not live long enough
+  --> $DIR/unconstrained-closure-lifetime-generic.rs:10:35
+   |
+LL |     pub fn ack<I>(&mut self, f: impl for<'a> Fn(&'a usize) -> Box<I>) {
+   |                   --------- the parameter type `I` must be valid for the anonymous lifetime defined here...
+LL |         self.bar = Box::new(|baz| Box::new(f(baz)));
+   |                                   ^^^^^^^^^^^^^^^^ ...so that the type `I` will meet its required lifetime bounds
+   |
+help: consider adding an explicit lifetime bound
+   |
+LL |     pub fn ack<'a, I: 'a>(&'a mut self, f: impl for<'a> Fn(&'a usize) -> Box<I>) {
+   |                +++  ++++   ++
+
+error[E0597]: `f` does not live long enough
+  --> $DIR/unconstrained-closure-lifetime-generic.rs:10:44
+   |
+LL |     pub fn ack<I>(&mut self, f: impl for<'a> Fn(&'a usize) -> Box<I>) {
+   |                              - binding `f` declared here
+LL |         self.bar = Box::new(|baz| Box::new(f(baz)));
+   |         --------            -----          ^ borrowed value does not live long enough
+   |         |                   |
+   |         |                   value captured here
+   |         coercion requires that `f` is borrowed for `'static`
+...
+LL |     }
+   |     - `f` dropped here while still borrowed
+   |
+   = note: due to object lifetime defaults, `Box<dyn for<'a> Fn(&'a usize) -> Box<(dyn Any + 'a)>>` actually means `Box<(dyn for<'a> Fn(&'a usize) -> Box<(dyn Any + 'a)> + 'static)>`
+
+error: aborting due to 8 previous errors
+
+Some errors have detailed explanations: E0310, E0311, E0597.
+For more information about an error, try `rustc --explain E0310`.
diff --git a/tests/ui/borrowck/unconstrained-closure-lifetime-trait-object.rs b/tests/ui/borrowck/unconstrained-closure-lifetime-trait-object.rs
new file mode 100644
index 00000000000..3eee98d9bdb
--- /dev/null
+++ b/tests/ui/borrowck/unconstrained-closure-lifetime-trait-object.rs
@@ -0,0 +1,11 @@
+// Regression test for #139004
+use std::any::Any;
+
+type B = Box<dyn for<'a> Fn(&(dyn Any + 'a)) -> Box<dyn Any + 'a>>;
+
+fn foo<E>() -> B {
+    Box::new(|e| Box::new(e.is::<E>()))
+    //~^ ERROR the parameter type `E` may not live long enough
+}
+
+fn main() {}
diff --git a/tests/ui/borrowck/unconstrained-closure-lifetime-trait-object.stderr b/tests/ui/borrowck/unconstrained-closure-lifetime-trait-object.stderr
new file mode 100644
index 00000000000..c9d5f78828d
--- /dev/null
+++ b/tests/ui/borrowck/unconstrained-closure-lifetime-trait-object.stderr
@@ -0,0 +1,17 @@
+error[E0310]: the parameter type `E` may not live long enough
+  --> $DIR/unconstrained-closure-lifetime-trait-object.rs:7:29
+   |
+LL |     Box::new(|e| Box::new(e.is::<E>()))
+   |                             ^^
+   |                             |
+   |                             the parameter type `E` must be valid for the static lifetime...
+   |                             ...so that the type `E` will meet its required lifetime bounds
+   |
+help: consider adding an explicit lifetime bound
+   |
+LL | fn foo<E: 'static>() -> B {
+   |         +++++++++
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0310`.