Skip to content
Permalink
Browse files

Rollup merge of rust-lang#63383 - Centril:async-lifetime-elision-test…

…s, r=nikomatsakis

`async fn` lifetime elision tests

Add `async fn` version of the tests in rust-lang#61207 per the first checkbox in rust-lang#62121 (comment).
Works towards resolving blockers in rust-lang#63209.

r? @nikomatsakis
cc @cramertj
  • Loading branch information...
Centril committed Aug 13, 2019
2 parents 95d7635 + 5ce8f7a commit 85662a5fb82090b0342c6e47f0fd46d9dfdbaa89
Showing with 2,867 additions and 0 deletions.
  1. +37 −0 src/test/ui/self/arbitrary_self_types_pin_lifetime-async.rs
  2. +14 −0 src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.nll.stderr
  3. +16 −0 src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.rs
  4. +20 −0 src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr
  5. +27 −0 src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.nll.stderr
  6. +28 −0 src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.rs
  7. +88 −0 src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.stderr
  8. +31 −0 src/test/ui/self/elision/README.md
  9. +39 −0 src/test/ui/self/elision/alias-async.rs
  10. +43 −0 src/test/ui/self/elision/assoc-async.rs
  11. +41 −0 src/test/ui/self/elision/lt-alias-async.rs
  12. +53 −0 src/test/ui/self/elision/lt-assoc-async.rs
  13. +51 −0 src/test/ui/self/elision/lt-ref-self-async.nll.stderr
  14. +54 −0 src/test/ui/self/elision/lt-ref-self-async.rs
  15. +159 −0 src/test/ui/self/elision/lt-ref-self-async.stderr
  16. +52 −0 src/test/ui/self/elision/lt-self-async.rs
  17. +39 −0 src/test/ui/self/elision/lt-struct-async.rs
  18. +43 −0 src/test/ui/self/elision/multiple-ref-self-async.nll.stderr
  19. +55 −0 src/test/ui/self/elision/multiple-ref-self-async.rs
  20. +133 −0 src/test/ui/self/elision/multiple-ref-self-async.stderr
  21. +43 −0 src/test/ui/self/elision/ref-alias-async.nll.stderr
  22. +51 −0 src/test/ui/self/elision/ref-alias-async.rs
  23. +133 −0 src/test/ui/self/elision/ref-alias-async.stderr
  24. +43 −0 src/test/ui/self/elision/ref-assoc-async.nll.stderr
  25. +52 −0 src/test/ui/self/elision/ref-assoc-async.rs
  26. +133 −0 src/test/ui/self/elision/ref-assoc-async.stderr
  27. +43 −0 src/test/ui/self/elision/ref-mut-alias-async.nll.stderr
  28. +48 −0 src/test/ui/self/elision/ref-mut-alias-async.rs
  29. +133 −0 src/test/ui/self/elision/ref-mut-alias-async.stderr
  30. +51 −0 src/test/ui/self/elision/ref-mut-self-async.nll.stderr
  31. +54 −0 src/test/ui/self/elision/ref-mut-self-async.rs
  32. +159 −0 src/test/ui/self/elision/ref-mut-self-async.stderr
  33. +43 −0 src/test/ui/self/elision/ref-mut-struct-async.nll.stderr
  34. +46 −0 src/test/ui/self/elision/ref-mut-struct-async.rs
  35. +133 −0 src/test/ui/self/elision/ref-mut-struct-async.stderr
  36. +59 −0 src/test/ui/self/elision/ref-self-async.nll.stderr
  37. +69 −0 src/test/ui/self/elision/ref-self-async.rs
  38. +185 −0 src/test/ui/self/elision/ref-self-async.stderr
  39. +43 −0 src/test/ui/self/elision/ref-struct-async.nll.stderr
  40. +46 −0 src/test/ui/self/elision/ref-struct-async.rs
  41. +133 −0 src/test/ui/self/elision/ref-struct-async.stderr
  42. +39 −0 src/test/ui/self/elision/self-async.rs
  43. +35 −0 src/test/ui/self/elision/struct-async.rs
  44. +11 −0 src/test/ui/self/self_lifetime-async.nll.stderr
  45. +20 −0 src/test/ui/self/self_lifetime-async.rs
  46. +39 −0 src/test/ui/self/self_lifetime-async.stderr
@@ -0,0 +1,37 @@
// check-pass
// edition:2018

#![feature(async_await)]

use std::pin::Pin;
use std::task::{Context, Poll};

struct Foo;

impl Foo {
async fn pin_ref(self: Pin<&Self>) -> Pin<&Self> { self }

async fn pin_mut(self: Pin<&mut Self>) -> Pin<&mut Self> { self }

async fn pin_pin_pin_ref(self: Pin<Pin<Pin<&Self>>>) -> Pin<Pin<Pin<&Self>>> { self }

async fn pin_ref_impl_trait(self: Pin<&Self>) -> impl Clone + '_ { self }

fn b(self: Pin<&Foo>, f: &Foo) -> Pin<&Foo> { self }
}

