introduce more tests covering async fn surface

This commit is contained in:
Niko Matsakis 2019-06-25 10:55:32 -04:00
parent 076b0d0f5c
commit 5bd423a7ca
13 changed files with 239 additions and 4 deletions

View File

@ -0,0 +1,12 @@
// edition:2018
// run-pass
// Test that we can use async fns with multiple arbitrary lifetimes.
#![feature(async_await, await_macro)]
async fn multiple_elided_lifetimes(_: &u8, _: &u8) {}
fn main() {
let _ = multiple_elided_lifetimes(&22, &44);
}

View File

@ -0,0 +1,14 @@
// edition:2018
// run-pass
// Test that we can use async fns with multiple arbitrary lifetimes.
#![feature(arbitrary_self_types, async_await, await_macro)]
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);
}

View File

@ -4,17 +4,14 @@
// Test that we can use async fns with multiple arbitrary lifetimes.
#![feature(arbitrary_self_types, async_await, await_macro)]
#![allow(dead_code)]
use std::ops::Add;
async fn multiple_named_lifetimes<'a, 'b>(_: &'a u8, _: &'b u8) {}
async fn multiple_hrtb_and_single_named_lifetime_ok<'c>(
_: impl for<'a> Add<&'a u8>,
_: impl for<'b> Add<&'b u8>,
_: &'c u8,
) {}
async fn multiple_elided_lifetimes(_: &u8, _: &u8) {}
fn main() {}

View File

@ -0,0 +1,12 @@
// edition:2018
// run-pass
// Test that we can use async fns with multiple arbitrary lifetimes.
#![feature(arbitrary_self_types, async_await, await_macro)]
async fn multiple_named_lifetimes<'a, 'b>(_: &'a u8, _: &'b u8) {}
fn main() {
let _ = multiple_named_lifetimes(&22, &44);
}

View File

@ -0,0 +1,15 @@
// edition:2018
// run-pass
#![feature(async_await)]
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);
}

View File

@ -0,0 +1,18 @@
// edition:2018
// run-pass
// Test that a feature gate is needed to use `impl Trait` as the
// return type of an async.
#![feature(async_await, member_constraints)]
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);
}

View File

@ -0,0 +1,18 @@
// edition:2018
// Test that a feature gate is needed to use `impl Trait` as the
// return type of an async.
#![feature(arbitrary_self_types, async_await, await_macro)]
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> {
//~^ ERROR ambiguous lifetime bound
(a, b)
}
fn main() {
let _ = async_ret_impl_trait(&22, &44);
}

View File

@ -0,0 +1,10 @@
error: ambiguous lifetime bound in `impl Trait`
--> $DIR/ret-impl-trait-no-fg.rs:11:64
|
LL | async fn async_ret_impl_trait<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a, 'b> {
| ^^^^^^^^^^^^^^^^^^ neither `'a` nor `'b` outlives the other
|
= help: add #![feature(member_constraints)] to the crate attributes to enable
error: aborting due to previous error

View File

@ -0,0 +1,27 @@
// edition:2018
// Test that a feature gate is needed to use `impl Trait` as the
// return type of an async.
#![feature(async_await, member_constraints)]
trait Trait<'a> { }
impl<T> Trait<'_> for T { }
// 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 lifetime mismatch
(a, b)
}
// As above, but `'b: 'a`, so return type ca 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() {
}

View File

@ -0,0 +1,11 @@
error[E0623]: lifetime mismatch
--> $DIR/ret-impl-trait-one.rs:12:65
|
LL | async fn async_ret_impl_trait1<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> {
| ------ ^^^^^^^^^^^^^^
| | |
| | ...but data from `b` is returned here
| this parameter and the return type are declared with different lifetimes...
error: aborting due to previous error

View File

@ -0,0 +1,46 @@
// 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.
#![feature(async_await)]
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() { }

View File

@ -0,0 +1,37 @@
error[E0506]: cannot assign to `a` because it is borrowed
--> $DIR/ret-ref.rs:18: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:19: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:30: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`.

View File

@ -0,0 +1,18 @@
// edition:2018
// run-pass
// Test for async fn where the parameters have distinct lifetime
// parameters that appear in all possible variances.
#![feature(arbitrary_self_types, async_await, await_macro)]
#[allow(dead_code)]
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);
}