summaryrefslogtreecommitdiffstats
path: root/tests/ui/async-await/multiple-lifetimes
diff options
context:
space:
mode:
Diffstat (limited to 'tests/ui/async-await/multiple-lifetimes')
-rw-r--r--tests/ui/async-await/multiple-lifetimes/elided.rs10
-rw-r--r--tests/ui/async-await/multiple-lifetimes/fn-ptr.rs12
-rw-r--r--tests/ui/async-await/multiple-lifetimes/hrtb.rs14
-rw-r--r--tests/ui/async-await/multiple-lifetimes/named.rs10
-rw-r--r--tests/ui/async-await/multiple-lifetimes/partial-relation.rs13
-rw-r--r--tests/ui/async-await/multiple-lifetimes/ret-impl-trait-fg.rs17
-rw-r--r--tests/ui/async-await/multiple-lifetimes/ret-impl-trait-one.rs31
-rw-r--r--tests/ui/async-await/multiple-lifetimes/ret-impl-trait-one.stderr35
-rw-r--r--tests/ui/async-await/multiple-lifetimes/ret-ref.rs44
-rw-r--r--tests/ui/async-await/multiple-lifetimes/ret-ref.stderr37
-rw-r--r--tests/ui/async-await/multiple-lifetimes/variance.rs15
11 files changed, 238 insertions, 0 deletions
diff --git a/tests/ui/async-await/multiple-lifetimes/elided.rs b/tests/ui/async-await/multiple-lifetimes/elided.rs
new file mode 100644
index 000000000..8258e2eff
--- /dev/null
+++ b/tests/ui/async-await/multiple-lifetimes/elided.rs
@@ -0,0 +1,10 @@
+// edition:2018
+// run-pass
+
+// Test that we can use async fns with multiple arbitrary lifetimes.
+
+async fn multiple_elided_lifetimes(_: &u8, _: &u8) {}
+
+fn main() {
+ let _ = multiple_elided_lifetimes(&22, &44);
+}
diff --git a/tests/ui/async-await/multiple-lifetimes/fn-ptr.rs b/tests/ui/async-await/multiple-lifetimes/fn-ptr.rs
new file mode 100644
index 000000000..3912b8547
--- /dev/null
+++ b/tests/ui/async-await/multiple-lifetimes/fn-ptr.rs
@@ -0,0 +1,12 @@
+// edition:2018
+// run-pass
+
+// Test that we can use async fns with multiple arbitrary lifetimes.
+
+async fn multiple_named_lifetimes<'a, 'b>(_: &'a u8, _: &'b u8, _: fn(&u8)) {}
+
+fn gimme(_: &u8) { }
+
+fn main() {
+ let _ = multiple_named_lifetimes(&22, &44, gimme);
+}
diff --git a/tests/ui/async-await/multiple-lifetimes/hrtb.rs b/tests/ui/async-await/multiple-lifetimes/hrtb.rs
new file mode 100644
index 000000000..e788ca5ff
--- /dev/null
+++ b/tests/ui/async-await/multiple-lifetimes/hrtb.rs
@@ -0,0 +1,14 @@
+// edition:2018
+// check-pass
+
+// Test that we can use async fns with multiple arbitrary lifetimes.
+
+use std::ops::Add;
+
+async fn multiple_hrtb_and_single_named_lifetime_ok<'c>(
+ _: impl for<'a> Add<&'a u8>,
+ _: impl for<'b> Add<&'b u8>,
+ _: &'c u8,
+) {}
+
+fn main() {}
diff --git a/tests/ui/async-await/multiple-lifetimes/named.rs b/tests/ui/async-await/multiple-lifetimes/named.rs
new file mode 100644
index 000000000..e8eb98102
--- /dev/null
+++ b/tests/ui/async-await/multiple-lifetimes/named.rs
@@ -0,0 +1,10 @@
+// edition:2018
+// run-pass
+
+// Test that we can use async fns with multiple arbitrary lifetimes.
+
+async fn multiple_named_lifetimes<'a, 'b>(_: &'a u8, _: &'b u8) {}
+
+fn main() {
+ let _ = multiple_named_lifetimes(&22, &44);
+}
diff --git a/tests/ui/async-await/multiple-lifetimes/partial-relation.rs b/tests/ui/async-await/multiple-lifetimes/partial-relation.rs
new file mode 100644
index 000000000..02b105999
--- /dev/null
+++ b/tests/ui/async-await/multiple-lifetimes/partial-relation.rs
@@ -0,0 +1,13 @@
+// edition:2018
+// run-pass
+
+async fn lotsa_lifetimes<'a, 'b, 'c>(a: &'a u32, b: &'b u32, c: &'c u32) -> (&'a u32, &'b u32)
+ where 'b: 'a
+{
+ drop((a, c));
+ (b, b)
+}
+
+fn main() {
+ let _ = lotsa_lifetimes(&22, &44, &66);
+}
diff --git a/tests/ui/async-await/multiple-lifetimes/ret-impl-trait-fg.rs b/tests/ui/async-await/multiple-lifetimes/ret-impl-trait-fg.rs
new file mode 100644
index 000000000..f1002947f
--- /dev/null
+++ b/tests/ui/async-await/multiple-lifetimes/ret-impl-trait-fg.rs
@@ -0,0 +1,17 @@
+// edition:2018
+// run-pass
+
+// Test member constraints that appear in the `impl Trait`
+// return type of an async function.
+// (This used to require a feature gate.)
+
+trait Trait<'a, 'b> { }
+impl<T> Trait<'_, '_> for T { }
+
+async fn async_ret_impl_trait<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a, 'b> {
+ (a, b)
+}
+
+fn main() {
+ let _ = async_ret_impl_trait(&22, &44);
+}
diff --git a/tests/ui/async-await/multiple-lifetimes/ret-impl-trait-one.rs b/tests/ui/async-await/multiple-lifetimes/ret-impl-trait-one.rs
new file mode 100644
index 000000000..aebc77d26
--- /dev/null
+++ b/tests/ui/async-await/multiple-lifetimes/ret-impl-trait-one.rs
@@ -0,0 +1,31 @@
+// edition:2018
+
+// Test that a feature gate is needed to use `impl Trait` as the
+// return type of an async.
+
+trait Trait<'a> { }
+impl<T> Trait<'_> for T { }
+
+// Fails to recognize that both 'a and 'b are mentioned and should thus be accepted
+async fn async_ret_impl_trait3<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> + 'b {
+ //~^ ERROR lifetime may not live long enough
+ (a, b)
+}
+
+// Only `'a` permitted in return type, not `'b`.
+async fn async_ret_impl_trait1<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> {
+ //~^ ERROR captures lifetime that does not appear in bounds
+ (a, b)
+}
+
+// As above, but `'b: 'a`, so return type can be inferred to `(&'a u8,
+// &'a u8)`.
+async fn async_ret_impl_trait2<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a>
+where
+ 'b: 'a,
+{
+ (a, b)
+}
+
+fn main() {
+}
diff --git a/tests/ui/async-await/multiple-lifetimes/ret-impl-trait-one.stderr b/tests/ui/async-await/multiple-lifetimes/ret-impl-trait-one.stderr
new file mode 100644
index 000000000..ae4d0d585
--- /dev/null
+++ b/tests/ui/async-await/multiple-lifetimes/ret-impl-trait-one.stderr
@@ -0,0 +1,35 @@
+error: lifetime may not live long enough
+ --> $DIR/ret-impl-trait-one.rs:10:85
+ |
+LL | async fn async_ret_impl_trait3<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> + 'b {
+ | ________________________________--__--_______________________________________________^
+ | | | |
+ | | | lifetime `'b` defined here
+ | | lifetime `'a` defined here
+LL | |
+LL | | (a, b)
+LL | | }
+ | |_^ 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[E0700]: hidden type for `impl Trait<'a>` captures lifetime that does not appear in bounds
+ --> $DIR/ret-impl-trait-one.rs:16:80
+ |
+LL | async fn async_ret_impl_trait1<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> {
+ | ____________________________________--__________________________________________^
+ | | |
+ | | hidden type `(&'a u8, &'b u8)` captures the lifetime `'b` as defined here
+LL | |
+LL | | (a, b)
+LL | | }
+ | |_^
+ |
+help: to declare that `impl Trait<'a>` captures `'b`, you can add an explicit `'b` lifetime bound
+ |
+LL | async fn async_ret_impl_trait1<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> + 'b {
+ | ++++
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0700`.
diff --git a/tests/ui/async-await/multiple-lifetimes/ret-ref.rs b/tests/ui/async-await/multiple-lifetimes/ret-ref.rs
new file mode 100644
index 000000000..149c020f9
--- /dev/null
+++ b/tests/ui/async-await/multiple-lifetimes/ret-ref.rs
@@ -0,0 +1,44 @@
+// edition:2018
+
+// Test that we get the expected borrow check errors when an async
+// function (which takes multiple lifetimes) only returns data from
+// one of them.
+
+async fn multiple_named_lifetimes<'a, 'b>(a: &'a u8, _: &'b u8) -> &'a u8 {
+ a
+}
+
+// Both are borrowed whilst the future is live.
+async fn future_live() {
+ let mut a = 22;
+ let mut b = 44;
+ let future = multiple_named_lifetimes(&a, &b);
+ a += 1; //~ ERROR cannot assign
+ b += 1; //~ ERROR cannot assign
+ let p = future.await;
+ drop(p);
+}
+
+// Just the return value is live after future is awaited.
+async fn just_return_live() {
+ let mut a = 22;
+ let mut b = 44;
+ let future = multiple_named_lifetimes(&a, &b);
+ let p = future.await;
+ a += 1; //~ ERROR cannot assign
+ b += 1;
+ drop(p);
+}
+
+// Once `p` is dead, both `a` and `b` are unborrowed.
+async fn after_both_dead() {
+ let mut a = 22;
+ let mut b = 44;
+ let future = multiple_named_lifetimes(&a, &b);
+ let p = future.await;
+ drop(p);
+ a += 1;
+ b += 1;
+}
+
+fn main() { }
diff --git a/tests/ui/async-await/multiple-lifetimes/ret-ref.stderr b/tests/ui/async-await/multiple-lifetimes/ret-ref.stderr
new file mode 100644
index 000000000..d86e84033
--- /dev/null
+++ b/tests/ui/async-await/multiple-lifetimes/ret-ref.stderr
@@ -0,0 +1,37 @@
+error[E0506]: cannot assign to `a` because it is borrowed
+ --> $DIR/ret-ref.rs:16:5
+ |
+LL | let future = multiple_named_lifetimes(&a, &b);
+ | -- borrow of `a` occurs here
+LL | a += 1;
+ | ^^^^^^ assignment to borrowed `a` occurs here
+LL | b += 1;
+LL | let p = future.await;
+ | ------ borrow later used here
+
+error[E0506]: cannot assign to `b` because it is borrowed
+ --> $DIR/ret-ref.rs:17:5
+ |
+LL | let future = multiple_named_lifetimes(&a, &b);
+ | -- borrow of `b` occurs here
+LL | a += 1;
+LL | b += 1;
+ | ^^^^^^ assignment to borrowed `b` occurs here
+LL | let p = future.await;
+ | ------ borrow later used here
+
+error[E0506]: cannot assign to `a` because it is borrowed
+ --> $DIR/ret-ref.rs:28:5
+ |
+LL | let future = multiple_named_lifetimes(&a, &b);
+ | -- borrow of `a` occurs here
+LL | let p = future.await;
+LL | a += 1;
+ | ^^^^^^ assignment to borrowed `a` occurs here
+LL | b += 1;
+LL | drop(p);
+ | - borrow later used here
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0506`.
diff --git a/tests/ui/async-await/multiple-lifetimes/variance.rs b/tests/ui/async-await/multiple-lifetimes/variance.rs
new file mode 100644
index 000000000..6ed8bef95
--- /dev/null
+++ b/tests/ui/async-await/multiple-lifetimes/variance.rs
@@ -0,0 +1,15 @@
+// edition:2018
+// run-pass
+
+// Test for async fn where the parameters have distinct lifetime
+// parameters that appear in all possible variances.
+
+async fn lotsa_lifetimes<'a, 'b, 'c>(_: fn(&'a u8), _: fn(&'b u8) -> &'b u8, _: fn() -> &'c u8) { }
+
+fn take_any(_: &u8) { }
+fn identify(x: &u8) -> &u8 { x }
+fn give_back() -> &'static u8 { &22 }
+
+fn main() {
+ let _ = lotsa_lifetimes(take_any, identify, give_back);
+}