type Alias<T> = Pin<T>;
impl Foo {
async fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> Alias<&Self> { self }
}

// FIXME(Centril): extend with the rest of the non-`async fn` test
// when we allow `async fn`s inside traits and trait implementations.

fn main() {
let mut foo = Foo;
{ Pin::new(&foo).pin_ref() };
{ Pin::new(&mut foo).pin_mut() };
{ Pin::new(Pin::new(Pin::new(&foo))).pin_pin_pin_ref() };
{ Pin::new(&foo).pin_ref_impl_trait() };
}
@@ -0,0 +1,14 @@
error: lifetime may not live long enough
--> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:10:48
|
LL | async fn f(self: Pin<&Self>) -> impl Clone { self }
| - ^^^^^^^^ returning this value requires that `'_` must outlive `'static`
| |
| lifetime `'_` defined here
help: to allow this `impl Trait` to capture borrowed data with lifetime `'_`, add `'_` as a constraint
|
LL | async fn f(self: Pin<&Self>) -> impl Clone + '_ { self }
| ^^^^^^^^^^^^^^^

error: aborting due to previous error

@@ -0,0 +1,16 @@
// edition:2018

#![feature(async_await)]

use std::pin::Pin;

struct Foo;

impl Foo {
async fn f(self: Pin<&Self>) -> impl Clone { self }
//~^ ERROR cannot infer an appropriate lifetime
}

fn main() {
{ Pin::new(&Foo).f() };
}
@@ -0,0 +1,20 @@
error: cannot infer an appropriate lifetime
--> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:10:16
|
LL | async fn f(self: Pin<&Self>) -> impl Clone { self }
| ^^^^ ---------- this return type evaluates to the `'static` lifetime...
| |
| ...but this borrow...
|
note: ...can't outlive the lifetime '_ as defined on the method body at 10:26
--> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:10:26
|
LL | async fn f(self: Pin<&Self>) -> impl Clone { self }
| ^
help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 10:26
|
LL | async fn f(self: Pin<&Self>) -> impl Clone + '_ { self }
| ^^^^^^^^^^^^^^^

error: aborting due to previous error

@@ -0,0 +1,27 @@
error[E0106]: missing lifetime specifier
--> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:10:45
|
LL | async fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f }
| ^
|
= note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.

error[E0106]: missing lifetime specifier
--> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:15:60
|
LL | async fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) }
| ^
|
= note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.

error[E0106]: missing lifetime specifier
--> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:15:67
|
LL | async fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) }
| ^
|
= note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0106`.
@@ -0,0 +1,28 @@
// edition:2018

#![feature(async_await)]

use std::pin::Pin;

struct Foo;

impl Foo {
async fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f }
//~^ ERROR missing lifetime specifier
//~| ERROR cannot infer an appropriate lifetime
// FIXME: should be E0623?

async fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) }
//~^ ERROR missing lifetime specifier
//~| ERROR cannot infer an appropriate lifetime
//~| ERROR missing lifetime specifier
//~| ERROR cannot infer an appropriate lifetime
// FIXME: should be E0623?
}

type Alias<T> = Pin<T>;
impl Foo {
async fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg } //~ ERROR E0623
}

fn main() {}
@@ -0,0 +1,88 @@
error[E0106]: missing lifetime specifier
--> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:10:45
|
LL | async fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f }
| ^
|
= note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.

error[E0106]: missing lifetime specifier
--> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:15:60
|
LL | async fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) }
| ^
|
= note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.

error[E0106]: missing lifetime specifier
--> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:15:67
|
LL | async fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) }
| ^
|
= note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.

error: cannot infer an appropriate lifetime
--> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:10:33
|
LL | async fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f }
| ^ ---- this return type evaluates to the `'static` lifetime...
| |
| ...but this borrow...
|
note: ...can't outlive the lifetime '_ as defined on the method body at 10:26
--> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:10:26
|
LL | async fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f }
| ^
help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 10:26
|
LL | async fn a(self: Pin<&Foo>, f: &Foo) -> &Foo + '_ { f }
| ^^^^^^^^^

error: cannot infer an appropriate lifetime
--> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:15:16
|
LL | async fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) }
| ^^^^ ...but this borrow... ----------------- this return type evaluates to the `'static` lifetime...
|
note: ...can't outlive the lifetime '_ as defined on the method body at 15:26
--> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:15:26
|
LL | async fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) }
| ^
help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 15:26
|
LL | async fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) + '_ { (self, f) }
| ^^^^^^^^^^^^^^^^^^^^^^

error: cannot infer an appropriate lifetime
--> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:15:34
|
LL | async fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) }
| ^ ----------------- this return type evaluates to the `'static` lifetime...
| |
| ...but this borrow...
|
note: ...can't outlive the lifetime '_ as defined on the method body at 15:26
--> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:15:26
|
LL | async fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) }
| ^
help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 15:26
|
LL | async fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) + '_ { (self, f) }
| ^^^^^^^^^^^^^^^^^^^^^^

