about summary refs log tree commit diff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/ui/fn/fn-item-lifetime-bounds.rs37
-rw-r--r--tests/ui/wf/wf-fn-def-check-sig-1.rs44
-rw-r--r--tests/ui/wf/wf-fn-def-check-sig-1.stderr14
-rw-r--r--tests/ui/wf/wf-fn-def-check-sig-2.rs44
-rw-r--r--tests/ui/wf/wf-fn-def-check-sig-2.stderr15
5 files changed, 117 insertions, 37 deletions
diff --git a/tests/ui/fn/fn-item-lifetime-bounds.rs b/tests/ui/fn/fn-item-lifetime-bounds.rs
deleted file mode 100644
index b80b7eade23..00000000000
--- a/tests/ui/fn/fn-item-lifetime-bounds.rs
+++ /dev/null
@@ -1,37 +0,0 @@
-//@ check-pass
-//@ known-bug: #84533
-
-// Should fail. Lifetimes are checked correctly when `foo` is called, but NOT
-// when only the lifetime parameters are instantiated.
-
-use std::marker::PhantomData;
-
-#[allow(dead_code)]
-fn foo<'b, 'a>() -> PhantomData<&'b &'a ()> {
-    PhantomData
-}
-
-#[allow(dead_code)]
-#[allow(path_statements)]
-fn caller<'b, 'a>() {
-    foo::<'b, 'a>;
-}
-
-// In contrast to above, below code correctly does NOT compile.
-// fn caller<'b, 'a>() {
-//     foo::<'b, 'a>();
-// }
-
-// error: lifetime may not live long enough
-//   --> src/main.rs:22:5
-//   |
-// 21 | fn caller<'b, 'a>() {
-//   |           --  -- lifetime `'a` defined here
-//   |           |
-//   |           lifetime `'b` defined here
-// 22 |     foo::<'b, 'a>();
-//   |     ^^^^^^^^^^^^^^^ requires that `'a` must outlive `'b`
-//   |
-//   = help: consider adding the following bound: `'a: 'b`
-
-fn main() {}
diff --git a/tests/ui/wf/wf-fn-def-check-sig-1.rs b/tests/ui/wf/wf-fn-def-check-sig-1.rs
new file mode 100644
index 00000000000..621d1ac3fc1
--- /dev/null
+++ b/tests/ui/wf/wf-fn-def-check-sig-1.rs
@@ -0,0 +1,44 @@
+// Regression test for #84533.
+
+use std::marker::PhantomData;
+
+fn foo<'b, 'a>() -> PhantomData<&'b &'a ()> {
+    PhantomData
+}
+
+fn extend_lifetime<'a, 'b, T: ?Sized>(x: &'a T) -> &'b T {
+    let f = foo::<'b, 'a>;
+    //~^ ERROR lifetime may not live long enough
+    f.baz(x)
+}
+
+trait Foo<'a, 'b, T: ?Sized> {
+    fn baz(self, s: &'a T) -> &'b T;
+}
+impl<'a, 'b, R, F, T: ?Sized> Foo<'a, 'b, T> for F
+where
+    F: Fn() -> R,
+    R: ProofForConversion<'a, 'b, T>,
+{
+    fn baz(self, s: &'a T) -> &'b T {
+        self().convert(s)
+    }
+}
+
+trait ProofForConversion<'a, 'b, T: ?Sized> {
+    fn convert(self, s: &'a T) -> &'b T;
+}
+impl<'a, 'b, T: ?Sized> ProofForConversion<'a, 'b, T> for PhantomData<&'b &'a ()> {
+    fn convert(self, s: &'a T) -> &'b T {
+        s
+    }
+}
+
+fn main() {
+    let d;
+    {
+        let x = "Hello World".to_string();
+        d = extend_lifetime(&x);
+    }
+    println!("{}", d);
+}
diff --git a/tests/ui/wf/wf-fn-def-check-sig-1.stderr b/tests/ui/wf/wf-fn-def-check-sig-1.stderr
new file mode 100644
index 00000000000..9501d6de8b5
--- /dev/null
+++ b/tests/ui/wf/wf-fn-def-check-sig-1.stderr
@@ -0,0 +1,14 @@
+error: lifetime may not live long enough
+  --> $DIR/wf-fn-def-check-sig-1.rs:10:13
+   |
+LL | fn extend_lifetime<'a, 'b, T: ?Sized>(x: &'a T) -> &'b T {
+   |                    --  -- lifetime `'b` defined here
+   |                    |
+   |                    lifetime `'a` defined here
+LL |     let f = foo::<'b, 'a>;
+   |             ^^^^^^^^^^^^^ requires that `'a` must outlive `'b`
+   |
+   = help: consider adding the following bound: `'a: 'b`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/wf/wf-fn-def-check-sig-2.rs b/tests/ui/wf/wf-fn-def-check-sig-2.rs
new file mode 100644
index 00000000000..51740dca8e9
--- /dev/null
+++ b/tests/ui/wf/wf-fn-def-check-sig-2.rs
@@ -0,0 +1,44 @@
+// Regression test for #84533 involving higher-ranked regions
+// in the return type.
+use std::marker::PhantomData;
+
+fn foo<'c, 'b, 'a>(_: &'c ()) -> (&'c (), PhantomData<&'b &'a ()>) {
+    (&(), PhantomData)
+}
+
+fn extend_lifetime<'a, 'b, T: ?Sized>(x: &'a T) -> &'b T {
+    let f = foo;
+    f.baz(x)
+    //~^ ERROR lifetime may not live long enough
+}
+
+trait Foo<'a, 'b, T: ?Sized> {
+    fn baz(self, s: &'a T) -> &'b T;
+}
+impl<'a, 'b, R, F, T: ?Sized> Foo<'a, 'b, T> for F
+where
+    F: for<'c> Fn(&'c ()) -> (&'c (), R),
+    R: ProofForConversion<'a, 'b, T>,
+{
+    fn baz(self, s: &'a T) -> &'b T {
+        self(&()).1.convert(s)
+    }
+}
+
+trait ProofForConversion<'a, 'b, T: ?Sized> {
+    fn convert(self, s: &'a T) -> &'b T;
+}
+impl<'a, 'b, T: ?Sized> ProofForConversion<'a, 'b, T> for PhantomData<&'b &'a ()> {
+    fn convert(self, s: &'a T) -> &'b T {
+        s
+    }
+}
+
+fn main() {
+    let d;
+    {
+        let x = "Hello World".to_string();
+        d = extend_lifetime(&x);
+    }
+    println!("{}", d);
+}
diff --git a/tests/ui/wf/wf-fn-def-check-sig-2.stderr b/tests/ui/wf/wf-fn-def-check-sig-2.stderr
new file mode 100644
index 00000000000..70c0fd32e1b
--- /dev/null
+++ b/tests/ui/wf/wf-fn-def-check-sig-2.stderr
@@ -0,0 +1,15 @@
+error: lifetime may not live long enough
+  --> $DIR/wf-fn-def-check-sig-2.rs:11:5
+   |
+LL | fn extend_lifetime<'a, 'b, T: ?Sized>(x: &'a T) -> &'b T {
+   |                    --  -- lifetime `'b` defined here
+   |                    |
+   |                    lifetime `'a` defined here
+LL |     let f = foo;
+LL |     f.baz(x)
+   |     ^^^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
+   |
+   = help: consider adding the following bound: `'a: 'b`
+
+error: aborting due to previous error
+