summaryrefslogtreecommitdiffstats
path: root/tests/ui/self/elision
diff options
context:
space:
mode:
Diffstat (limited to 'tests/ui/self/elision')
-rw-r--r--tests/ui/self/elision/README.md75
-rw-r--r--tests/ui/self/elision/alias-async.rs36
-rw-r--r--tests/ui/self/elision/alias.rs35
-rw-r--r--tests/ui/self/elision/assoc-async.rs40
-rw-r--r--tests/ui/self/elision/assoc.rs39
-rw-r--r--tests/ui/self/elision/lt-alias-async.rs38
-rw-r--r--tests/ui/self/elision/lt-alias.rs37
-rw-r--r--tests/ui/self/elision/lt-assoc-async.rs50
-rw-r--r--tests/ui/self/elision/lt-assoc.rs43
-rw-r--r--tests/ui/self/elision/lt-ref-self-async.rs45
-rw-r--r--tests/ui/self/elision/lt-ref-self-async.stderr92
-rw-r--r--tests/ui/self/elision/lt-ref-self.rs43
-rw-r--r--tests/ui/self/elision/lt-ref-self.stderr92
-rw-r--r--tests/ui/self/elision/lt-self-async.rs49
-rw-r--r--tests/ui/self/elision/lt-self.rs48
-rw-r--r--tests/ui/self/elision/lt-struct-async.rs36
-rw-r--r--tests/ui/self/elision/lt-struct.rs35
-rw-r--r--tests/ui/self/elision/multiple-ref-self-async.rs44
-rw-r--r--tests/ui/self/elision/multiple-ref-self.rs43
-rw-r--r--tests/ui/self/elision/ref-alias-async.rs39
-rw-r--r--tests/ui/self/elision/ref-alias.rs38
-rw-r--r--tests/ui/self/elision/ref-assoc-async.rs40
-rw-r--r--tests/ui/self/elision/ref-assoc.rs39
-rw-r--r--tests/ui/self/elision/ref-mut-alias-async.rs36
-rw-r--r--tests/ui/self/elision/ref-mut-alias.rs35
-rw-r--r--tests/ui/self/elision/ref-mut-self-async.rs45
-rw-r--r--tests/ui/self/elision/ref-mut-self-async.stderr92
-rw-r--r--tests/ui/self/elision/ref-mut-self.rs43
-rw-r--r--tests/ui/self/elision/ref-mut-self.stderr92
-rw-r--r--tests/ui/self/elision/ref-mut-struct-async.rs38
-rw-r--r--tests/ui/self/elision/ref-mut-struct-async.stderr77
-rw-r--r--tests/ui/self/elision/ref-mut-struct.rs36
-rw-r--r--tests/ui/self/elision/ref-mut-struct.stderr77
-rw-r--r--tests/ui/self/elision/ref-self-async.rs60
-rw-r--r--tests/ui/self/elision/ref-self-async.stderr107
-rw-r--r--tests/ui/self/elision/ref-self.rs58
-rw-r--r--tests/ui/self/elision/ref-self.stderr107
-rw-r--r--tests/ui/self/elision/ref-struct-async.rs38
-rw-r--r--tests/ui/self/elision/ref-struct-async.stderr77
-rw-r--r--tests/ui/self/elision/ref-struct.rs36
-rw-r--r--tests/ui/self/elision/ref-struct.stderr77
-rw-r--r--tests/ui/self/elision/self-async.rs36
-rw-r--r--tests/ui/self/elision/self.rs35
-rw-r--r--tests/ui/self/elision/struct-async.rs32
-rw-r--r--tests/ui/self/elision/struct.rs31
45 files changed, 2341 insertions, 0 deletions
diff --git a/tests/ui/self/elision/README.md b/tests/ui/self/elision/README.md
new file mode 100644
index 000000000..3bd7a6c00
--- /dev/null
+++ b/tests/ui/self/elision/README.md
@@ -0,0 +1,75 @@
+Test cases intended to document behavior and try to exhaustively
+explore the combinations.
+
+## Confidence
+
+These tests are not yet considered 100% normative, in that some
+aspects of the current behavior are not desirable. This is expressed
+in the "confidence" field in the following table. Values:
+
+| Confidence | Interpretation |
+| --- | --- |
+| 100% | this will remain recommended behavior |
+| 75% | unclear whether we will continue to accept this |
+| 50% | this will likely be deprecated but remain valid |
+| 25% | this could change in the future |
+| 0% | this is definitely bogus and will likely change in the future in *some* way |
+
+## Tests
+
+| Test file | `Self` type | Pattern | Current elision behavior | Confidence |
+| --- | --- | --- | --- | --- |
+| `self.rs` | `Struct` | `Self` | ignore `self` parameter | 100% |
+| `struct.rs` | `Struct` | `Struct` | ignore `self` parameter | 100% |
+| `alias.rs` | `Struct` | `Alias` | ignore `self` parameter | 100% |
+| `ref-self.rs` | `Struct` | `&Self` | take lifetime from `&Self` | 100% |
+| `ref-mut-self.rs` | `Struct` | `&mut Self` | take lifetime from `&mut Self` | 100% |
+| `ref-struct.rs` | `Struct` | `&Struct` | take lifetime from `&Self` | 50% |
+| `ref-mut-struct.rs` | `Struct` | `&mut Struct` | take lifetime from `&mut Self` | 50% |
+| `ref-alias.rs` | `Struct` | `&Alias` | ignore `Alias` | 0% |
+| `ref-mut-alias.rs` | `Struct` | `&mut Alias` | ignore `Alias` | 0% |
+| `lt-self.rs` | `Struct<'a>` | `Self` | ignore `Self` (and hence `'a`) | 25% |
+| `lt-struct.rs` | `Struct<'a>` | `Self` | ignore `Self` (and hence `'a`) | 0% |
+| `lt-alias.rs` | `Alias<'a>` | `Self` | ignore `Self` (and hence `'a`) | 0% |
+| `lt-ref-self.rs` | `Struct<'a>` | `&Self` | take lifetime from `&Self` | 75% |
+
+In each case, we test the following patterns:
+
+- `self: XXX`
+- `self: Box<XXX>`
+- `self: Pin<XXX>`
+- `self: Box<Box<XXX>>`
+- `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 | ✓ | N/A |
+| `ref-mut-self-async.rs` | X | ✓ | N/A |
+| `ref-struct-async.rs` | X | ✓ | N/A |
+| `ref-mut-struct-async.rs` | X | ✓ | N/A |
+| `ref-alias-async.rs` | ✓ | ✓ | N/A |
+| `ref-assoc-async.rs` | ✓ | ✓ | N/A |
+| `ref-mut-alias-async.rs` | ✓ | ✓ | N/A |
+| `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 | ✓ | N/A |
diff --git a/tests/ui/self/elision/alias-async.rs b/tests/ui/self/elision/alias-async.rs
new file mode 100644
index 000000000..7c0dd0686
--- /dev/null
+++ b/tests/ui/self/elision/alias-async.rs
@@ -0,0 +1,36 @@
+// check-pass
+// edition:2018
+
+#![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() { }
diff --git a/tests/ui/self/elision/alias.rs b/tests/ui/self/elision/alias.rs
new file mode 100644
index 000000000..0c801d702
--- /dev/null
+++ b/tests/ui/self/elision/alias.rs
@@ -0,0 +1,35 @@
+// check-pass
+
+#![allow(non_snake_case)]
+
+use std::rc::Rc;
+
+struct Struct { }
+
+type Alias = Struct;
+
+impl Struct {
+ // Test using an alias for `Struct`:
+
+ fn alias(self: Alias, f: &u32) -> &u32 {
+ f
+ }
+
+ fn box_Alias(self: Box<Alias>, f: &u32) -> &u32 {
+ f
+ }
+
+ fn rc_Alias(self: Rc<Alias>, f: &u32) -> &u32 {
+ f
+ }
+
+ fn box_box_Alias(self: Box<Box<Alias>>, f: &u32) -> &u32 {
+ f
+ }
+
+ fn box_rc_Alias(self: Box<Rc<Alias>>, f: &u32) -> &u32 {
+ f
+ }
+}
+
+fn main() { }
diff --git a/tests/ui/self/elision/assoc-async.rs b/tests/ui/self/elision/assoc-async.rs
new file mode 100644
index 000000000..363b7fc2a
--- /dev/null
+++ b/tests/ui/self/elision/assoc-async.rs
@@ -0,0 +1,40 @@
+// check-pass
+// edition:2018
+
+#![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() { }
diff --git a/tests/ui/self/elision/assoc.rs b/tests/ui/self/elision/assoc.rs
new file mode 100644
index 000000000..fa39a2b47
--- /dev/null
+++ b/tests/ui/self/elision/assoc.rs
@@ -0,0 +1,39 @@
+// check-pass
+
+#![allow(non_snake_case)]
+
+use std::rc::Rc;
+
+trait Trait {
+ type AssocType;
+}
+
+struct Struct { }
+
+impl Trait for Struct {
+ type AssocType = Self;
+}
+
+impl Struct {
+ fn assoc(self: <Struct as Trait>::AssocType, f: &u32) -> &u32 {
+ f
+ }
+
+ fn box_AssocType(self: Box<<Struct as Trait>::AssocType>, f: &u32) -> &u32 {
+ f
+ }
+
+ fn rc_AssocType(self: Rc<<Struct as Trait>::AssocType>, f: &u32) -> &u32 {
+ f
+ }
+
+ fn box_box_AssocType(self: Box<Box<<Struct as Trait>::AssocType>>, f: &u32) -> &u32 {
+ f
+ }
+
+ fn box_rc_AssocType(self: Box<Rc<<Struct as Trait>::AssocType>>, f: &u32) -> &u32 {
+ f
+ }
+}
+
+fn main() { }
diff --git a/tests/ui/self/elision/lt-alias-async.rs b/tests/ui/self/elision/lt-alias-async.rs
new file mode 100644
index 000000000..3a6f8471e
--- /dev/null
+++ b/tests/ui/self/elision/lt-alias-async.rs
@@ -0,0 +1,38 @@
+// check-pass
+// edition:2018
+
+#![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() { }
diff --git a/tests/ui/self/elision/lt-alias.rs b/tests/ui/self/elision/lt-alias.rs
new file mode 100644
index 000000000..bbba88e4e
--- /dev/null
+++ b/tests/ui/self/elision/lt-alias.rs
@@ -0,0 +1,37 @@
+// check-pass
+
+#![allow(non_snake_case)]
+
+use std::rc::Rc;
+
+struct Struct<'a> { x: &'a u32 }
+
+type Alias<'a> = Struct<'a>;
+
+impl<'a> Alias<'a> {
+ fn take_self(self, f: &u32) -> &u32 {
+ f
+ }
+
+ fn take_Alias(self: Alias<'a>, f: &u32) -> &u32 {
+ f
+ }
+
+ fn take_Box_Alias(self: Box<Alias<'a>>, f: &u32) -> &u32 {
+ f
+ }
+
+ fn take_Box_Box_Alias(self: Box<Box<Alias<'a>>>, f: &u32) -> &u32 {
+ f
+ }
+
+ fn take_Rc_Alias(self: Rc<Alias<'a>>, f: &u32) -> &u32 {
+ f
+ }
+
+ fn take_Box_Rc_Alias(self: Box<Rc<Alias<'a>>>, f: &u32) -> &u32 {
+ f
+ }
+}
+
+fn main() { }
diff --git a/tests/ui/self/elision/lt-assoc-async.rs b/tests/ui/self/elision/lt-assoc-async.rs
new file mode 100644
index 000000000..0d3ff630d
--- /dev/null
+++ b/tests/ui/self/elision/lt-assoc-async.rs
@@ -0,0 +1,50 @@
+// check-pass
+// edition:2018
+
+#![allow(non_snake_case)]
+
+use std::rc::Rc;
+
+trait Trait {
+ type AssocType;
+}
+
+struct Struct<'a> { x: &'a u32 }
+
+impl<'a> Trait for Struct<'a> {
+ type AssocType = Self;
+}
+
+impl<'a> Struct<'a> {
+ async fn take_self(self, f: &u32) -> &u32 {
+ f
+ }
+
+ async fn take_AssocType(self: <Struct<'a> as Trait>::AssocType, f: &u32) -> &u32 {
+ f
+ }
+
+ async fn take_Box_AssocType(self: Box<<Struct<'a> as Trait>::AssocType>, f: &u32) -> &u32 {
+ f
+ }
+
+ async fn take_Box_Box_AssocType(
+ self: Box<Box<<Struct<'a> as Trait>::AssocType>>,
+ f: &u32
+ ) -> &u32 {
+ f
+ }
+
+ async fn take_Rc_AssocType(self: Rc<<Struct<'a> as Trait>::AssocType>, f: &u32) -> &u32 {
+ f
+ }
+
+ async fn take_Box_Rc_AssocType(
+ self: Box<Rc<<Struct<'a> as Trait>::AssocType>>,
+ f: &u32
+ ) -> &u32 {
+ f
+ }
+}
+
+fn main() { }
diff --git a/tests/ui/self/elision/lt-assoc.rs b/tests/ui/self/elision/lt-assoc.rs
new file mode 100644
index 000000000..8f3543135
--- /dev/null
+++ b/tests/ui/self/elision/lt-assoc.rs
@@ -0,0 +1,43 @@
+// check-pass
+
+#![allow(non_snake_case)]
+
+use std::rc::Rc;
+
+trait Trait {
+ type AssocType;
+}
+
+struct Struct<'a> { x: &'a u32 }
+
+impl<'a> Trait for Struct<'a> {
+ type AssocType = Self;
+}
+
+impl<'a> Struct<'a> {
+ fn take_self(self, f: &u32) -> &u32 {
+ f
+ }
+
+ fn take_AssocType(self: <Struct<'a> as Trait>::AssocType, f: &u32) -> &u32 {
+ f
+ }
+
+ fn take_Box_AssocType(self: Box<<Struct<'a> as Trait>::AssocType>, f: &u32) -> &u32 {
+ f
+ }
+
+ fn take_Box_Box_AssocType(self: Box<Box<<Struct<'a> as Trait>::AssocType>>, f: &u32) -> &u32 {
+ f
+ }
+
+ fn take_Rc_AssocType(self: Rc<<Struct<'a> as Trait>::AssocType>, f: &u32) -> &u32 {
+ f
+ }
+
+ fn take_Box_Rc_AssocType(self: Box<Rc<<Struct<'a> as Trait>::AssocType>>, f: &u32) -> &u32 {
+ f
+ }
+}
+
+fn main() { }
diff --git a/tests/ui/self/elision/lt-ref-self-async.rs b/tests/ui/self/elision/lt-ref-self-async.rs
new file mode 100644
index 000000000..a2325ba7f
--- /dev/null
+++ b/tests/ui/self/elision/lt-ref-self-async.rs
@@ -0,0 +1,45 @@
+// edition:2018
+
+#![allow(non_snake_case)]
+
+use std::pin::Pin;
+
+struct Struct<'a> { data: &'a u32 }
+
+impl<'a> Struct<'a> {
+ // Test using `&self` sugar:
+
+ async fn ref_self(&self, f: &u32) -> &u32 {
+ f
+ //~^ ERROR lifetime may not live long enough
+ }
+
+ // Test using `&Self` explicitly:
+
+ async fn ref_Self(self: &Self, f: &u32) -> &u32 {
+ f
+ //~^ ERROR lifetime may not live long enough
+ }
+
+ async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
+ f
+ //~^ ERROR lifetime may not live long enough
+ }
+
+ async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
+ f
+ //~^ ERROR lifetime may not live long enough
+ }
+
+ async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
+ f
+ //~^ ERROR lifetime may not live long enough
+ }
+
+ async fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
+ f
+ //~^ ERROR lifetime may not live long enough
+ }
+}
+
+fn main() { }
diff --git a/tests/ui/self/elision/lt-ref-self-async.stderr b/tests/ui/self/elision/lt-ref-self-async.stderr
new file mode 100644
index 000000000..787afd4dc
--- /dev/null
+++ b/tests/ui/self/elision/lt-ref-self-async.stderr
@@ -0,0 +1,92 @@
+error: lifetime may not live long enough
+ --> $DIR/lt-ref-self-async.rs:13:9
+ |
+LL | async fn ref_self(&self, f: &u32) -> &u32 {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | f
+ | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+ |
+help: consider introducing a named lifetime parameter and update trait if needed
+ |
+LL | async fn ref_self<'a>(&'a self, f: &'a u32) -> &u32 {
+ | ++++ ++ ++
+
+error: lifetime may not live long enough
+ --> $DIR/lt-ref-self-async.rs:20:9
+ |
+LL | async fn ref_Self(self: &Self, f: &u32) -> &u32 {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | f
+ | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+ |
+help: consider introducing a named lifetime parameter and update trait if needed
+ |
+LL | async fn ref_Self<'a>(self: &'a Self, f: &'a u32) -> &u32 {
+ | ++++ ++ ++
+
+error: lifetime may not live long enough
+ --> $DIR/lt-ref-self-async.rs:25:9
+ |
+LL | async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | f
+ | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+ |
+help: consider introducing a named lifetime parameter and update trait if needed
+ |
+LL | async fn box_ref_Self<'a>(self: Box<&'a Self>, f: &'a u32) -> &u32 {
+ | ++++ ++ ++
+
+error: lifetime may not live long enough
+ --> $DIR/lt-ref-self-async.rs:30:9
+ |
+LL | async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | f
+ | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+ |
+help: consider introducing a named lifetime parameter and update trait if needed
+ |
+LL | async fn pin_ref_Self<'a>(self: Pin<&'a Self>, f: &'a u32) -> &u32 {
+ | ++++ ++ ++
+
+error: lifetime may not live long enough
+ --> $DIR/lt-ref-self-async.rs:35:9
+ |
+LL | async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | f
+ | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+ |
+help: consider introducing a named lifetime parameter and update trait if needed
+ |
+LL | async fn box_box_ref_Self<'a>(self: Box<Box<&'a Self>>, f: &'a u32) -> &u32 {
+ | ++++ ++ ++
+
+error: lifetime may not live long enough
+ --> $DIR/lt-ref-self-async.rs:40:9
+ |
+LL | async fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | f
+ | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+ |
+help: consider introducing a named lifetime parameter and update trait if needed
+ |
+LL | async fn box_pin_Self<'a>(self: Box<Pin<&'a Self>>, f: &'a u32) -> &u32 {
+ | ++++ ++ ++
+
+error: aborting due to 6 previous errors
+
diff --git a/tests/ui/self/elision/lt-ref-self.rs b/tests/ui/self/elision/lt-ref-self.rs
new file mode 100644
index 000000000..d37ed5acb
--- /dev/null
+++ b/tests/ui/self/elision/lt-ref-self.rs
@@ -0,0 +1,43 @@
+#![allow(non_snake_case)]
+
+use std::pin::Pin;
+
+struct Struct<'a> { data: &'a u32 }
+
+impl<'a> Struct<'a> {
+ // Test using `&self` sugar:
+
+ fn ref_self(&self, f: &u32) -> &u32 {
+ f
+ //~^ ERROR lifetime may not live long enough
+ }
+
+ // Test using `&Self` explicitly:
+
+ fn ref_Self(self: &Self, f: &u32) -> &u32 {
+ f
+ //~^ ERROR lifetime may not live long enough
+ }
+
+ fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
+ f
+ //~^ ERROR lifetime may not live long enough
+ }
+
+ fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
+ f
+ //~^ ERROR lifetime may not live long enough
+ }
+
+ fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
+ f
+ //~^ ERROR lifetime may not live long enough
+ }
+
+ fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
+ f
+ //~^ ERROR lifetime may not live long enough
+ }
+}
+
+fn main() { }
diff --git a/tests/ui/self/elision/lt-ref-self.stderr b/tests/ui/self/elision/lt-ref-self.stderr
new file mode 100644
index 000000000..49af638e4
--- /dev/null
+++ b/tests/ui/self/elision/lt-ref-self.stderr
@@ -0,0 +1,92 @@
+error: lifetime may not live long enough
+ --> $DIR/lt-ref-self.rs:11:9
+ |
+LL | fn ref_self(&self, f: &u32) -> &u32 {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | f
+ | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+ |
+help: consider introducing a named lifetime parameter and update trait if needed
+ |
+LL | fn ref_self<'a>(&'a self, f: &'a u32) -> &u32 {
+ | ++++ ++ ++
+
+error: lifetime may not live long enough
+ --> $DIR/lt-ref-self.rs:18:9
+ |
+LL | fn ref_Self(self: &Self, f: &u32) -> &u32 {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | f
+ | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+ |
+help: consider introducing a named lifetime parameter and update trait if needed
+ |
+LL | fn ref_Self<'a>(self: &'a Self, f: &'a u32) -> &u32 {
+ | ++++ ++ ++
+
+error: lifetime may not live long enough
+ --> $DIR/lt-ref-self.rs:23:9
+ |
+LL | fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | f
+ | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+ |
+help: consider introducing a named lifetime parameter and update trait if needed
+ |
+LL | fn box_ref_Self<'a>(self: Box<&'a Self>, f: &'a u32) -> &u32 {
+ | ++++ ++ ++
+
+error: lifetime may not live long enough
+ --> $DIR/lt-ref-self.rs:28:9
+ |
+LL | fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | f
+ | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+ |
+help: consider introducing a named lifetime parameter and update trait if needed
+ |
+LL | fn pin_ref_Self<'a>(self: Pin<&'a Self>, f: &'a u32) -> &u32 {
+ | ++++ ++ ++
+
+error: lifetime may not live long enough
+ --> $DIR/lt-ref-self.rs:33:9
+ |
+LL | fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | f
+ | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+ |
+help: consider introducing a named lifetime parameter and update trait if needed
+ |
+LL | fn box_box_ref_Self<'a>(self: Box<Box<&'a Self>>, f: &'a u32) -> &u32 {
+ | ++++ ++ ++
+
+error: lifetime may not live long enough
+ --> $DIR/lt-ref-self.rs:38:9
+ |
+LL | fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | f
+ | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+ |
+help: consider introducing a named lifetime parameter and update trait if needed
+ |
+LL | fn box_pin_Self<'a>(self: Box<Pin<&'a Self>>, f: &'a u32) -> &u32 {
+ | ++++ ++ ++
+
+error: aborting due to 6 previous errors
+
diff --git a/tests/ui/self/elision/lt-self-async.rs b/tests/ui/self/elision/lt-self-async.rs
new file mode 100644
index 000000000..4cedaf79d
--- /dev/null
+++ b/tests/ui/self/elision/lt-self-async.rs
@@ -0,0 +1,49 @@
+// check-pass
+// edition:2018
+
+#![allow(non_snake_case)]
+
+use std::pin::Pin;
+use std::rc::Rc;
+
+struct Struct<'a> {
+ x: &'a u32
+}
+
+impl<'a> Struct<'a> {
+ async fn take_self(self, f: &u32) -> &u32 {
+ f
+ }
+
+ async fn take_Self(self: Self, f: &u32) -> &u32 {
+ f
+ }
+
+ async fn take_Box_Self(self: Box<Self>, f: &u32) -> &u32 {
+ f
+ }
+
+ async fn take_Box_Box_Self(self: Box<Box<Self>>, f: &u32) -> &u32 {
+ f
+ }
+
+ async fn take_Rc_Self(self: Rc<Self>, f: &u32) -> &u32 {
+ f
+ }
+
+ async fn take_Box_Rc_Self(self: Box<Rc<Self>>, f: &u32) -> &u32 {
+ f
+ }
+
+ // N/A
+ //fn take_Pin_Self(self: Pin<Self>, f: &u32) -> &u32 {
+ // f
+ //}
+
+ // N/A
+ //fn take_Box_Pin_Self(self: Box<Pin<Self>>, f: &u32) -> &u32 {
+ // f
+ //}
+}
+
+fn main() { }
diff --git a/tests/ui/self/elision/lt-self.rs b/tests/ui/self/elision/lt-self.rs
new file mode 100644
index 000000000..cf74f892b
--- /dev/null
+++ b/tests/ui/self/elision/lt-self.rs
@@ -0,0 +1,48 @@
+// check-pass
+
+#![allow(non_snake_case)]
+
+use std::pin::Pin;
+use std::rc::Rc;
+
+struct Struct<'a> {
+ x: &'a u32
+}
+
+impl<'a> Struct<'a> {
+ fn take_self(self, f: &u32) -> &u32 {
+ f
+ }
+
+ fn take_Self(self: Self, f: &u32) -> &u32 {
+ f
+ }
+
+ fn take_Box_Self(self: Box<Self>, f: &u32) -> &u32 {
+ f
+ }
+
+ fn take_Box_Box_Self(self: Box<Box<Self>>, f: &u32) -> &u32 {
+ f
+ }
+
+ fn take_Rc_Self(self: Rc<Self>, f: &u32) -> &u32 {
+ f
+ }
+
+ fn take_Box_Rc_Self(self: Box<Rc<Self>>, f: &u32) -> &u32 {
+ f
+ }
+
+ // N/A
+ //fn take_Pin_Self(self: Pin<Self>, f: &u32) -> &u32 {
+ // f
+ //}
+
+ // N/A
+ //fn take_Box_Pin_Self(self: Box<Pin<Self>>, f: &u32) -> &u32 {
+ // f
+ //}
+}
+
+fn main() { }
diff --git a/tests/ui/self/elision/lt-struct-async.rs b/tests/ui/self/elision/lt-struct-async.rs
new file mode 100644
index 000000000..abbee7fdf
--- /dev/null
+++ b/tests/ui/self/elision/lt-struct-async.rs
@@ -0,0 +1,36 @@
+// check-pass
+// edition:2018
+
+#![allow(non_snake_case)]
+
+use std::rc::Rc;
+
+struct Struct<'a> { x: &'a u32 }
+
+impl<'a> Struct<'a> {
+ async fn take_self(self, f: &u32) -> &u32 {
+ f
+ }
+
+ async fn take_Struct(self: Struct<'a>, f: &u32) -> &u32 {
+ f
+ }
+
+ async fn take_Box_Struct(self: Box<Struct<'a>>, f: &u32) -> &u32 {
+ f
+ }
+
+ async fn take_Box_Box_Struct(self: Box<Box<Struct<'a>>>, f: &u32) -> &u32 {
+ f
+ }
+
+ async fn take_Rc_Struct(self: Rc<Struct<'a>>, f: &u32) -> &u32 {
+ f
+ }
+
+ async fn take_Box_Rc_Struct(self: Box<Rc<Struct<'a>>>, f: &u32) -> &u32 {
+ f
+ }
+}
+
+fn main() { }
diff --git a/tests/ui/self/elision/lt-struct.rs b/tests/ui/self/elision/lt-struct.rs
new file mode 100644
index 000000000..799c6c079
--- /dev/null
+++ b/tests/ui/self/elision/lt-struct.rs
@@ -0,0 +1,35 @@
+// check-pass
+
+#![allow(non_snake_case)]
+
+use std::rc::Rc;
+
+struct Struct<'a> { x: &'a u32 }
+
+impl<'a> Struct<'a> {
+ fn take_self(self, f: &u32) -> &u32 {
+ f
+ }
+
+ fn take_Struct(self: Struct<'a>, f: &u32) -> &u32 {
+ f
+ }
+
+ fn take_Box_Struct(self: Box<Struct<'a>>, f: &u32) -> &u32 {
+ f
+ }
+
+ fn take_Box_Box_Struct(self: Box<Box<Struct<'a>>>, f: &u32) -> &u32 {
+ f
+ }
+
+ fn take_Rc_Struct(self: Rc<Struct<'a>>, f: &u32) -> &u32 {
+ f
+ }
+
+ fn take_Box_Rc_Struct(self: Box<Rc<Struct<'a>>>, f: &u32) -> &u32 {
+ f
+ }
+}
+
+fn main() { }
diff --git a/tests/ui/self/elision/multiple-ref-self-async.rs b/tests/ui/self/elision/multiple-ref-self-async.rs
new file mode 100644
index 000000000..be073c6ed
--- /dev/null
+++ b/tests/ui/self/elision/multiple-ref-self-async.rs
@@ -0,0 +1,44 @@
+// check-pass
+// edition:2018
+
+#![feature(arbitrary_self_types)]
+#![allow(non_snake_case)]
+
+use std::marker::PhantomData;
+use std::ops::Deref;
+use std::pin::Pin;
+
+struct Struct { }
+
+struct Wrap<T, P>(T, PhantomData<P>);
+
+impl<T, P> Deref for Wrap<T, P> {
+ type Target = T;
+ fn deref(&self) -> &T { &self.0 }
+}
+
+impl Struct {
+ // Test using multiple `&Self`:
+
+ async fn wrap_ref_Self_ref_Self(self: Wrap<&Self, &Self>, f: &u8) -> &u8 {
+ f
+ }
+
+ async fn box_wrap_ref_Self_ref_Self(self: Box<Wrap<&Self, &Self>>, f: &u32) -> &u32 {
+ f
+ }
+
+ async fn pin_wrap_ref_Self_ref_Self(self: Pin<Wrap<&Self, &Self>>, f: &u32) -> &u32 {
+ f
+ }
+
+ async fn box_box_wrap_ref_Self_ref_Self(self: Box<Box<Wrap<&Self, &Self>>>, f: &u32) -> &u32 {
+ f
+ }
+
+ async fn box_pin_wrap_ref_Self_ref_Self(self: Box<Pin<Wrap<&Self, &Self>>>, f: &u32) -> &u32 {
+ f
+ }
+}
+
+fn main() { }
diff --git a/tests/ui/self/elision/multiple-ref-self.rs b/tests/ui/self/elision/multiple-ref-self.rs
new file mode 100644
index 000000000..f39613d0c
--- /dev/null
+++ b/tests/ui/self/elision/multiple-ref-self.rs
@@ -0,0 +1,43 @@
+// check-pass
+
+#![feature(arbitrary_self_types)]
+#![allow(non_snake_case)]
+
+use std::marker::PhantomData;
+use std::ops::Deref;
+use std::pin::Pin;
+
+struct Struct { }
+
+struct Wrap<T, P>(T, PhantomData<P>);
+
+impl<T, P> Deref for Wrap<T, P> {
+ type Target = T;
+ fn deref(&self) -> &T { &self.0 }
+}
+
+impl Struct {
+ // Test using multiple `&Self`:
+
+ fn wrap_ref_Self_ref_Self(self: Wrap<&Self, &Self>, f: &u8) -> &u8 {
+ f
+ }
+
+ fn box_wrap_ref_Self_ref_Self(self: Box<Wrap<&Self, &Self>>, f: &u32) -> &u32 {
+ f
+ }
+
+ fn pin_wrap_ref_Self_ref_Self(self: Pin<Wrap<&Self, &Self>>, f: &u32) -> &u32 {
+ f
+ }
+
+ fn box_box_wrap_ref_Self_ref_Self(self: Box<Box<Wrap<&Self, &Self>>>, f: &u32) -> &u32 {
+ f
+ }
+
+ fn box_pin_wrap_ref_Self_ref_Self(self: Box<Pin<Wrap<&Self, &Self>>>, f: &u32) -> &u32 {
+ f
+ }
+}
+
+fn main() { }
diff --git a/tests/ui/self/elision/ref-alias-async.rs b/tests/ui/self/elision/ref-alias-async.rs
new file mode 100644
index 000000000..15f16525b
--- /dev/null
+++ b/tests/ui/self/elision/ref-alias-async.rs
@@ -0,0 +1,39 @@
+// edition:2018
+// check-pass
+
+#![allow(non_snake_case)]
+
+use std::pin::Pin;
+
+struct Struct { }
+
+type Alias = Struct;
+
+impl Struct {
+ // Test using an alias for `Struct`:
+ //
+ // FIXME. We currently fail to recognize this as the self type, which
+ // feels like a bug.
+
+ async fn ref_Alias(self: &Alias, f: &u32) -> &u32 {
+ f
+ }
+
+ async fn box_ref_Alias(self: Box<&Alias>, f: &u32) -> &u32 {
+ f
+ }
+
+ async fn pin_ref_Alias(self: Pin<&Alias>, f: &u32) -> &u32 {
+ f
+ }
+
+ async fn box_box_ref_Alias(self: Box<Box<&Alias>>, f: &u32) -> &u32 {
+ f
+ }
+
+ async fn box_pin_ref_Alias(self: Box<Pin<&Alias>>, f: &u32) -> &u32 {
+ f
+ }
+}
+
+fn main() { }
diff --git a/tests/ui/self/elision/ref-alias.rs b/tests/ui/self/elision/ref-alias.rs
new file mode 100644
index 000000000..341f5b52d
--- /dev/null
+++ b/tests/ui/self/elision/ref-alias.rs
@@ -0,0 +1,38 @@
+// check-pass
+
+#![allow(non_snake_case)]
+
+use std::pin::Pin;
+
+struct Struct { }
+
+type Alias = Struct;
+
+impl Struct {
+ // Test using an alias for `Struct`:
+ //
+ // FIXME. We currently fail to recognize this as the self type, which
+ // feels like a bug.
+
+ fn ref_Alias(self: &Alias, f: &u32) -> &u32 {
+ f
+ }
+
+ fn box_ref_Alias(self: Box<&Alias>, f: &u32) -> &u32 {
+ f
+ }
+
+ fn pin_ref_Alias(self: Pin<&Alias>, f: &u32) -> &u32 {
+ f
+ }
+
+ fn box_box_ref_Alias(self: Box<Box<&Alias>>, f: &u32) -> &u32 {
+ f
+ }
+
+ fn box_pin_ref_Alias(self: Box<Pin<&Alias>>, f: &u32) -> &u32 {
+ f
+ }
+}
+
+fn main() { }
diff --git a/tests/ui/self/elision/ref-assoc-async.rs b/tests/ui/self/elision/ref-assoc-async.rs
new file mode 100644
index 000000000..ad10d8ba4
--- /dev/null
+++ b/tests/ui/self/elision/ref-assoc-async.rs
@@ -0,0 +1,40 @@
+// edition:2018
+// check-pass
+
+#![allow(non_snake_case)]
+
+use std::pin::Pin;
+
+trait Trait {
+ type AssocType;
+}
+
+struct Struct { }
+
+impl Trait for Struct {
+ type AssocType = Self;
+}
+
+impl Struct {
+ async fn ref_AssocType(self: &<Struct as Trait>::AssocType, f: &u32) -> &u32 {
+ f
+ }
+
+ async fn box_ref_AssocType(self: Box<&<Struct as Trait>::AssocType>, f: &u32) -> &u32 {
+ f
+ }
+
+ async fn pin_ref_AssocType(self: Pin<&<Struct as Trait>::AssocType>, f: &u32) -> &u32 {
+ f
+ }
+
+ async fn box_box_ref_AssocType(self: Box<Box<&<Struct as Trait>::AssocType>>, f: &u32) -> &u32 {
+ f
+ }
+
+ async fn box_pin_ref_AssocType(self: Box<Pin<&<Struct as Trait>::AssocType>>, f: &u32) -> &u32 {
+ f
+ }
+}
+
+fn main() { }
diff --git a/tests/ui/self/elision/ref-assoc.rs b/tests/ui/self/elision/ref-assoc.rs
new file mode 100644
index 000000000..2f02cb5f3
--- /dev/null
+++ b/tests/ui/self/elision/ref-assoc.rs
@@ -0,0 +1,39 @@
+// check-pass
+
+#![allow(non_snake_case)]
+
+use std::pin::Pin;
+
+trait Trait {
+ type AssocType;
+}
+
+struct Struct { }
+
+impl Trait for Struct {
+ type AssocType = Self;
+}
+
+impl Struct {
+ fn ref_AssocType(self: &<Struct as Trait>::AssocType, f: &u32) -> &u32 {
+ f
+ }
+
+ fn box_ref_AssocType(self: Box<&<Struct as Trait>::AssocType>, f: &u32) -> &u32 {
+ f
+ }
+
+ fn pin_ref_AssocType(self: Pin<&<Struct as Trait>::AssocType>, f: &u32) -> &u32 {
+ f
+ }
+
+ fn box_box_ref_AssocType(self: Box<Box<&<Struct as Trait>::AssocType>>, f: &u32) -> &u32 {
+ f
+ }
+
+ fn box_pin_ref_AssocType(self: Box<Pin<&<Struct as Trait>::AssocType>>, f: &u32) -> &u32 {
+ f
+ }
+}
+
+fn main() { }
diff --git a/tests/ui/self/elision/ref-mut-alias-async.rs b/tests/ui/self/elision/ref-mut-alias-async.rs
new file mode 100644
index 000000000..2c3f971d2
--- /dev/null
+++ b/tests/ui/self/elision/ref-mut-alias-async.rs
@@ -0,0 +1,36 @@
+// edition:2018
+// check-pass
+
+#![allow(non_snake_case)]
+
+use std::pin::Pin;
+
+struct Struct { }
+
+type Alias = Struct;
+
+impl Struct {
+ // Test using an alias for `Struct`:
+
+ async fn ref_Alias(self: &mut Alias, f: &u32) -> &u32 {
+ f
+ }
+
+ async fn box_ref_Alias(self: Box<&mut Alias>, f: &u32) -> &u32 {
+ f
+ }
+
+ async fn pin_ref_Alias(self: Pin<&mut Alias>, f: &u32) -> &u32 {
+ f
+ }
+
+ async fn box_box_ref_Alias(self: Box<Box<&mut Alias>>, f: &u32) -> &u32 {
+ f
+ }
+
+ async fn box_pin_ref_Alias(self: Box<Pin<&mut Alias>>, f: &u32) -> &u32 {
+ f
+ }
+}
+
+fn main() { }
diff --git a/tests/ui/self/elision/ref-mut-alias.rs b/tests/ui/self/elision/ref-mut-alias.rs
new file mode 100644
index 000000000..ce1ab3ffc
--- /dev/null
+++ b/tests/ui/self/elision/ref-mut-alias.rs
@@ -0,0 +1,35 @@
+// check-pass
+
+#![allow(non_snake_case)]
+
+use std::pin::Pin;
+
+struct Struct { }
+
+type Alias = Struct;
+
+impl Struct {
+ // Test using an alias for `Struct`:
+
+ fn ref_Alias(self: &mut Alias, f: &u32) -> &u32 {
+ f
+ }
+
+ fn box_ref_Alias(self: Box<&mut Alias>, f: &u32) -> &u32 {
+ f
+ }
+
+ fn pin_ref_Alias(self: Pin<&mut Alias>, f: &u32) -> &u32 {
+ f
+ }
+
+ fn box_box_ref_Alias(self: Box<Box<&mut Alias>>, f: &u32) -> &u32 {
+ f
+ }
+
+ fn box_pin_ref_Alias(self: Box<Pin<&mut Alias>>, f: &u32) -> &u32 {
+ f
+ }
+}
+
+fn main() { }
diff --git a/tests/ui/self/elision/ref-mut-self-async.rs b/tests/ui/self/elision/ref-mut-self-async.rs
new file mode 100644
index 000000000..e07bc8564
--- /dev/null
+++ b/tests/ui/self/elision/ref-mut-self-async.rs
@@ -0,0 +1,45 @@
+// edition:2018
+
+#![allow(non_snake_case)]
+
+use std::pin::Pin;
+
+struct Struct { }
+
+impl Struct {
+ // Test using `&mut self` sugar:
+
+ async fn ref_self(&mut self, f: &u32) -> &u32 {
+ f
+ //~^ ERROR lifetime may not live long enough
+ }
+
+ // Test using `&mut Self` explicitly:
+
+ async fn ref_Self(self: &mut Self, f: &u32) -> &u32 {
+ f
+ //~^ ERROR lifetime may not live long enough
+ }
+
+ async fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 {
+ f
+ //~^ ERROR lifetime may not live long enough
+ }
+
+ async fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 {
+ f
+ //~^ ERROR lifetime may not live long enough
+ }
+
+ async fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 {
+ f
+ //~^ ERROR lifetime may not live long enough
+ }
+
+ async fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 {
+ f
+ //~^ ERROR lifetime may not live long enough
+ }
+}
+
+fn main() { }
diff --git a/tests/ui/self/elision/ref-mut-self-async.stderr b/tests/ui/self/elision/ref-mut-self-async.stderr
new file mode 100644
index 000000000..dff50aee9
--- /dev/null
+++ b/tests/ui/self/elision/ref-mut-self-async.stderr
@@ -0,0 +1,92 @@
+error: lifetime may not live long enough
+ --> $DIR/ref-mut-self-async.rs:13:9
+ |
+LL | async fn ref_self(&mut self, f: &u32) -> &u32 {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | f
+ | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+ |
+help: consider introducing a named lifetime parameter and update trait if needed
+ |
+LL | async fn ref_self<'a>(&'a mut self, f: &'a u32) -> &u32 {
+ | ++++ ++ ++
+
+error: lifetime may not live long enough
+ --> $DIR/ref-mut-self-async.rs:20:9
+ |
+LL | async fn ref_Self(self: &mut Self, f: &u32) -> &u32 {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | f
+ | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+ |
+help: consider introducing a named lifetime parameter and update trait if needed
+ |
+LL | async fn ref_Self<'a>(self: &'a mut Self, f: &'a u32) -> &u32 {
+ | ++++ ++ ++
+
+error: lifetime may not live long enough
+ --> $DIR/ref-mut-self-async.rs:25:9
+ |
+LL | async fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | f
+ | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+ |
+help: consider introducing a named lifetime parameter and update trait if needed
+ |
+LL | async fn box_ref_Self<'a>(self: Box<&'a mut Self>, f: &'a u32) -> &u32 {
+ | ++++ ++ ++
+
+error: lifetime may not live long enough
+ --> $DIR/ref-mut-self-async.rs:30:9
+ |
+LL | async fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | f
+ | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+ |
+help: consider introducing a named lifetime parameter and update trait if needed
+ |
+LL | async fn pin_ref_Self<'a>(self: Pin<&'a mut Self>, f: &'a u32) -> &u32 {
+ | ++++ ++ ++
+
+error: lifetime may not live long enough
+ --> $DIR/ref-mut-self-async.rs:35:9
+ |
+LL | async fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | f
+ | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+ |
+help: consider introducing a named lifetime parameter and update trait if needed
+ |
+LL | async fn box_box_ref_Self<'a>(self: Box<Box<&'a mut Self>>, f: &'a u32) -> &u32 {
+ | ++++ ++ ++
+
+error: lifetime may not live long enough
+ --> $DIR/ref-mut-self-async.rs:40:9
+ |
+LL | async fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | f
+ | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+ |
+help: consider introducing a named lifetime parameter and update trait if needed
+ |
+LL | async fn box_pin_ref_Self<'a>(self: Box<Pin<&'a mut Self>>, f: &'a u32) -> &u32 {
+ | ++++ ++ ++
+
+error: aborting due to 6 previous errors
+
diff --git a/tests/ui/self/elision/ref-mut-self.rs b/tests/ui/self/elision/ref-mut-self.rs
new file mode 100644
index 000000000..bb82e6be7
--- /dev/null
+++ b/tests/ui/self/elision/ref-mut-self.rs
@@ -0,0 +1,43 @@
+#![allow(non_snake_case)]
+
+use std::pin::Pin;
+
+struct Struct { }
+
+impl Struct {
+ // Test using `&mut self` sugar:
+
+ fn ref_self(&mut self, f: &u32) -> &u32 {
+ f
+ //~^ ERROR lifetime may not live long enough
+ }
+
+ // Test using `&mut Self` explicitly:
+
+ fn ref_Self(self: &mut Self, f: &u32) -> &u32 {
+ f
+ //~^ ERROR lifetime may not live long enough
+ }
+
+ fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 {
+ f
+ //~^ ERROR lifetime may not live long enough
+ }
+
+ fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 {
+ f
+ //~^ ERROR lifetime may not live long enough
+ }
+
+ fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 {
+ f
+ //~^ ERROR lifetime may not live long enough
+ }
+
+ fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 {
+ f
+ //~^ ERROR lifetime may not live long enough
+ }
+}
+
+fn main() { }
diff --git a/tests/ui/self/elision/ref-mut-self.stderr b/tests/ui/self/elision/ref-mut-self.stderr
new file mode 100644
index 000000000..ccf183016
--- /dev/null
+++ b/tests/ui/self/elision/ref-mut-self.stderr
@@ -0,0 +1,92 @@
+error: lifetime may not live long enough
+ --> $DIR/ref-mut-self.rs:11:9
+ |
+LL | fn ref_self(&mut self, f: &u32) -> &u32 {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | f
+ | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+ |
+help: consider introducing a named lifetime parameter and update trait if needed
+ |
+LL | fn ref_self<'a>(&'a mut self, f: &'a u32) -> &u32 {
+ | ++++ ++ ++
+
+error: lifetime may not live long enough
+ --> $DIR/ref-mut-self.rs:18:9
+ |
+LL | fn ref_Self(self: &mut Self, f: &u32) -> &u32 {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | f
+ | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+ |
+help: consider introducing a named lifetime parameter and update trait if needed
+ |
+LL | fn ref_Self<'a>(self: &'a mut Self, f: &'a u32) -> &u32 {
+ | ++++ ++ ++
+
+error: lifetime may not live long enough
+ --> $DIR/ref-mut-self.rs:23:9
+ |
+LL | fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | f
+ | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+ |
+help: consider introducing a named lifetime parameter and update trait if needed
+ |
+LL | fn box_ref_Self<'a>(self: Box<&'a mut Self>, f: &'a u32) -> &u32 {
+ | ++++ ++ ++
+
+error: lifetime may not live long enough
+ --> $DIR/ref-mut-self.rs:28:9
+ |
+LL | fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | f
+ | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+ |
+help: consider introducing a named lifetime parameter and update trait if needed
+ |
+LL | fn pin_ref_Self<'a>(self: Pin<&'a mut Self>, f: &'a u32) -> &u32 {
+ | ++++ ++ ++
+
+error: lifetime may not live long enough
+ --> $DIR/ref-mut-self.rs:33:9
+ |
+LL | fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | f
+ | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+ |
+help: consider introducing a named lifetime parameter and update trait if needed
+ |
+LL | fn box_box_ref_Self<'a>(self: Box<Box<&'a mut Self>>, f: &'a u32) -> &u32 {
+ | ++++ ++ ++
+
+error: lifetime may not live long enough
+ --> $DIR/ref-mut-self.rs:38:9
+ |
+LL | fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | f
+ | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+ |
+help: consider introducing a named lifetime parameter and update trait if needed
+ |
+LL | fn box_pin_ref_Self<'a>(self: Box<Pin<&'a mut Self>>, f: &'a u32) -> &u32 {
+ | ++++ ++ ++
+
+error: aborting due to 6 previous errors
+
diff --git a/tests/ui/self/elision/ref-mut-struct-async.rs b/tests/ui/self/elision/ref-mut-struct-async.rs
new file mode 100644
index 000000000..392bf1d6b
--- /dev/null
+++ b/tests/ui/self/elision/ref-mut-struct-async.rs
@@ -0,0 +1,38 @@
+// edition:2018
+
+#![allow(non_snake_case)]
+
+use std::pin::Pin;
+
+struct Struct { }
+
+impl Struct {
+ // Test using `&mut Struct` explicitly:
+
+ async fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 {
+ f
+ //~^ ERROR lifetime may not live long enough
+ }
+
+ async fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 {
+ f
+ //~^ ERROR lifetime may not live long enough
+ }
+
+ async fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 {
+ f
+ //~^ ERROR lifetime may not live long enough
+ }
+
+ async fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u32 {
+ f
+ //~^ ERROR lifetime may not live long enough
+ }
+
+ async fn box_pin_ref_Struct(self: Box<Pin<&mut Struct>>, f: &u32) -> &u32 {
+ f
+ //~^ ERROR lifetime may not live long enough
+ }
+}
+
+fn main() { }
diff --git a/tests/ui/self/elision/ref-mut-struct-async.stderr b/tests/ui/self/elision/ref-mut-struct-async.stderr
new file mode 100644
index 000000000..5b7ad026f
--- /dev/null
+++ b/tests/ui/self/elision/ref-mut-struct-async.stderr
@@ -0,0 +1,77 @@
+error: lifetime may not live long enough
+ --> $DIR/ref-mut-struct-async.rs:13:9
+ |
+LL | async fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | f
+ | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+ |
+help: consider introducing a named lifetime parameter and update trait if needed
+ |
+LL | async fn ref_Struct<'a>(self: &'a mut Struct, f: &'a u32) -> &u32 {
+ | ++++ ++ ++
+
+error: lifetime may not live long enough
+ --> $DIR/ref-mut-struct-async.rs:18:9
+ |
+LL | async fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | f
+ | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+ |
+help: consider introducing a named lifetime parameter and update trait if needed
+ |
+LL | async fn box_ref_Struct<'a>(self: Box<&'a mut Struct>, f: &'a u32) -> &u32 {
+ | ++++ ++ ++
+
+error: lifetime may not live long enough
+ --> $DIR/ref-mut-struct-async.rs:23:9
+ |
+LL | async fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | f
+ | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+ |
+help: consider introducing a named lifetime parameter and update trait if needed
+ |
+LL | async fn pin_ref_Struct<'a>(self: Pin<&'a mut Struct>, f: &'a u32) -> &u32 {
+ | ++++ ++ ++
+
+error: lifetime may not live long enough
+ --> $DIR/ref-mut-struct-async.rs:28:9
+ |
+LL | async fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u32 {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | f
+ | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+ |
+help: consider introducing a named lifetime parameter and update trait if needed
+ |
+LL | async fn box_box_ref_Struct<'a>(self: Box<Box<&'a mut Struct>>, f: &'a u32) -> &u32 {
+ | ++++ ++ ++
+
+error: lifetime may not live long enough
+ --> $DIR/ref-mut-struct-async.rs:33:9
+ |
+LL | async fn box_pin_ref_Struct(self: Box<Pin<&mut Struct>>, f: &u32) -> &u32 {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | f
+ | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+ |
+help: consider introducing a named lifetime parameter and update trait if needed
+ |
+LL | async fn box_pin_ref_Struct<'a>(self: Box<Pin<&'a mut Struct>>, f: &'a u32) -> &u32 {
+ | ++++ ++ ++
+
+error: aborting due to 5 previous errors
+
diff --git a/tests/ui/self/elision/ref-mut-struct.rs b/tests/ui/self/elision/ref-mut-struct.rs
new file mode 100644
index 000000000..ca8bd8da1
--- /dev/null
+++ b/tests/ui/self/elision/ref-mut-struct.rs
@@ -0,0 +1,36 @@
+#![allow(non_snake_case)]
+
+use std::pin::Pin;
+
+struct Struct { }
+
+impl Struct {
+ // Test using `&mut Struct` explicitly:
+
+ fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 {
+ f
+ //~^ ERROR lifetime may not live long enough
+ }
+
+ fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 {
+ f
+ //~^ ERROR lifetime may not live long enough
+ }
+
+ fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 {
+ f
+ //~^ ERROR lifetime may not live long enough
+ }
+
+ fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u32 {
+ f
+ //~^ ERROR lifetime may not live long enough
+ }
+
+ fn box_pin_ref_Struct(self: Box<Pin<&mut Struct>>, f: &u32) -> &u32 {
+ f
+ //~^ ERROR lifetime may not live long enough
+ }
+}
+
+fn main() { }
diff --git a/tests/ui/self/elision/ref-mut-struct.stderr b/tests/ui/self/elision/ref-mut-struct.stderr
new file mode 100644
index 000000000..b9c71e843
--- /dev/null
+++ b/tests/ui/self/elision/ref-mut-struct.stderr
@@ -0,0 +1,77 @@
+error: lifetime may not live long enough
+ --> $DIR/ref-mut-struct.rs:11:9
+ |
+LL | fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | f
+ | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+ |
+help: consider introducing a named lifetime parameter and update trait if needed
+ |
+LL | fn ref_Struct<'a>(self: &'a mut Struct, f: &'a u32) -> &u32 {
+ | ++++ ++ ++
+
+error: lifetime may not live long enough
+ --> $DIR/ref-mut-struct.rs:16:9
+ |
+LL | fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | f
+ | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+ |
+help: consider introducing a named lifetime parameter and update trait if needed
+ |
+LL | fn box_ref_Struct<'a>(self: Box<&'a mut Struct>, f: &'a u32) -> &u32 {
+ | ++++ ++ ++
+
+error: lifetime may not live long enough
+ --> $DIR/ref-mut-struct.rs:21:9
+ |
+LL | fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | f
+ | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+ |
+help: consider introducing a named lifetime parameter and update trait if needed
+ |
+LL | fn pin_ref_Struct<'a>(self: Pin<&'a mut Struct>, f: &'a u32) -> &u32 {
+ | ++++ ++ ++
+
+error: lifetime may not live long enough
+ --> $DIR/ref-mut-struct.rs:26:9
+ |
+LL | fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u32 {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | f
+ | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+ |
+help: consider introducing a named lifetime parameter and update trait if needed
+ |
+LL | fn box_box_ref_Struct<'a>(self: Box<Box<&'a mut Struct>>, f: &'a u32) -> &u32 {
+ | ++++ ++ ++
+
+error: lifetime may not live long enough
+ --> $DIR/ref-mut-struct.rs:31:9
+ |
+LL | fn box_pin_ref_Struct(self: Box<Pin<&mut Struct>>, f: &u32) -> &u32 {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | f
+ | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+ |
+help: consider introducing a named lifetime parameter and update trait if needed
+ |
+LL | fn box_pin_ref_Struct<'a>(self: Box<Pin<&'a mut Struct>>, f: &'a u32) -> &u32 {
+ | ++++ ++ ++
+
+error: aborting due to 5 previous errors
+
diff --git a/tests/ui/self/elision/ref-self-async.rs b/tests/ui/self/elision/ref-self-async.rs
new file mode 100644
index 000000000..b0133ec1b
--- /dev/null
+++ b/tests/ui/self/elision/ref-self-async.rs
@@ -0,0 +1,60 @@
+// edition:2018
+
+#![allow(non_snake_case)]
+#![feature(arbitrary_self_types)]
+
+use std::marker::PhantomData;
+use std::ops::Deref;
+use std::pin::Pin;
+
+struct Struct { }
+
+struct Wrap<T, P>(T, PhantomData<P>);
+
+impl<T, P> Deref for Wrap<T, P> {
+ type Target = T;
+ fn deref(&self) -> &T { &self.0 }
+}
+
+impl Struct {
+ // Test using `&self` sugar:
+
+ async fn ref_self(&self, f: &u32) -> &u32 {
+ f
+ //~^ ERROR lifetime may not live long enough
+ }
+
+ // Test using `&Self` explicitly:
+
+ async fn ref_Self(self: &Self, f: &u32) -> &u32 {
+ f
+ //~^ ERROR lifetime may not live long enough
+ }
+
+ async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
+ f
+ //~^ ERROR lifetime may not live long enough
+ }
+
+ async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
+ f
+ //~^ ERROR lifetime may not live long enough
+ }
+
+ async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
+ f
+ //~^ ERROR lifetime may not live long enough
+ }
+
+ async fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
+ f
+ //~^ ERROR lifetime may not live long enough
+ }
+
+ async fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 {
+ f
+ //~^ ERROR lifetime may not live long enough
+ }
+}
+
+fn main() { }
diff --git a/tests/ui/self/elision/ref-self-async.stderr b/tests/ui/self/elision/ref-self-async.stderr
new file mode 100644
index 000000000..26ef9779b
--- /dev/null
+++ b/tests/ui/self/elision/ref-self-async.stderr
@@ -0,0 +1,107 @@
+error: lifetime may not live long enough
+ --> $DIR/ref-self-async.rs:23:9
+ |
+LL | async fn ref_self(&self, f: &u32) -> &u32 {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | f
+ | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+ |
+help: consider introducing a named lifetime parameter and update trait if needed
+ |
+LL | async fn ref_self<'a>(&'a self, f: &'a u32) -> &u32 {
+ | ++++ ++ ++
+
+error: lifetime may not live long enough
+ --> $DIR/ref-self-async.rs:30:9
+ |
+LL | async fn ref_Self(self: &Self, f: &u32) -> &u32 {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | f
+ | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+ |
+help: consider introducing a named lifetime parameter and update trait if needed
+ |
+LL | async fn ref_Self<'a>(self: &'a Self, f: &'a u32) -> &u32 {
+ | ++++ ++ ++
+
+error: lifetime may not live long enough
+ --> $DIR/ref-self-async.rs:35:9
+ |
+LL | async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | f
+ | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+ |
+help: consider introducing a named lifetime parameter and update trait if needed
+ |
+LL | async fn box_ref_Self<'a>(self: Box<&'a Self>, f: &'a u32) -> &u32 {
+ | ++++ ++ ++
+
+error: lifetime may not live long enough
+ --> $DIR/ref-self-async.rs:40:9
+ |
+LL | async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | f
+ | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+ |
+help: consider introducing a named lifetime parameter and update trait if needed
+ |
+LL | async fn pin_ref_Self<'a>(self: Pin<&'a Self>, f: &'a u32) -> &u32 {
+ | ++++ ++ ++
+
+error: lifetime may not live long enough
+ --> $DIR/ref-self-async.rs:45:9
+ |
+LL | async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | f
+ | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+ |
+help: consider introducing a named lifetime parameter and update trait if needed
+ |
+LL | async fn box_box_ref_Self<'a>(self: Box<Box<&'a Self>>, f: &'a u32) -> &u32 {
+ | ++++ ++ ++
+
+error: lifetime may not live long enough
+ --> $DIR/ref-self-async.rs:50:9
+ |
+LL | async fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | f
+ | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+ |
+help: consider introducing a named lifetime parameter and update trait if needed
+ |
+LL | async fn box_pin_ref_Self<'a>(self: Box<Pin<&'a Self>>, f: &'a u32) -> &u32 {
+ | ++++ ++ ++
+
+error: lifetime may not live long enough
+ --> $DIR/ref-self-async.rs:55:9
+ |
+LL | async fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | f
+ | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+ |
+help: consider introducing a named lifetime parameter and update trait if needed
+ |
+LL | async fn wrap_ref_Self_Self<'a>(self: Wrap<&'a Self, Self>, f: &'a u8) -> &u8 {
+ | ++++ ++ ++
+
+error: aborting due to 7 previous errors
+
diff --git a/tests/ui/self/elision/ref-self.rs b/tests/ui/self/elision/ref-self.rs
new file mode 100644
index 000000000..dd07fe1b0
--- /dev/null
+++ b/tests/ui/self/elision/ref-self.rs
@@ -0,0 +1,58 @@
+#![feature(arbitrary_self_types)]
+#![allow(non_snake_case)]
+
+use std::marker::PhantomData;
+use std::ops::Deref;
+use std::pin::Pin;
+
+struct Struct { }
+
+struct Wrap<T, P>(T, PhantomData<P>);
+
+impl<T, P> Deref for Wrap<T, P> {
+ type Target = T;
+ fn deref(&self) -> &T { &self.0 }
+}
+
+impl Struct {
+ // Test using `&self` sugar:
+
+ fn ref_self(&self, f: &u32) -> &u32 {
+ f
+ //~^ ERROR lifetime may not live long enough
+ }
+
+ // Test using `&Self` explicitly:
+
+ fn ref_Self(self: &Self, f: &u32) -> &u32 {
+ f
+ //~^ ERROR lifetime may not live long enough
+ }
+
+ fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
+ f
+ //~^ ERROR lifetime may not live long enough
+ }
+
+ fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
+ f
+ //~^ ERROR lifetime may not live long enough
+ }
+
+ fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
+ f
+ //~^ ERROR lifetime may not live long enough
+ }
+
+ fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
+ f
+ //~^ ERROR lifetime may not live long enough
+ }
+
+ fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 {
+ f
+ //~^ ERROR lifetime may not live long enough
+ }
+}
+
+fn main() { }
diff --git a/tests/ui/self/elision/ref-self.stderr b/tests/ui/self/elision/ref-self.stderr
new file mode 100644
index 000000000..32448f3a6
--- /dev/null
+++ b/tests/ui/self/elision/ref-self.stderr
@@ -0,0 +1,107 @@
+error: lifetime may not live long enough
+ --> $DIR/ref-self.rs:21:9
+ |
+LL | fn ref_self(&self, f: &u32) -> &u32 {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | f
+ | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+ |
+help: consider introducing a named lifetime parameter and update trait if needed
+ |
+LL | fn ref_self<'a>(&'a self, f: &'a u32) -> &u32 {
+ | ++++ ++ ++
+
+error: lifetime may not live long enough
+ --> $DIR/ref-self.rs:28:9
+ |
+LL | fn ref_Self(self: &Self, f: &u32) -> &u32 {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | f
+ | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+ |
+help: consider introducing a named lifetime parameter and update trait if needed
+ |
+LL | fn ref_Self<'a>(self: &'a Self, f: &'a u32) -> &u32 {
+ | ++++ ++ ++
+
+error: lifetime may not live long enough
+ --> $DIR/ref-self.rs:33:9
+ |
+LL | fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | f
+ | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+ |
+help: consider introducing a named lifetime parameter and update trait if needed
+ |
+LL | fn box_ref_Self<'a>(self: Box<&'a Self>, f: &'a u32) -> &u32 {
+ | ++++ ++ ++
+
+error: lifetime may not live long enough
+ --> $DIR/ref-self.rs:38:9
+ |
+LL | fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | f
+ | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+ |
+help: consider introducing a named lifetime parameter and update trait if needed
+ |
+LL | fn pin_ref_Self<'a>(self: Pin<&'a Self>, f: &'a u32) -> &u32 {
+ | ++++ ++ ++
+
+error: lifetime may not live long enough
+ --> $DIR/ref-self.rs:43:9
+ |
+LL | fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | f
+ | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+ |
+help: consider introducing a named lifetime parameter and update trait if needed
+ |
+LL | fn box_box_ref_Self<'a>(self: Box<Box<&'a Self>>, f: &'a u32) -> &u32 {
+ | ++++ ++ ++
+
+error: lifetime may not live long enough
+ --> $DIR/ref-self.rs:48:9
+ |
+LL | fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | f
+ | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+ |
+help: consider introducing a named lifetime parameter and update trait if needed
+ |
+LL | fn box_pin_ref_Self<'a>(self: Box<Pin<&'a Self>>, f: &'a u32) -> &u32 {
+ | ++++ ++ ++
+
+error: lifetime may not live long enough
+ --> $DIR/ref-self.rs:53:9
+ |
+LL | fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | f
+ | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+ |
+help: consider introducing a named lifetime parameter and update trait if needed
+ |
+LL | fn wrap_ref_Self_Self<'a>(self: Wrap<&'a Self, Self>, f: &'a u8) -> &u8 {
+ | ++++ ++ ++
+
+error: aborting due to 7 previous errors
+
diff --git a/tests/ui/self/elision/ref-struct-async.rs b/tests/ui/self/elision/ref-struct-async.rs
new file mode 100644
index 000000000..0be748745
--- /dev/null
+++ b/tests/ui/self/elision/ref-struct-async.rs
@@ -0,0 +1,38 @@
+// edition:2018
+
+#![allow(non_snake_case)]
+
+use std::pin::Pin;
+
+struct Struct { }
+
+impl Struct {
+ // Test using `&Struct` explicitly:
+
+ async fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
+ f
+ //~^ ERROR lifetime may not live long enough
+ }
+
+ async fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 {
+ f
+ //~^ ERROR lifetime may not live long enough
+ }
+
+ async fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 {
+ f
+ //~^ ERROR lifetime may not live long enough
+ }
+
+ async fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 {
+ f
+ //~^ ERROR lifetime may not live long enough
+ }
+
+ async fn box_pin_Struct(self: Box<Pin<&Struct>>, f: &u32) -> &u32 {
+ f
+ //~^ ERROR lifetime may not live long enough
+ }
+}
+
+fn main() { }
diff --git a/tests/ui/self/elision/ref-struct-async.stderr b/tests/ui/self/elision/ref-struct-async.stderr
new file mode 100644
index 000000000..edb5c54ab
--- /dev/null
+++ b/tests/ui/self/elision/ref-struct-async.stderr
@@ -0,0 +1,77 @@
+error: lifetime may not live long enough
+ --> $DIR/ref-struct-async.rs:13:9
+ |
+LL | async fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | f
+ | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+ |
+help: consider introducing a named lifetime parameter and update trait if needed
+ |
+LL | async fn ref_Struct<'a>(self: &'a Struct, f: &'a u32) -> &u32 {
+ | ++++ ++ ++
+
+error: lifetime may not live long enough
+ --> $DIR/ref-struct-async.rs:18:9
+ |
+LL | async fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | f
+ | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+ |
+help: consider introducing a named lifetime parameter and update trait if needed
+ |
+LL | async fn box_ref_Struct<'a>(self: Box<&'a Struct>, f: &'a u32) -> &u32 {
+ | ++++ ++ ++
+
+error: lifetime may not live long enough
+ --> $DIR/ref-struct-async.rs:23:9
+ |
+LL | async fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | f
+ | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+ |
+help: consider introducing a named lifetime parameter and update trait if needed
+ |
+LL | async fn pin_ref_Struct<'a>(self: Pin<&'a Struct>, f: &'a u32) -> &u32 {
+ | ++++ ++ ++
+
+error: lifetime may not live long enough
+ --> $DIR/ref-struct-async.rs:28:9
+ |
+LL | async fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | f
+ | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+ |
+help: consider introducing a named lifetime parameter and update trait if needed
+ |
+LL | async fn box_box_ref_Struct<'a>(self: Box<Box<&'a Struct>>, f: &'a u32) -> &u32 {
+ | ++++ ++ ++
+
+error: lifetime may not live long enough
+ --> $DIR/ref-struct-async.rs:33:9
+ |
+LL | async fn box_pin_Struct(self: Box<Pin<&Struct>>, f: &u32) -> &u32 {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | f
+ | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+ |
+help: consider introducing a named lifetime parameter and update trait if needed
+ |
+LL | async fn box_pin_Struct<'a>(self: Box<Pin<&'a Struct>>, f: &'a u32) -> &u32 {
+ | ++++ ++ ++
+
+error: aborting due to 5 previous errors
+
diff --git a/tests/ui/self/elision/ref-struct.rs b/tests/ui/self/elision/ref-struct.rs
new file mode 100644
index 000000000..13a42cd1a
--- /dev/null
+++ b/tests/ui/self/elision/ref-struct.rs
@@ -0,0 +1,36 @@
+#![allow(non_snake_case)]
+
+use std::pin::Pin;
+
+struct Struct { }
+
+impl Struct {
+ // Test using `&Struct` explicitly:
+
+ fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
+ f
+ //~^ ERROR lifetime may not live long enough
+ }
+
+ fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 {
+ f
+ //~^ ERROR lifetime may not live long enough
+ }
+
+ fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 {
+ f
+ //~^ ERROR lifetime may not live long enough
+ }
+
+ fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 {
+ f
+ //~^ ERROR lifetime may not live long enough
+ }
+
+ fn box_pin_Struct(self: Box<Pin<&Struct>>, f: &u32) -> &u32 {
+ f
+ //~^ ERROR lifetime may not live long enough
+ }
+}
+
+fn main() { }
diff --git a/tests/ui/self/elision/ref-struct.stderr b/tests/ui/self/elision/ref-struct.stderr
new file mode 100644
index 000000000..4492ed4aa
--- /dev/null
+++ b/tests/ui/self/elision/ref-struct.stderr
@@ -0,0 +1,77 @@
+error: lifetime may not live long enough
+ --> $DIR/ref-struct.rs:11:9
+ |
+LL | fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | f
+ | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+ |
+help: consider introducing a named lifetime parameter and update trait if needed
+ |
+LL | fn ref_Struct<'a>(self: &'a Struct, f: &'a u32) -> &u32 {
+ | ++++ ++ ++
+
+error: lifetime may not live long enough
+ --> $DIR/ref-struct.rs:16:9
+ |
+LL | fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | f
+ | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+ |
+help: consider introducing a named lifetime parameter and update trait if needed
+ |
+LL | fn box_ref_Struct<'a>(self: Box<&'a Struct>, f: &'a u32) -> &u32 {
+ | ++++ ++ ++
+
+error: lifetime may not live long enough
+ --> $DIR/ref-struct.rs:21:9
+ |
+LL | fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | f
+ | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+ |
+help: consider introducing a named lifetime parameter and update trait if needed
+ |
+LL | fn pin_ref_Struct<'a>(self: Pin<&'a Struct>, f: &'a u32) -> &u32 {
+ | ++++ ++ ++
+
+error: lifetime may not live long enough
+ --> $DIR/ref-struct.rs:26:9
+ |
+LL | fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | f
+ | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+ |
+help: consider introducing a named lifetime parameter and update trait if needed
+ |
+LL | fn box_box_ref_Struct<'a>(self: Box<Box<&'a Struct>>, f: &'a u32) -> &u32 {
+ | ++++ ++ ++
+
+error: lifetime may not live long enough
+ --> $DIR/ref-struct.rs:31:9
+ |
+LL | fn box_pin_Struct(self: Box<Pin<&Struct>>, f: &u32) -> &u32 {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | f
+ | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+ |
+help: consider introducing a named lifetime parameter and update trait if needed
+ |
+LL | fn box_pin_Struct<'a>(self: Box<Pin<&'a Struct>>, f: &'a u32) -> &u32 {
+ | ++++ ++ ++
+
+error: aborting due to 5 previous errors
+
diff --git a/tests/ui/self/elision/self-async.rs b/tests/ui/self/elision/self-async.rs
new file mode 100644
index 000000000..eb01cfc97
--- /dev/null
+++ b/tests/ui/self/elision/self-async.rs
@@ -0,0 +1,36 @@
+// check-pass
+// edition:2018
+
+#![allow(non_snake_case)]
+
+use std::rc::Rc;
+
+struct Struct { }
+
+impl Struct {
+ async fn take_self(self, f: &u32) -> &u32 {
+ f
+ }
+
+ async fn take_Self(self: Self, f: &u32) -> &u32 {
+ f
+ }
+
+ async fn take_Box_Self(self: Box<Self>, f: &u32) -> &u32 {
+ f
+ }
+
+ async fn take_Box_Box_Self(self: Box<Box<Self>>, f: &u32) -> &u32 {
+ f
+ }
+
+ async fn take_Rc_Self(self: Rc<Self>, f: &u32) -> &u32 {
+ f
+ }
+
+ async fn take_Box_Rc_Self(self: Box<Rc<Self>>, f: &u32) -> &u32 {
+ f
+ }
+}
+
+fn main() { }
diff --git a/tests/ui/self/elision/self.rs b/tests/ui/self/elision/self.rs
new file mode 100644
index 000000000..574b7e7c9
--- /dev/null
+++ b/tests/ui/self/elision/self.rs
@@ -0,0 +1,35 @@
+// check-pass
+
+#![allow(non_snake_case)]
+
+use std::rc::Rc;
+
+struct Struct { }
+
+impl Struct {
+ fn take_self(self, f: &u32) -> &u32 {
+ f
+ }
+
+ fn take_Self(self: Self, f: &u32) -> &u32 {
+ f
+ }
+
+ fn take_Box_Self(self: Box<Self>, f: &u32) -> &u32 {
+ f
+ }
+
+ fn take_Box_Box_Self(self: Box<Box<Self>>, f: &u32) -> &u32 {
+ f
+ }
+
+ fn take_Rc_Self(self: Rc<Self>, f: &u32) -> &u32 {
+ f
+ }
+
+ fn take_Box_Rc_Self(self: Box<Rc<Self>>, f: &u32) -> &u32 {
+ f
+ }
+}
+
+fn main() { }
diff --git a/tests/ui/self/elision/struct-async.rs b/tests/ui/self/elision/struct-async.rs
new file mode 100644
index 000000000..e018e0daf
--- /dev/null
+++ b/tests/ui/self/elision/struct-async.rs
@@ -0,0 +1,32 @@
+// check-pass
+// edition:2018
+
+#![allow(non_snake_case)]
+
+use std::rc::Rc;
+
+struct Struct { }
+
+impl Struct {
+ async fn ref_Struct(self: Struct, f: &u32) -> &u32 {
+ f
+ }
+
+ async fn box_Struct(self: Box<Struct>, f: &u32) -> &u32 {
+ f
+ }
+
+ async fn rc_Struct(self: Rc<Struct>, f: &u32) -> &u32 {
+ f
+ }
+
+ async fn box_box_Struct(self: Box<Box<Struct>>, f: &u32) -> &u32 {
+ f
+ }
+
+ async fn box_rc_Struct(self: Box<Rc<Struct>>, f: &u32) -> &u32 {
+ f
+ }
+}
+
+fn main() { }
diff --git a/tests/ui/self/elision/struct.rs b/tests/ui/self/elision/struct.rs
new file mode 100644
index 000000000..d1ac99d13
--- /dev/null
+++ b/tests/ui/self/elision/struct.rs
@@ -0,0 +1,31 @@
+// check-pass
+
+#![allow(non_snake_case)]
+
+use std::rc::Rc;
+
+struct Struct { }
+
+impl Struct {
+ fn ref_Struct(self: Struct, f: &u32) -> &u32 {
+ f
+ }
+
+ fn box_Struct(self: Box<Struct>, f: &u32) -> &u32 {
+ f
+ }
+
+ fn rc_Struct(self: Rc<Struct>, f: &u32) -> &u32 {
+ f
+ }
+
+ fn box_box_Struct(self: Box<Box<Struct>>, f: &u32) -> &u32 {
+ f
+ }
+
+ fn box_rc_Struct(self: Box<Rc<Struct>>, f: &u32) -> &u32 {
+ f
+ }
+}
+
+fn main() { }