error[E0623]: lifetime mismatch
--> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:25:58
|
LL | async fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg }
| ----- ^^^
| | |
| | ...but data from `arg` is returned here
| this parameter and the return type are declared with different lifetimes...

error: aborting due to 7 previous errors

For more information about this error, try `rustc --explain E0106`.
@@ -42,3 +42,34 @@ In each case, we test the following patterns:
- `self: Box<Pin<XXX>>`

In the non-reference cases, `Pin` causes errors so we substitute `Rc`.

### `async fn`

For each of the tests above we also check that `async fn` behaves as an `fn` would.
These tests are in files named `*-async.rs`.

Legends:
- ✓ ⟹ Yes / Pass
- X ⟹ No
- α ⟹ lifetime mismatch
- β ⟹ cannot infer an appropriate lifetime
- γ ⟹ missing lifetime specifier

| `async` file | Pass? | Conforms to `fn`? | How does it diverge? <br/> `fn` ⟶ `async fn` |
| --- | --- | --- | --- |
| `self-async.rs` | ✓ | ✓ | N/A |
| `struct-async.rs`| ✓ | ✓ | N/A |
| `alias-async.rs`| ✓ | ✓ | N/A |
| `assoc-async.rs`| ✓ | ✓ | N/A |
| `ref-self-async.rs` | X | X | α ⟶ β + γ |
| `ref-mut-self-async.rs` | X | X | α ⟶ β + γ |
| `ref-struct-async.rs` | X | X | α ⟶ β + γ |
| `ref-mut-struct-async.rs` | X | X | α ⟶ β + γ |
| `ref-alias-async.rs` | X | X | ✓ ⟶ β + γ |
| `ref-assoc-async.rs` | X | X | ✓ ⟶ β + γ |
| `ref-mut-alias-async.rs` | X | X | ✓ ⟶ β + γ |
| `lt-self-async.rs` | ✓ | ✓ | N/A
| `lt-struct-async.rs` | ✓ | ✓ | N/A
| `lt-alias-async.rs` | ✓ | ✓ | N/A
| `lt-assoc-async.rs` | ✓ | ✓ | N/A
| `lt-ref-self-async.rs` | X | X | α ⟶ β + γ
@@ -0,0 +1,39 @@
// check-pass
// edition:2018

#![feature(async_await)]

#![feature(arbitrary_self_types)]
#![allow(non_snake_case)]

use std::rc::Rc;

struct Struct { }

type Alias = Struct;

impl Struct {
// Test using an alias for `Struct`:

async fn alias(self: Alias, f: &u32) -> &u32 {
f
}

async fn box_Alias(self: Box<Alias>, f: &u32) -> &u32 {
f
}

async fn rc_Alias(self: Rc<Alias>, f: &u32) -> &u32 {
f
}

async fn box_box_Alias(self: Box<Box<Alias>>, f: &u32) -> &u32 {
f
}

async fn box_rc_Alias(self: Box<Rc<Alias>>, f: &u32) -> &u32 {
f
}
}

fn main() { }
@@ -0,0 +1,43 @@
// check-pass
// edition:2018

#![feature(async_await)]

#![feature(arbitrary_self_types)]
#![allow(non_snake_case)]

use std::rc::Rc;

trait Trait {
type AssocType;
}

struct Struct { }

impl Trait for Struct {
type AssocType = Self;
}

impl Struct {
async fn assoc(self: <Struct as Trait>::AssocType, f: &u32) -> &u32 {
f
}

async fn box_AssocType(self: Box<<Struct as Trait>::AssocType>, f: &u32) -> &u32 {
f
}

async fn rc_AssocType(self: Rc<<Struct as Trait>::AssocType>, f: &u32) -> &u32 {
f
}

async fn box_box_AssocType(self: Box<Box<<Struct as Trait>::AssocType>>, f: &u32) -> &u32 {
f
}

async fn box_rc_AssocType(self: Box<Rc<<Struct as Trait>::AssocType>>, f: &u32) -> &u32 {
f
}
}

fn main() { }
@@ -0,0 +1,41 @@
// check-pass
// edition:2018

#![feature(async_await)]

#![feature(arbitrary_self_types)]
#![allow(non_snake_case)]

use std::rc::Rc;

struct Struct<'a> { x: &'a u32 }

type Alias<'a> = Struct<'a>;

impl<'a> Alias<'a> {
async fn take_self(self, f: &u32) -> &u32 {
f
}

async fn take_Alias(self: Alias<'a>, f: &u32) -> &u32 {
f
}

async fn take_Box_Alias(self: Box<Alias<'a>>, f: &u32) -> &u32 {
f
}

async fn take_Box_Box_Alias(self: Box<Box<Alias<'a>>>, f: &u32) -> &u32 {
f
}

async fn take_Rc_Alias(self: Rc<Alias<'a>>, f: &u32) -> &u32 {
f
}

async fn take_Box_Rc_Alias(self: Box<Rc<Alias<'a>>>, f: &u32) -> &u32 {
f
}
}

fn main() { }

0 comments on commit 85662a5

Please sign in to comment.
You can’t perform that action at this time.