about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2019-06-28 14:46:45 -0400
committerTaiki Endo <te316e89@gmail.com>2019-07-27 12:28:04 +0900
commit30965689045d71d9335b83c1efb429f1a18a9fa9 (patch)
treefb6588c7d6c78df386e3d5a61cc1fab53fc1fb4b
parent2f64404ba34c525d7fdaa1a5dfdf784cdc2806a1 (diff)
downloadrust-30965689045d71d9335b83c1efb429f1a18a9fa9.tar.gz
rust-30965689045d71d9335b83c1efb429f1a18a9fa9.zip
add a bevy of new test cases
-rw-r--r--src/test/ui/self/elision/README.md45
-rw-r--r--src/test/ui/self/elision/alias.rs32
-rw-r--r--src/test/ui/self/elision/alias.stderr7
-rw-r--r--src/test/ui/self/elision/lt-alias.rs38
-rw-r--r--src/test/ui/self/elision/lt-ref-self.rs38
-rw-r--r--src/test/ui/self/elision/lt-ref-self.stderr62
-rw-r--r--src/test/ui/self/elision/lt-self.rs49
-rw-r--r--src/test/ui/self/elision/lt-struct.rs36
-rw-r--r--src/test/ui/self/elision/ref-alias.rs39
-rw-r--r--src/test/ui/self/elision/ref-mut-alias.rs32
-rw-r--r--src/test/ui/self/elision/ref-mut-alias.stderr7
-rw-r--r--src/test/ui/self/elision/ref-mut-self.rs40
-rw-r--r--src/test/ui/self/elision/ref-mut-self.stderr62
-rw-r--r--src/test/ui/self/elision/ref-mut-struct.rs34
-rw-r--r--src/test/ui/self/elision/ref-mut-struct.stderr52
-rw-r--r--src/test/ui/self/elision/ref-self.rs40
-rw-r--r--src/test/ui/self/elision/ref-self.stderr62
-rw-r--r--src/test/ui/self/elision/ref-struct.rs34
-rw-r--r--src/test/ui/self/elision/ref-struct.stderr52
-rw-r--r--src/test/ui/self/elision/self.rs36
-rw-r--r--src/test/ui/self/elision/struct.rs34
21 files changed, 831 insertions, 0 deletions
diff --git a/src/test/ui/self/elision/README.md b/src/test/ui/self/elision/README.md
new file mode 100644
index 00000000000..de29a9d5e53
--- /dev/null
+++ b/src/test/ui/self/elision/README.md
@@ -0,0 +1,45 @@
+Test cases intended to to document behavior and tryto 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 `&Self` | 100% |
+| `ref-struct.rs` | `Struct` | `&Struct` | take lifetime from `&Self` | 50% |
+| `ref-mut-struct.rs` | `Struct` | `&Struct` | take lifetime from `&Self` | 50% |
+| `ref-alias.rs` | `Struct` | `&Alias` | ignore `Alias` | 0% |
+| `ref-mut-alias.rs` | `Struct` | `&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`.
+
diff --git a/src/test/ui/self/elision/alias.rs b/src/test/ui/self/elision/alias.rs
new file mode 100644
index 00000000000..6f113ec1a4b
--- /dev/null
+++ b/src/test/ui/self/elision/alias.rs
@@ -0,0 +1,32 @@
+#![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`:
+
+    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
+    }
+}
diff --git a/src/test/ui/self/elision/alias.stderr b/src/test/ui/self/elision/alias.stderr
new file mode 100644
index 00000000000..a8f2a125b5e
--- /dev/null
+++ b/src/test/ui/self/elision/alias.stderr
@@ -0,0 +1,7 @@
+error[E0601]: `main` function not found in crate `alias`
+   |
+   = note: consider adding a `main` function to `$DIR/alias.rs`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0601`.
diff --git a/src/test/ui/self/elision/lt-alias.rs b/src/test/ui/self/elision/lt-alias.rs
new file mode 100644
index 00000000000..04468278900
--- /dev/null
+++ b/src/test/ui/self/elision/lt-alias.rs
@@ -0,0 +1,38 @@
+// run-pass
+
+#![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> {
+    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/src/test/ui/self/elision/lt-ref-self.rs b/src/test/ui/self/elision/lt-ref-self.rs
new file mode 100644
index 00000000000..8abf2876a5c
--- /dev/null
+++ b/src/test/ui/self/elision/lt-ref-self.rs
@@ -0,0 +1,38 @@
+#![feature(arbitrary_self_types)]
+#![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 mismatch
+    }
+
+    // Test using `&Self` explicitly:
+
+    fn ref_Self(self: &Self, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+
+    fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+
+    fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+
+    fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+
+    fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+}
+
+fn main() { }
diff --git a/src/test/ui/self/elision/lt-ref-self.stderr b/src/test/ui/self/elision/lt-ref-self.stderr
new file mode 100644
index 00000000000..f73b3eddd38
--- /dev/null
+++ b/src/test/ui/self/elision/lt-ref-self.stderr
@@ -0,0 +1,62 @@
+error[E0623]: lifetime mismatch
+  --> $DIR/lt-ref-self.rs:12:9
+   |
+LL |     fn ref_self(&self, f: &u32) -> &u32 {
+   |                           ----     ----
+   |                           |
+   |                           this parameter and the return type are declared with different lifetimes...
+LL |         f
+   |         ^ ...but data from `f` is returned here
+
+error[E0623]: lifetime mismatch
+  --> $DIR/lt-ref-self.rs:18:9
+   |
+LL |     fn ref_Self(self: &Self, f: &u32) -> &u32 {
+   |                                 ----     ----
+   |                                 |
+   |                                 this parameter and the return type are declared with different lifetimes...
+LL |         f
+   |         ^ ...but data from `f` is returned here
+
+error[E0623]: lifetime mismatch
+  --> $DIR/lt-ref-self.rs:22:9
+   |
+LL |     fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
+   |                                          ----     ----
+   |                                          |
+   |                                          this parameter and the return type are declared with different lifetimes...
+LL |         f
+   |         ^ ...but data from `f` is returned here
+
+error[E0623]: lifetime mismatch
+  --> $DIR/lt-ref-self.rs:26:9
+   |
+LL |     fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
+   |                                          ----     ----
+   |                                          |
+   |                                          this parameter and the return type are declared with different lifetimes...
+LL |         f
+   |         ^ ...but data from `f` is returned here
+
+error[E0623]: lifetime mismatch
+  --> $DIR/lt-ref-self.rs:30:9
+   |
+LL |     fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
+   |                                                   ----     ----
+   |                                                   |
+   |                                                   this parameter and the return type are declared with different lifetimes...
+LL |         f
+   |         ^ ...but data from `f` is returned here
+
+error[E0623]: lifetime mismatch
+  --> $DIR/lt-ref-self.rs:34:9
+   |
+LL |     fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
+   |                                               ----     ----
+   |                                               |
+   |                                               this parameter and the return type are declared with different lifetimes...
+LL |         f
+   |         ^ ...but data from `f` is returned here
+
+error: aborting due to 6 previous errors
+
diff --git a/src/test/ui/self/elision/lt-self.rs b/src/test/ui/self/elision/lt-self.rs
new file mode 100644
index 00000000000..c33df08e0ee
--- /dev/null
+++ b/src/test/ui/self/elision/lt-self.rs
@@ -0,0 +1,49 @@
+// run-pass
+
+#![feature(arbitrary_self_types)]
+#![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/src/test/ui/self/elision/lt-struct.rs b/src/test/ui/self/elision/lt-struct.rs
new file mode 100644
index 00000000000..79ffc8fd6f4
--- /dev/null
+++ b/src/test/ui/self/elision/lt-struct.rs
@@ -0,0 +1,36 @@
+// run-pass
+
+#![feature(arbitrary_self_types)]
+#![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/src/test/ui/self/elision/ref-alias.rs b/src/test/ui/self/elision/ref-alias.rs
new file mode 100644
index 00000000000..23bfe8fb029
--- /dev/null
+++ b/src/test/ui/self/elision/ref-alias.rs
@@ -0,0 +1,39 @@
+// run-pass
+
+#![feature(arbitrary_self_types)]
+#![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/src/test/ui/self/elision/ref-mut-alias.rs b/src/test/ui/self/elision/ref-mut-alias.rs
new file mode 100644
index 00000000000..abb41296576
--- /dev/null
+++ b/src/test/ui/self/elision/ref-mut-alias.rs
@@ -0,0 +1,32 @@
+#![feature(arbitrary_self_types)]
+#![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
+    }
+}
diff --git a/src/test/ui/self/elision/ref-mut-alias.stderr b/src/test/ui/self/elision/ref-mut-alias.stderr
new file mode 100644
index 00000000000..cf202ccaa5d
--- /dev/null
+++ b/src/test/ui/self/elision/ref-mut-alias.stderr
@@ -0,0 +1,7 @@
+error[E0601]: `main` function not found in crate `ref_mut_alias`
+   |
+   = note: consider adding a `main` function to `$DIR/ref-mut-alias.rs`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0601`.
diff --git a/src/test/ui/self/elision/ref-mut-self.rs b/src/test/ui/self/elision/ref-mut-self.rs
new file mode 100644
index 00000000000..6705ca9e305
--- /dev/null
+++ b/src/test/ui/self/elision/ref-mut-self.rs
@@ -0,0 +1,40 @@
+#![feature(arbitrary_self_types)]
+#![allow(non_snake_case)]
+
+use std::pin::Pin;
+
+struct Struct { }
+
+type Alias = Struct;
+
+impl Struct {
+    // Test using `&mut self` sugar:
+
+    fn ref_self(&mut self, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+
+    // Test using `&mut Self` explicitly:
+
+    fn ref_Self(self: &mut Self, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+
+    fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+
+    fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+
+    fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+
+    fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+}
+
+fn main() { }
diff --git a/src/test/ui/self/elision/ref-mut-self.stderr b/src/test/ui/self/elision/ref-mut-self.stderr
new file mode 100644
index 00000000000..05dc5b774c8
--- /dev/null
+++ b/src/test/ui/self/elision/ref-mut-self.stderr
@@ -0,0 +1,62 @@
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-mut-self.rs:14:9
+   |
+LL |     fn ref_self(&mut self, f: &u32) -> &u32 {
+   |                               ----     ----
+   |                               |
+   |                               this parameter and the return type are declared with different lifetimes...
+LL |         f
+   |         ^ ...but data from `f` is returned here
+
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-mut-self.rs:20:9
+   |
+LL |     fn ref_Self(self: &mut Self, f: &u32) -> &u32 {
+   |                                     ----     ----
+   |                                     |
+   |                                     this parameter and the return type are declared with different lifetimes...
+LL |         f
+   |         ^ ...but data from `f` is returned here
+
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-mut-self.rs:24:9
+   |
+LL |     fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 {
+   |                                              ----     ----
+   |                                              |
+   |                                              this parameter and the return type are declared with different lifetimes...
+LL |         f
+   |         ^ ...but data from `f` is returned here
+
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-mut-self.rs:28:9
+   |
+LL |     fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 {
+   |                                              ----     ----
+   |                                              |
+   |                                              this parameter and the return type are declared with different lifetimes...
+LL |         f
+   |         ^ ...but data from `f` is returned here
+
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-mut-self.rs:32:9
+   |
+LL |     fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 {
+   |                                                       ----     ----
+   |                                                       |
+   |                                                       this parameter and the return type are declared with different lifetimes...
+LL |         f
+   |         ^ ...but data from `f` is returned here
+
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-mut-self.rs:36:9
+   |
+LL |     fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 {
+   |                                                       ----     ----
+   |                                                       |
+   |                                                       this parameter and the return type are declared with different lifetimes...
+LL |         f
+   |         ^ ...but data from `f` is returned here
+
+error: aborting due to 6 previous errors
+
diff --git a/src/test/ui/self/elision/ref-mut-struct.rs b/src/test/ui/self/elision/ref-mut-struct.rs
new file mode 100644
index 00000000000..f063728e247
--- /dev/null
+++ b/src/test/ui/self/elision/ref-mut-struct.rs
@@ -0,0 +1,34 @@
+#![feature(arbitrary_self_types)]
+#![allow(non_snake_case)]
+
+use std::pin::Pin;
+
+struct Struct { }
+
+type Alias = Struct;
+
+impl Struct {
+    // Test using `&mut Struct` explicitly:
+
+    fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+
+    fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+
+    fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+
+    fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+
+    fn box_pin_ref_Struct(self: Box<Pin<&mut Struct>>, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+}
+
+fn main() { }
diff --git a/src/test/ui/self/elision/ref-mut-struct.stderr b/src/test/ui/self/elision/ref-mut-struct.stderr
new file mode 100644
index 00000000000..88dfb17892a
--- /dev/null
+++ b/src/test/ui/self/elision/ref-mut-struct.stderr
@@ -0,0 +1,52 @@
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-mut-struct.rs:14:9
+   |
+LL |     fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 {
+   |                                         ----     ----
+   |                                         |
+   |                                         this parameter and the return type are declared with different lifetimes...
+LL |         f
+   |         ^ ...but data from `f` is returned here
+
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-mut-struct.rs:18:9
+   |
+LL |     fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 {
+   |                                                  ----     ----
+   |                                                  |
+   |                                                  this parameter and the return type are declared with different lifetimes...
+LL |         f
+   |         ^ ...but data from `f` is returned here
+
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-mut-struct.rs:22:9
+   |
+LL |     fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 {
+   |                                                  ----     ----
+   |                                                  |
+   |                                                  this parameter and the return type are declared with different lifetimes...
+LL |         f
+   |         ^ ...but data from `f` is returned here
+
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-mut-struct.rs:26:9
+   |
+LL |     fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u32 {
+   |                                                           ----     ----
+   |                                                           |
+   |                                                           this parameter and the return type are declared with different lifetimes...
+LL |         f
+   |         ^ ...but data from `f` is returned here
+
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-mut-struct.rs:30:9
+   |
+LL |     fn box_pin_ref_Struct(self: Box<Pin<&mut Struct>>, f: &u32) -> &u32 {
+   |                                                           ----     ----
+   |                                                           |
+   |                                                           this parameter and the return type are declared with different lifetimes...
+LL |         f
+   |         ^ ...but data from `f` is returned here
+
+error: aborting due to 5 previous errors
+
diff --git a/src/test/ui/self/elision/ref-self.rs b/src/test/ui/self/elision/ref-self.rs
new file mode 100644
index 00000000000..af10e10d311
--- /dev/null
+++ b/src/test/ui/self/elision/ref-self.rs
@@ -0,0 +1,40 @@
+#![feature(arbitrary_self_types)]
+#![allow(non_snake_case)]
+
+use std::pin::Pin;
+
+struct Struct { }
+
+type Alias = Struct;
+
+impl Struct {
+    // Test using `&self` sugar:
+
+    fn ref_self(&self, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+
+    // Test using `&Self` explicitly:
+
+    fn ref_Self(self: &Self, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+
+    fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+
+    fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+
+    fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+
+    fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+}
+
+fn main() { }
diff --git a/src/test/ui/self/elision/ref-self.stderr b/src/test/ui/self/elision/ref-self.stderr
new file mode 100644
index 00000000000..10131cc5935
--- /dev/null
+++ b/src/test/ui/self/elision/ref-self.stderr
@@ -0,0 +1,62 @@
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-self.rs:14:9
+   |
+LL |     fn ref_self(&self, f: &u32) -> &u32 {
+   |                           ----     ----
+   |                           |
+   |                           this parameter and the return type are declared with different lifetimes...
+LL |         f
+   |         ^ ...but data from `f` is returned here
+
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-self.rs:20:9
+   |
+LL |     fn ref_Self(self: &Self, f: &u32) -> &u32 {
+   |                                 ----     ----
+   |                                 |
+   |                                 this parameter and the return type are declared with different lifetimes...
+LL |         f
+   |         ^ ...but data from `f` is returned here
+
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-self.rs:24:9
+   |
+LL |     fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
+   |                                          ----     ----
+   |                                          |
+   |                                          this parameter and the return type are declared with different lifetimes...
+LL |         f
+   |         ^ ...but data from `f` is returned here
+
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-self.rs:28:9
+   |
+LL |     fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
+   |                                          ----     ----
+   |                                          |
+   |                                          this parameter and the return type are declared with different lifetimes...
+LL |         f
+   |         ^ ...but data from `f` is returned here
+
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-self.rs:32:9
+   |
+LL |     fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
+   |                                                   ----     ----
+   |                                                   |
+   |                                                   this parameter and the return type are declared with different lifetimes...
+LL |         f
+   |         ^ ...but data from `f` is returned here
+
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-self.rs:36:9
+   |
+LL |     fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
+   |                                                   ----     ----
+   |                                                   |
+   |                                                   this parameter and the return type are declared with different lifetimes...
+LL |         f
+   |         ^ ...but data from `f` is returned here
+
+error: aborting due to 6 previous errors
+
diff --git a/src/test/ui/self/elision/ref-struct.rs b/src/test/ui/self/elision/ref-struct.rs
new file mode 100644
index 00000000000..28afe17c234
--- /dev/null
+++ b/src/test/ui/self/elision/ref-struct.rs
@@ -0,0 +1,34 @@
+#![feature(arbitrary_self_types)]
+#![allow(non_snake_case)]
+
+use std::pin::Pin;
+
+struct Struct { }
+
+type Alias = Struct;
+
+impl Struct {
+    // Test using `&Struct` explicitly:
+
+    fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+
+    fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+
+    fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+
+    fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+
+    fn box_pin_Struct(self: Box<Pin<&Struct>>, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+}
+
+fn main() { }
diff --git a/src/test/ui/self/elision/ref-struct.stderr b/src/test/ui/self/elision/ref-struct.stderr
new file mode 100644
index 00000000000..8a17ab13d57
--- /dev/null
+++ b/src/test/ui/self/elision/ref-struct.stderr
@@ -0,0 +1,52 @@
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-struct.rs:14:9
+   |
+LL |     fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
+   |                                     ----     ----
+   |                                     |
+   |                                     this parameter and the return type are declared with different lifetimes...
+LL |         f
+   |         ^ ...but data from `f` is returned here
+
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-struct.rs:18:9
+   |
+LL |     fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 {
+   |                                              ----     ----
+   |                                              |
+   |                                              this parameter and the return type are declared with different lifetimes...
+LL |         f
+   |         ^ ...but data from `f` is returned here
+
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-struct.rs:22:9
+   |
+LL |     fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 {
+   |                                              ----     ----
+   |                                              |
+   |                                              this parameter and the return type are declared with different lifetimes...
+LL |         f
+   |         ^ ...but data from `f` is returned here
+
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-struct.rs:26:9
+   |
+LL |     fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 {
+   |                                                       ----     ----
+   |                                                       |
+   |                                                       this parameter and the return type are declared with different lifetimes...
+LL |         f
+   |         ^ ...but data from `f` is returned here
+
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-struct.rs:30:9
+   |
+LL |     fn box_pin_Struct(self: Box<Pin<&Struct>>, f: &u32) -> &u32 {
+   |                                                   ----     ----
+   |                                                   |
+   |                                                   this parameter and the return type are declared with different lifetimes...
+LL |         f
+   |         ^ ...but data from `f` is returned here
+
+error: aborting due to 5 previous errors
+
diff --git a/src/test/ui/self/elision/self.rs b/src/test/ui/self/elision/self.rs
new file mode 100644
index 00000000000..cfd1e79e975
--- /dev/null
+++ b/src/test/ui/self/elision/self.rs
@@ -0,0 +1,36 @@
+// run-pass
+
+#![feature(arbitrary_self_types)]
+#![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/src/test/ui/self/elision/struct.rs b/src/test/ui/self/elision/struct.rs
new file mode 100644
index 00000000000..efdeb121fed
--- /dev/null
+++ b/src/test/ui/self/elision/struct.rs
@@ -0,0 +1,34 @@
+// run-pass
+
+#![feature(arbitrary_self_types)]
+#![allow(non_snake_case)]
+
+use std::rc::Rc;
+
+struct Struct { }
+
+impl Struct {
+    // Test using `&mut Struct` explicitly:
+
+    fn ref_Struct(self: Struct, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+
+    fn box_Struct(self: Box<Struct>, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+
+    fn rc_Struct(self: Rc<Struct>, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+
+    fn box_box_Struct(self: Box<Box<Struct>>, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+
+    fn box_rc_Struct(self: Box<Rc<Struct>>, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+}
+
+fn main() { }