about summary refs log tree commit diff
path: root/tests
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2024-01-04 01:46:43 +0000
committerMichael Goulet <michael@errs.io>2024-01-04 01:47:56 +0000
commit1d48f69d65af74201314304623f37f5bcefa9a24 (patch)
tree0d23182d1d71f440a1abf6fff4cba9778bd80fa1 /tests
parent139fb2214675fed8143a12f6287a3a1e6e2e866d (diff)
downloadrust-1d48f69d65af74201314304623f37f5bcefa9a24.tar.gz
rust-1d48f69d65af74201314304623f37f5bcefa9a24.zip
Check yield terminator's resume type in borrowck
Diffstat (limited to 'tests')
-rw-r--r--tests/ui/coroutine/check-resume-ty-lifetimes-2.rs35
-rw-r--r--tests/ui/coroutine/check-resume-ty-lifetimes-2.stderr36
-rw-r--r--tests/ui/coroutine/check-resume-ty-lifetimes.rs27
-rw-r--r--tests/ui/coroutine/check-resume-ty-lifetimes.stderr11
4 files changed, 109 insertions, 0 deletions
diff --git a/tests/ui/coroutine/check-resume-ty-lifetimes-2.rs b/tests/ui/coroutine/check-resume-ty-lifetimes-2.rs
new file mode 100644
index 00000000000..a316c50e867
--- /dev/null
+++ b/tests/ui/coroutine/check-resume-ty-lifetimes-2.rs
@@ -0,0 +1,35 @@
+#![feature(coroutine_trait)]
+#![feature(coroutines)]
+
+use std::ops::Coroutine;
+
+struct Contravariant<'a>(fn(&'a ()));
+struct Covariant<'a>(fn() -> &'a ());
+
+fn bad1<'short, 'long: 'short>() -> impl Coroutine<Covariant<'short>> {
+    |_: Covariant<'short>| {
+        let a: Covariant<'long> = yield ();
+        //~^ ERROR lifetime may not live long enough
+    }
+}
+
+fn bad2<'short, 'long: 'short>() -> impl Coroutine<Contravariant<'long>> {
+    |_: Contravariant<'long>| {
+        let a: Contravariant<'short> = yield ();
+        //~^ ERROR lifetime may not live long enough
+    }
+}
+
+fn good1<'short, 'long: 'short>() -> impl Coroutine<Covariant<'long>> {
+    |_: Covariant<'long>| {
+        let a: Covariant<'short> = yield ();
+    }
+}
+
+fn good2<'short, 'long: 'short>() -> impl Coroutine<Contravariant<'short>> {
+    |_: Contravariant<'short>| {
+        let a: Contravariant<'long> = yield ();
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/coroutine/check-resume-ty-lifetimes-2.stderr b/tests/ui/coroutine/check-resume-ty-lifetimes-2.stderr
new file mode 100644
index 00000000000..e0cbca2dd52
--- /dev/null
+++ b/tests/ui/coroutine/check-resume-ty-lifetimes-2.stderr
@@ -0,0 +1,36 @@
+error: lifetime may not live long enough
+  --> $DIR/check-resume-ty-lifetimes-2.rs:11:16
+   |
+LL | fn bad1<'short, 'long: 'short>() -> impl Coroutine<Covariant<'short>> {
+   |         ------  ----- lifetime `'long` defined here
+   |         |
+   |         lifetime `'short` defined here
+LL |     |_: Covariant<'short>| {
+LL |         let a: Covariant<'long> = yield ();
+   |                ^^^^^^^^^^^^^^^^ type annotation requires that `'short` must outlive `'long`
+   |
+   = help: consider adding the following bound: `'short: 'long`
+help: consider adding 'move' keyword before the nested closure
+   |
+LL |     move |_: Covariant<'short>| {
+   |     ++++
+
+error: lifetime may not live long enough
+  --> $DIR/check-resume-ty-lifetimes-2.rs:18:40
+   |
+LL | fn bad2<'short, 'long: 'short>() -> impl Coroutine<Contravariant<'long>> {
+   |         ------  ----- lifetime `'long` defined here
+   |         |
+   |         lifetime `'short` defined here
+LL |     |_: Contravariant<'long>| {
+LL |         let a: Contravariant<'short> = yield ();
+   |                                        ^^^^^^^^ yielding this value requires that `'short` must outlive `'long`
+   |
+   = help: consider adding the following bound: `'short: 'long`
+help: consider adding 'move' keyword before the nested closure
+   |
+LL |     move |_: Contravariant<'long>| {
+   |     ++++
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/coroutine/check-resume-ty-lifetimes.rs b/tests/ui/coroutine/check-resume-ty-lifetimes.rs
new file mode 100644
index 00000000000..add0b5080a8
--- /dev/null
+++ b/tests/ui/coroutine/check-resume-ty-lifetimes.rs
@@ -0,0 +1,27 @@
+#![feature(coroutine_trait)]
+#![feature(coroutines)]
+#![allow(unused)]
+
+use std::ops::Coroutine;
+use std::ops::CoroutineState;
+use std::pin::pin;
+
+fn mk_static(s: &str) -> &'static str {
+    let mut storage: Option<&'static str> = None;
+
+    let mut coroutine = pin!(|_: &str| {
+        let x: &'static str = yield ();
+        //~^ ERROR lifetime may not live long enough
+        storage = Some(x);
+    });
+
+    coroutine.as_mut().resume(s);
+    coroutine.as_mut().resume(s);
+
+    storage.unwrap()
+}
+
+fn main() {
+    let s = mk_static(&String::from("hello, world"));
+    println!("{s}");
+}
diff --git a/tests/ui/coroutine/check-resume-ty-lifetimes.stderr b/tests/ui/coroutine/check-resume-ty-lifetimes.stderr
new file mode 100644
index 00000000000..f373aa778a8
--- /dev/null
+++ b/tests/ui/coroutine/check-resume-ty-lifetimes.stderr
@@ -0,0 +1,11 @@
+error: lifetime may not live long enough
+  --> $DIR/check-resume-ty-lifetimes.rs:13:16
+   |
+LL | fn mk_static(s: &str) -> &'static str {
+   |                 - let's call the lifetime of this reference `'1`
+...
+LL |         let x: &'static str = yield ();
+   |                ^^^^^^^^^^^^ type annotation requires that `'1` must outlive `'static`
+
+error: aborting due to 1 previous error
+