From 43a2cbdfd33b02be90ab1616e1b706142fa5d498 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Thu, 8 Aug 2019 15:06:26 +0200
Subject: [PATCH 1/5] lifetime elision: add conforming-to-fn tests.

---
 src/test/ui/self/elision/alias-async.rs     | 39 +++++++++++++++
 src/test/ui/self/elision/assoc-async.rs     | 43 +++++++++++++++++
 src/test/ui/self/elision/lt-alias-async.rs  | 41 ++++++++++++++++
 src/test/ui/self/elision/lt-assoc-async.rs  | 53 +++++++++++++++++++++
 src/test/ui/self/elision/lt-self-async.rs   | 52 ++++++++++++++++++++
 src/test/ui/self/elision/lt-struct-async.rs | 39 +++++++++++++++
 src/test/ui/self/elision/self-async.rs      | 39 +++++++++++++++
 src/test/ui/self/elision/struct-async.rs    | 35 ++++++++++++++
 8 files changed, 341 insertions(+)
 create mode 100644 src/test/ui/self/elision/alias-async.rs
 create mode 100644 src/test/ui/self/elision/assoc-async.rs
 create mode 100644 src/test/ui/self/elision/lt-alias-async.rs
 create mode 100644 src/test/ui/self/elision/lt-assoc-async.rs
 create mode 100644 src/test/ui/self/elision/lt-self-async.rs
 create mode 100644 src/test/ui/self/elision/lt-struct-async.rs
 create mode 100644 src/test/ui/self/elision/self-async.rs
 create mode 100644 src/test/ui/self/elision/struct-async.rs

diff --git a/src/test/ui/self/elision/alias-async.rs b/src/test/ui/self/elision/alias-async.rs
new file mode 100644
index 0000000000000..3d5b24a8946aa
--- /dev/null
+++ b/src/test/ui/self/elision/alias-async.rs
@@ -0,0 +1,39 @@
+// check-pass
+// edition:2018
+
+#![feature(async_await)]
+
+#![feature(arbitrary_self_types)]
+#![allow(non_snake_case)]
+
+use std::rc::Rc;
+
+struct Struct { }
+
+type Alias = Struct;
+
+impl Struct {
+    // Test using an alias for `Struct`:
+
+    async fn alias(self: Alias, f: &u32) -> &u32 {
+        f
+    }
+
+    async fn box_Alias(self: Box<Alias>, f: &u32) -> &u32 {
+        f
+    }
+
+    async fn rc_Alias(self: Rc<Alias>, f: &u32) -> &u32 {
+        f
+    }
+
+    async fn box_box_Alias(self: Box<Box<Alias>>, f: &u32) -> &u32 {
+        f
+    }
+
+    async fn box_rc_Alias(self: Box<Rc<Alias>>, f: &u32) -> &u32 {
+        f
+    }
+}
+
+fn main() { }
diff --git a/src/test/ui/self/elision/assoc-async.rs b/src/test/ui/self/elision/assoc-async.rs
new file mode 100644
index 0000000000000..0f33f2887726c
--- /dev/null
+++ b/src/test/ui/self/elision/assoc-async.rs
@@ -0,0 +1,43 @@
+// check-pass
+// edition:2018
+
+#![feature(async_await)]
+
+#![feature(arbitrary_self_types)]
+#![allow(non_snake_case)]
+
+use std::rc::Rc;
+
+trait Trait {
+    type AssocType;
+}
+
+struct Struct { }
+
+impl Trait for Struct {
+    type AssocType = Self;
+}
+
+impl Struct {
+    async fn assoc(self: <Struct as Trait>::AssocType, f: &u32) -> &u32 {
+        f
+    }
+
+    async fn box_AssocType(self: Box<<Struct as Trait>::AssocType>, f: &u32) -> &u32 {
+        f
+    }
+
+    async fn rc_AssocType(self: Rc<<Struct as Trait>::AssocType>, f: &u32) -> &u32 {
+        f
+    }
+
+    async fn box_box_AssocType(self: Box<Box<<Struct as Trait>::AssocType>>, f: &u32) -> &u32 {
+        f
+    }
+
+    async fn box_rc_AssocType(self: Box<Rc<<Struct as Trait>::AssocType>>, f: &u32) -> &u32 {
+        f
+    }
+}
+
+fn main() { }
diff --git a/src/test/ui/self/elision/lt-alias-async.rs b/src/test/ui/self/elision/lt-alias-async.rs
new file mode 100644
index 0000000000000..5a8989f078ef3
--- /dev/null
+++ b/src/test/ui/self/elision/lt-alias-async.rs
@@ -0,0 +1,41 @@
+// check-pass
+// edition:2018
+
+#![feature(async_await)]
+
+#![feature(arbitrary_self_types)]
+#![allow(non_snake_case)]
+
+use std::rc::Rc;
+
+struct Struct<'a> { x: &'a u32 }
+
+type Alias<'a> = Struct<'a>;
+
+impl<'a> Alias<'a> {
+    async fn take_self(self, f: &u32) -> &u32 {
+        f
+    }
+
+    async fn take_Alias(self: Alias<'a>, f: &u32) -> &u32 {
+        f
+    }
+
+    async fn take_Box_Alias(self: Box<Alias<'a>>, f: &u32) -> &u32 {
+        f
+    }
+
+    async fn take_Box_Box_Alias(self: Box<Box<Alias<'a>>>, f: &u32) -> &u32 {
+        f
+    }
+
+    async fn take_Rc_Alias(self: Rc<Alias<'a>>, f: &u32) -> &u32 {
+        f
+    }
+
+    async fn take_Box_Rc_Alias(self: Box<Rc<Alias<'a>>>, f: &u32) -> &u32 {
+        f
+    }
+}
+
+fn main() { }
diff --git a/src/test/ui/self/elision/lt-assoc-async.rs b/src/test/ui/self/elision/lt-assoc-async.rs
new file mode 100644
index 0000000000000..98c9aa3b6c26a
--- /dev/null
+++ b/src/test/ui/self/elision/lt-assoc-async.rs
@@ -0,0 +1,53 @@
+// check-pass
+// edition:2018
+
+#![feature(async_await)]
+
+#![feature(arbitrary_self_types)]
+#![allow(non_snake_case)]
+
+use std::rc::Rc;
+
+trait Trait {
+    type AssocType;
+}
+
+struct Struct<'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/src/test/ui/self/elision/lt-self-async.rs b/src/test/ui/self/elision/lt-self-async.rs
new file mode 100644
index 0000000000000..0202db8a63526
--- /dev/null
+++ b/src/test/ui/self/elision/lt-self-async.rs
@@ -0,0 +1,52 @@
+// check-pass
+// edition:2018
+
+#![feature(async_await)]
+
+#![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> {
+    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/src/test/ui/self/elision/lt-struct-async.rs b/src/test/ui/self/elision/lt-struct-async.rs
new file mode 100644
index 0000000000000..c0fc63d423257
--- /dev/null
+++ b/src/test/ui/self/elision/lt-struct-async.rs
@@ -0,0 +1,39 @@
+// check-pass
+// edition:2018
+
+#![feature(async_await)]
+
+#![feature(arbitrary_self_types)]
+#![allow(non_snake_case)]
+
+use std::rc::Rc;
+
+struct Struct<'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/src/test/ui/self/elision/self-async.rs b/src/test/ui/self/elision/self-async.rs
new file mode 100644
index 0000000000000..d1dc050be0d1e
--- /dev/null
+++ b/src/test/ui/self/elision/self-async.rs
@@ -0,0 +1,39 @@
+// check-pass
+// edition:2018
+
+#![feature(async_await)]
+
+#![feature(arbitrary_self_types)]
+#![allow(non_snake_case)]
+
+use std::rc::Rc;
+
+struct Struct { }
+
+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/src/test/ui/self/elision/struct-async.rs b/src/test/ui/self/elision/struct-async.rs
new file mode 100644
index 0000000000000..f7c8591ebd31d
--- /dev/null
+++ b/src/test/ui/self/elision/struct-async.rs
@@ -0,0 +1,35 @@
+// check-pass
+// edition:2018
+
+#![feature(async_await)]
+
+#![feature(arbitrary_self_types)]
+#![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() { }

From a69478242d152558a9fd60c8d1c4a20cc530a081 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Thu, 8 Aug 2019 15:57:32 +0200
Subject: [PATCH 2/5] lifetime elision: add non-conforming-to-fn tests.

---
 .../self/elision/lt-ref-self-async.nll.stderr |  51 +++++
 src/test/ui/self/elision/lt-ref-self-async.rs |  54 +++++
 .../ui/self/elision/lt-ref-self-async.stderr  | 159 +++++++++++++++
 .../multiple-ref-self-async.nll.stderr        |  43 ++++
 .../self/elision/multiple-ref-self-async.rs   |  55 ++++++
 .../elision/multiple-ref-self-async.stderr    | 133 +++++++++++++
 .../self/elision/ref-alias-async.nll.stderr   |  43 ++++
 src/test/ui/self/elision/ref-alias-async.rs   |  51 +++++
 .../ui/self/elision/ref-alias-async.stderr    | 133 +++++++++++++
 .../self/elision/ref-assoc-async.nll.stderr   |  43 ++++
 src/test/ui/self/elision/ref-assoc-async.rs   |  52 +++++
 .../ui/self/elision/ref-assoc-async.stderr    | 133 +++++++++++++
 .../elision/ref-mut-alias-async.nll.stderr    |  43 ++++
 .../ui/self/elision/ref-mut-alias-async.rs    |  48 +++++
 .../self/elision/ref-mut-alias-async.stderr   | 133 +++++++++++++
 .../elision/ref-mut-self-async.nll.stderr     |  51 +++++
 .../ui/self/elision/ref-mut-self-async.rs     |  54 +++++
 .../ui/self/elision/ref-mut-self-async.stderr | 159 +++++++++++++++
 .../elision/ref-mut-struct-async.nll.stderr   |  43 ++++
 .../ui/self/elision/ref-mut-struct-async.rs   |  46 +++++
 .../self/elision/ref-mut-struct-async.stderr  | 133 +++++++++++++
 .../ui/self/elision/ref-self-async.nll.stderr |  59 ++++++
 src/test/ui/self/elision/ref-self-async.rs    |  69 +++++++
 .../ui/self/elision/ref-self-async.stderr     | 185 ++++++++++++++++++
 .../self/elision/ref-struct-async.nll.stderr  |  43 ++++
 src/test/ui/self/elision/ref-struct-async.rs  |  46 +++++
 .../ui/self/elision/ref-struct-async.stderr   | 133 +++++++++++++
 27 files changed, 2195 insertions(+)
 create mode 100644 src/test/ui/self/elision/lt-ref-self-async.nll.stderr
 create mode 100644 src/test/ui/self/elision/lt-ref-self-async.rs
 create mode 100644 src/test/ui/self/elision/lt-ref-self-async.stderr
 create mode 100644 src/test/ui/self/elision/multiple-ref-self-async.nll.stderr
 create mode 100644 src/test/ui/self/elision/multiple-ref-self-async.rs
 create mode 100644 src/test/ui/self/elision/multiple-ref-self-async.stderr
 create mode 100644 src/test/ui/self/elision/ref-alias-async.nll.stderr
 create mode 100644 src/test/ui/self/elision/ref-alias-async.rs
 create mode 100644 src/test/ui/self/elision/ref-alias-async.stderr
 create mode 100644 src/test/ui/self/elision/ref-assoc-async.nll.stderr
 create mode 100644 src/test/ui/self/elision/ref-assoc-async.rs
 create mode 100644 src/test/ui/self/elision/ref-assoc-async.stderr
 create mode 100644 src/test/ui/self/elision/ref-mut-alias-async.nll.stderr
 create mode 100644 src/test/ui/self/elision/ref-mut-alias-async.rs
 create mode 100644 src/test/ui/self/elision/ref-mut-alias-async.stderr
 create mode 100644 src/test/ui/self/elision/ref-mut-self-async.nll.stderr
 create mode 100644 src/test/ui/self/elision/ref-mut-self-async.rs
 create mode 100644 src/test/ui/self/elision/ref-mut-self-async.stderr
 create mode 100644 src/test/ui/self/elision/ref-mut-struct-async.nll.stderr
 create mode 100644 src/test/ui/self/elision/ref-mut-struct-async.rs
 create mode 100644 src/test/ui/self/elision/ref-mut-struct-async.stderr
 create mode 100644 src/test/ui/self/elision/ref-self-async.nll.stderr
 create mode 100644 src/test/ui/self/elision/ref-self-async.rs
 create mode 100644 src/test/ui/self/elision/ref-self-async.stderr
 create mode 100644 src/test/ui/self/elision/ref-struct-async.nll.stderr
 create mode 100644 src/test/ui/self/elision/ref-struct-async.rs
 create mode 100644 src/test/ui/self/elision/ref-struct-async.stderr

diff --git a/src/test/ui/self/elision/lt-ref-self-async.nll.stderr b/src/test/ui/self/elision/lt-ref-self-async.nll.stderr
new file mode 100644
index 0000000000000..d3aeb73b9b7c2
--- /dev/null
+++ b/src/test/ui/self/elision/lt-ref-self-async.nll.stderr
@@ -0,0 +1,51 @@
+error[E0106]: missing lifetime specifier
+  --> $DIR/lt-ref-self-async.rs:15:42
+   |
+LL |     async fn ref_self(&self, f: &u32) -> &u32 {
+   |                                          ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/lt-ref-self-async.rs:23:48
+   |
+LL |     async fn ref_Self(self: &Self, f: &u32) -> &u32 {
+   |                                                ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/lt-ref-self-async.rs:29:57
+   |
+LL |     async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
+   |                                                         ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/lt-ref-self-async.rs:35:57
+   |
+LL |     async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
+   |                                                         ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/lt-ref-self-async.rs:41:66
+   |
+LL |     async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
+   |                                                                  ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/lt-ref-self-async.rs:47:62
+   |
+LL |     async fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
+   |                                                              ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0106`.
diff --git a/src/test/ui/self/elision/lt-ref-self-async.rs b/src/test/ui/self/elision/lt-ref-self-async.rs
new file mode 100644
index 0000000000000..84b91ba08b75d
--- /dev/null
+++ b/src/test/ui/self/elision/lt-ref-self-async.rs
@@ -0,0 +1,54 @@
+// edition:2018
+
+#![feature(async_await)]
+
+#![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:
+
+    async fn ref_self(&self, f: &u32) -> &u32 {
+        //~^ ERROR cannot infer an appropriate lifetime
+        //~| ERROR missing lifetime specifier
+        f
+    }
+
+    // Test using `&Self` explicitly:
+
+    async fn ref_Self(self: &Self, f: &u32) -> &u32 {
+        //~^ ERROR cannot infer an appropriate lifetime
+        //~| ERROR missing lifetime specifier
+        f
+    }
+
+    async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
+        //~^ ERROR cannot infer an appropriate lifetime
+        //~| ERROR missing lifetime specifier
+        f
+    }
+
+    async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
+        //~^ ERROR cannot infer an appropriate lifetime
+        //~| ERROR missing lifetime specifier
+        f
+    }
+
+    async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
+        //~^ ERROR cannot infer an appropriate lifetime
+        //~| ERROR missing lifetime specifier
+        f
+    }
+
+    async fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
+        //~^ ERROR cannot infer an appropriate lifetime
+        //~| ERROR missing lifetime specifier
+        f
+    }
+}
+
+fn main() { }
diff --git a/src/test/ui/self/elision/lt-ref-self-async.stderr b/src/test/ui/self/elision/lt-ref-self-async.stderr
new file mode 100644
index 0000000000000..56595d008a6bf
--- /dev/null
+++ b/src/test/ui/self/elision/lt-ref-self-async.stderr
@@ -0,0 +1,159 @@
+error[E0106]: missing lifetime specifier
+  --> $DIR/lt-ref-self-async.rs:15:42
+   |
+LL |     async fn ref_self(&self, f: &u32) -> &u32 {
+   |                                          ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/lt-ref-self-async.rs:23:48
+   |
+LL |     async fn ref_Self(self: &Self, f: &u32) -> &u32 {
+   |                                                ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/lt-ref-self-async.rs:29:57
+   |
+LL |     async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
+   |                                                         ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/lt-ref-self-async.rs:35:57
+   |
+LL |     async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
+   |                                                         ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/lt-ref-self-async.rs:41:66
+   |
+LL |     async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
+   |                                                                  ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/lt-ref-self-async.rs:47:62
+   |
+LL |     async fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
+   |                                                              ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error: cannot infer an appropriate lifetime
+  --> $DIR/lt-ref-self-async.rs:15:30
+   |
+LL |     async fn ref_self(&self, f: &u32) -> &u32 {
+   |                              ^           ---- this return type evaluates to the `'static` lifetime...
+   |                              |
+   |                              ...but this borrow...
+   |
+note: ...can't outlive the lifetime '_ as defined on the method body at 15:23
+  --> $DIR/lt-ref-self-async.rs:15:23
+   |
+LL |     async fn ref_self(&self, f: &u32) -> &u32 {
+   |                       ^
+help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 15:23
+   |
+LL |     async fn ref_self(&self, f: &u32) -> &u32 + '_ {
+   |                                          ^^^^^^^^^
+
+error: cannot infer an appropriate lifetime
+  --> $DIR/lt-ref-self-async.rs:23:36
+   |
+LL |     async fn ref_Self(self: &Self, f: &u32) -> &u32 {
+   |                                    ^           ---- this return type evaluates to the `'static` lifetime...
+   |                                    |
+   |                                    ...but this borrow...
+   |
+note: ...can't outlive the lifetime '_ as defined on the method body at 23:29
+  --> $DIR/lt-ref-self-async.rs:23:29
+   |
+LL |     async fn ref_Self(self: &Self, f: &u32) -> &u32 {
+   |                             ^
+help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 23:29
+   |
+LL |     async fn ref_Self(self: &Self, f: &u32) -> &u32 + '_ {
+   |                                                ^^^^^^^^^
+
+error: cannot infer an appropriate lifetime
+  --> $DIR/lt-ref-self-async.rs:29:45
+   |
+LL |     async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
+   |                                             ^           ---- this return type evaluates to the `'static` lifetime...
+   |                                             |
+   |                                             ...but this borrow...
+   |
+note: ...can't outlive the lifetime '_ as defined on the method body at 29:37
+  --> $DIR/lt-ref-self-async.rs:29:37
+   |
+LL |     async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
+   |                                     ^
+help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 29:37
+   |
+LL |     async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 + '_ {
+   |                                                         ^^^^^^^^^
+
+error: cannot infer an appropriate lifetime
+  --> $DIR/lt-ref-self-async.rs:35:45
+   |
+LL |     async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
+   |                                             ^           ---- this return type evaluates to the `'static` lifetime...
+   |                                             |
+   |                                             ...but this borrow...
+   |
+note: ...can't outlive the lifetime '_ as defined on the method body at 35:37
+  --> $DIR/lt-ref-self-async.rs:35:37
+   |
+LL |     async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
+   |                                     ^
+help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 35:37
+   |
+LL |     async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 + '_ {
+   |                                                         ^^^^^^^^^
+
+error: cannot infer an appropriate lifetime
+  --> $DIR/lt-ref-self-async.rs:41:54
+   |
+LL |     async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
+   |                                                      ^           ---- this return type evaluates to the `'static` lifetime...
+   |                                                      |
+   |                                                      ...but this borrow...
+   |
+note: ...can't outlive the lifetime '_ as defined on the method body at 41:45
+  --> $DIR/lt-ref-self-async.rs:41:45
+   |
+LL |     async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
+   |                                             ^
+help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 41:45
+   |
+LL |     async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 + '_ {
+   |                                                                  ^^^^^^^^^
+
+error: cannot infer an appropriate lifetime
+  --> $DIR/lt-ref-self-async.rs:47:50
+   |
+LL |     async fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
+   |                                                  ^           ---- this return type evaluates to the `'static` lifetime...
+   |                                                  |
+   |                                                  ...but this borrow...
+   |
+note: ...can't outlive the lifetime '_ as defined on the method body at 47:41
+  --> $DIR/lt-ref-self-async.rs:47:41
+   |
+LL |     async fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
+   |                                         ^
+help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 47:41
+   |
+LL |     async fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 + '_ {
+   |                                                              ^^^^^^^^^
+
+error: aborting due to 12 previous errors
+
+For more information about this error, try `rustc --explain E0106`.
diff --git a/src/test/ui/self/elision/multiple-ref-self-async.nll.stderr b/src/test/ui/self/elision/multiple-ref-self-async.nll.stderr
new file mode 100644
index 0000000000000..00e16cd7f99fb
--- /dev/null
+++ b/src/test/ui/self/elision/multiple-ref-self-async.nll.stderr
@@ -0,0 +1,43 @@
+error[E0106]: missing lifetime specifier
+  --> $DIR/multiple-ref-self-async.rs:24:74
+   |
+LL |     async fn wrap_ref_Self_ref_Self(self: Wrap<&Self, &Self>, f: &u8) -> &u8 {
+   |                                                                          ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/multiple-ref-self-async.rs:30:84
+   |
+LL |     async fn box_wrap_ref_Self_ref_Self(self: Box<Wrap<&Self, &Self>>, f: &u32) -> &u32 {
+   |                                                                                    ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/multiple-ref-self-async.rs:36:84
+   |
+LL |     async fn pin_wrap_ref_Self_ref_Self(self: Pin<Wrap<&Self, &Self>>, f: &u32) -> &u32 {
+   |                                                                                    ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/multiple-ref-self-async.rs:42:93
+   |
+LL |     async fn box_box_wrap_ref_Self_ref_Self(self: Box<Box<Wrap<&Self, &Self>>>, f: &u32) -> &u32 {
+   |                                                                                             ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/multiple-ref-self-async.rs:48:93
+   |
+LL |     async fn box_pin_wrap_ref_Self_ref_Self(self: Box<Pin<Wrap<&Self, &Self>>>, f: &u32) -> &u32 {
+   |                                                                                             ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0106`.
diff --git a/src/test/ui/self/elision/multiple-ref-self-async.rs b/src/test/ui/self/elision/multiple-ref-self-async.rs
new file mode 100644
index 0000000000000..3cc146c5dc7b2
--- /dev/null
+++ b/src/test/ui/self/elision/multiple-ref-self-async.rs
@@ -0,0 +1,55 @@
+// edition:2018
+
+#![feature(async_await)]
+
+#![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 {
+        //~^ ERROR missing lifetime specifier
+        //~| ERROR cannot infer an appropriate lifetime
+        f
+    }
+
+    async fn box_wrap_ref_Self_ref_Self(self: Box<Wrap<&Self, &Self>>, f: &u32) -> &u32 {
+        //~^ ERROR missing lifetime specifier
+        //~| ERROR cannot infer an appropriate lifetime
+        f
+    }
+
+    async fn pin_wrap_ref_Self_ref_Self(self: Pin<Wrap<&Self, &Self>>, f: &u32) -> &u32 {
+        //~^ ERROR missing lifetime specifier
+        //~| ERROR cannot infer an appropriate lifetime
+        f
+    }
+
+    async fn box_box_wrap_ref_Self_ref_Self(self: Box<Box<Wrap<&Self, &Self>>>, f: &u32) -> &u32 {
+        //~^ ERROR missing lifetime specifier
+        //~| ERROR cannot infer an appropriate lifetime
+        f
+    }
+
+    async fn box_pin_wrap_ref_Self_ref_Self(self: Box<Pin<Wrap<&Self, &Self>>>, f: &u32) -> &u32 {
+        //~^ ERROR missing lifetime specifier
+        //~| ERROR cannot infer an appropriate lifetime
+        f
+    }
+}
+
+fn main() { }
diff --git a/src/test/ui/self/elision/multiple-ref-self-async.stderr b/src/test/ui/self/elision/multiple-ref-self-async.stderr
new file mode 100644
index 0000000000000..2a89ed3feba62
--- /dev/null
+++ b/src/test/ui/self/elision/multiple-ref-self-async.stderr
@@ -0,0 +1,133 @@
+error[E0106]: missing lifetime specifier
+  --> $DIR/multiple-ref-self-async.rs:24:74
+   |
+LL |     async fn wrap_ref_Self_ref_Self(self: Wrap<&Self, &Self>, f: &u8) -> &u8 {
+   |                                                                          ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/multiple-ref-self-async.rs:30:84
+   |
+LL |     async fn box_wrap_ref_Self_ref_Self(self: Box<Wrap<&Self, &Self>>, f: &u32) -> &u32 {
+   |                                                                                    ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/multiple-ref-self-async.rs:36:84
+   |
+LL |     async fn pin_wrap_ref_Self_ref_Self(self: Pin<Wrap<&Self, &Self>>, f: &u32) -> &u32 {
+   |                                                                                    ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/multiple-ref-self-async.rs:42:93
+   |
+LL |     async fn box_box_wrap_ref_Self_ref_Self(self: Box<Box<Wrap<&Self, &Self>>>, f: &u32) -> &u32 {
+   |                                                                                             ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/multiple-ref-self-async.rs:48:93
+   |
+LL |     async fn box_pin_wrap_ref_Self_ref_Self(self: Box<Pin<Wrap<&Self, &Self>>>, f: &u32) -> &u32 {
+   |                                                                                             ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error: cannot infer an appropriate lifetime
+  --> $DIR/multiple-ref-self-async.rs:24:63
+   |
+LL |     async fn wrap_ref_Self_ref_Self(self: Wrap<&Self, &Self>, f: &u8) -> &u8 {
+   |                                                               ^          --- this return type evaluates to the `'static` lifetime...
+   |                                                               |
+   |                                                               ...but this borrow...
+   |
+note: ...can't outlive the lifetime '_ as defined on the method body at 24:48
+  --> $DIR/multiple-ref-self-async.rs:24:48
+   |
+LL |     async fn wrap_ref_Self_ref_Self(self: Wrap<&Self, &Self>, f: &u8) -> &u8 {
+   |                                                ^
+help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 24:48
+   |
+LL |     async fn wrap_ref_Self_ref_Self(self: Wrap<&Self, &Self>, f: &u8) -> &u8 + '_ {
+   |                                                                          ^^^^^^^^
+
+error: cannot infer an appropriate lifetime
+  --> $DIR/multiple-ref-self-async.rs:30:72
+   |
+LL |     async fn box_wrap_ref_Self_ref_Self(self: Box<Wrap<&Self, &Self>>, f: &u32) -> &u32 {
+   |                                                                        ^           ---- this return type evaluates to the `'static` lifetime...
+   |                                                                        |
+   |                                                                        ...but this borrow...
+   |
+note: ...can't outlive the lifetime '_ as defined on the method body at 30:56
+  --> $DIR/multiple-ref-self-async.rs:30:56
+   |
+LL |     async fn box_wrap_ref_Self_ref_Self(self: Box<Wrap<&Self, &Self>>, f: &u32) -> &u32 {
+   |                                                        ^
+help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 30:56
+   |
+LL |     async fn box_wrap_ref_Self_ref_Self(self: Box<Wrap<&Self, &Self>>, f: &u32) -> &u32 + '_ {
+   |                                                                                    ^^^^^^^^^
+
+error: cannot infer an appropriate lifetime
+  --> $DIR/multiple-ref-self-async.rs:36:72
+   |
+LL |     async fn pin_wrap_ref_Self_ref_Self(self: Pin<Wrap<&Self, &Self>>, f: &u32) -> &u32 {
+   |                                                                        ^           ---- this return type evaluates to the `'static` lifetime...
+   |                                                                        |
+   |                                                                        ...but this borrow...
+   |
+note: ...can't outlive the lifetime '_ as defined on the method body at 36:56
+  --> $DIR/multiple-ref-self-async.rs:36:56
+   |
+LL |     async fn pin_wrap_ref_Self_ref_Self(self: Pin<Wrap<&Self, &Self>>, f: &u32) -> &u32 {
+   |                                                        ^
+help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 36:56
+   |
+LL |     async fn pin_wrap_ref_Self_ref_Self(self: Pin<Wrap<&Self, &Self>>, f: &u32) -> &u32 + '_ {
+   |                                                                                    ^^^^^^^^^
+
+error: cannot infer an appropriate lifetime
+  --> $DIR/multiple-ref-self-async.rs:42:81
+   |
+LL |     async fn box_box_wrap_ref_Self_ref_Self(self: Box<Box<Wrap<&Self, &Self>>>, f: &u32) -> &u32 {
+   |                                                                                 ^           ---- this return type evaluates to the `'static` lifetime...
+   |                                                                                 |
+   |                                                                                 ...but this borrow...
+   |
+note: ...can't outlive the lifetime '_ as defined on the method body at 42:64
+  --> $DIR/multiple-ref-self-async.rs:42:64
+   |
+LL |     async fn box_box_wrap_ref_Self_ref_Self(self: Box<Box<Wrap<&Self, &Self>>>, f: &u32) -> &u32 {
+   |                                                                ^
+help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 42:64
+   |
+LL |     async fn box_box_wrap_ref_Self_ref_Self(self: Box<Box<Wrap<&Self, &Self>>>, f: &u32) -> &u32 + '_ {
+   |                                                                                             ^^^^^^^^^
+
+error: cannot infer an appropriate lifetime
+  --> $DIR/multiple-ref-self-async.rs:48:81
+   |
+LL |     async fn box_pin_wrap_ref_Self_ref_Self(self: Box<Pin<Wrap<&Self, &Self>>>, f: &u32) -> &u32 {
+   |                                                                                 ^           ---- this return type evaluates to the `'static` lifetime...
+   |                                                                                 |
+   |                                                                                 ...but this borrow...
+   |
+note: ...can't outlive the lifetime '_ as defined on the method body at 48:64
+  --> $DIR/multiple-ref-self-async.rs:48:64
+   |
+LL |     async fn box_pin_wrap_ref_Self_ref_Self(self: Box<Pin<Wrap<&Self, &Self>>>, f: &u32) -> &u32 {
+   |                                                                ^
+help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 48:64
+   |
+LL |     async fn box_pin_wrap_ref_Self_ref_Self(self: Box<Pin<Wrap<&Self, &Self>>>, f: &u32) -> &u32 + '_ {
+   |                                                                                             ^^^^^^^^^
+
+error: aborting due to 10 previous errors
+
+For more information about this error, try `rustc --explain E0106`.
diff --git a/src/test/ui/self/elision/ref-alias-async.nll.stderr b/src/test/ui/self/elision/ref-alias-async.nll.stderr
new file mode 100644
index 0000000000000..7e47b3794035f
--- /dev/null
+++ b/src/test/ui/self/elision/ref-alias-async.nll.stderr
@@ -0,0 +1,43 @@
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-alias-async.rs:20:50
+   |
+LL |     async fn ref_Alias(self: &Alias, f: &u32) -> &u32 {
+   |                                                  ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-alias-async.rs:26:59
+   |
+LL |     async fn box_ref_Alias(self: Box<&Alias>, f: &u32) -> &u32 {
+   |                                                           ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-alias-async.rs:32:59
+   |
+LL |     async fn pin_ref_Alias(self: Pin<&Alias>, f: &u32) -> &u32 {
+   |                                                           ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-alias-async.rs:38:68
+   |
+LL |     async fn box_box_ref_Alias(self: Box<Box<&Alias>>, f: &u32) -> &u32 {
+   |                                                                    ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-alias-async.rs:44:68
+   |
+LL |     async fn box_pin_ref_Alias(self: Box<Pin<&Alias>>, f: &u32) -> &u32 {
+   |                                                                    ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0106`.
diff --git a/src/test/ui/self/elision/ref-alias-async.rs b/src/test/ui/self/elision/ref-alias-async.rs
new file mode 100644
index 0000000000000..224151b9b0c55
--- /dev/null
+++ b/src/test/ui/self/elision/ref-alias-async.rs
@@ -0,0 +1,51 @@
+// edition:2018
+
+#![feature(async_await)]
+
+#![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.
+
+    async fn ref_Alias(self: &Alias, f: &u32) -> &u32 {
+        //~^ ERROR missing lifetime specifier
+        //~| ERROR cannot infer an appropriate lifetime
+        f
+    }
+
+    async fn box_ref_Alias(self: Box<&Alias>, f: &u32) -> &u32 {
+        //~^ ERROR missing lifetime specifier
+        //~| ERROR cannot infer an appropriate lifetime
+        f
+    }
+
+    async fn pin_ref_Alias(self: Pin<&Alias>, f: &u32) -> &u32 {
+        //~^ ERROR missing lifetime specifier
+        //~| ERROR cannot infer an appropriate lifetime
+        f
+    }
+
+    async fn box_box_ref_Alias(self: Box<Box<&Alias>>, f: &u32) -> &u32 {
+        //~^ ERROR missing lifetime specifier
+        //~| ERROR cannot infer an appropriate lifetime
+        f
+    }
+
+    async fn box_pin_ref_Alias(self: Box<Pin<&Alias>>, f: &u32) -> &u32 {
+        //~^ ERROR missing lifetime specifier
+        //~| ERROR cannot infer an appropriate lifetime
+        f
+    }
+}
+
+fn main() { }
diff --git a/src/test/ui/self/elision/ref-alias-async.stderr b/src/test/ui/self/elision/ref-alias-async.stderr
new file mode 100644
index 0000000000000..a3250562c6fff
--- /dev/null
+++ b/src/test/ui/self/elision/ref-alias-async.stderr
@@ -0,0 +1,133 @@
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-alias-async.rs:20:50
+   |
+LL |     async fn ref_Alias(self: &Alias, f: &u32) -> &u32 {
+   |                                                  ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-alias-async.rs:26:59
+   |
+LL |     async fn box_ref_Alias(self: Box<&Alias>, f: &u32) -> &u32 {
+   |                                                           ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-alias-async.rs:32:59
+   |
+LL |     async fn pin_ref_Alias(self: Pin<&Alias>, f: &u32) -> &u32 {
+   |                                                           ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-alias-async.rs:38:68
+   |
+LL |     async fn box_box_ref_Alias(self: Box<Box<&Alias>>, f: &u32) -> &u32 {
+   |                                                                    ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-alias-async.rs:44:68
+   |
+LL |     async fn box_pin_ref_Alias(self: Box<Pin<&Alias>>, f: &u32) -> &u32 {
+   |                                                                    ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error: cannot infer an appropriate lifetime
+  --> $DIR/ref-alias-async.rs:20:38
+   |
+LL |     async fn ref_Alias(self: &Alias, f: &u32) -> &u32 {
+   |                                      ^           ---- this return type evaluates to the `'static` lifetime...
+   |                                      |
+   |                                      ...but this borrow...
+   |
+note: ...can't outlive the lifetime '_ as defined on the method body at 20:30
+  --> $DIR/ref-alias-async.rs:20:30
+   |
+LL |     async fn ref_Alias(self: &Alias, f: &u32) -> &u32 {
+   |                              ^
+help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 20:30
+   |
+LL |     async fn ref_Alias(self: &Alias, f: &u32) -> &u32 + '_ {
+   |                                                  ^^^^^^^^^
+
+error: cannot infer an appropriate lifetime
+  --> $DIR/ref-alias-async.rs:26:47
+   |
+LL |     async fn box_ref_Alias(self: Box<&Alias>, f: &u32) -> &u32 {
+   |                                               ^           ---- this return type evaluates to the `'static` lifetime...
+   |                                               |
+   |                                               ...but this borrow...
+   |
+note: ...can't outlive the lifetime '_ as defined on the method body at 26:38
+  --> $DIR/ref-alias-async.rs:26:38
+   |
+LL |     async fn box_ref_Alias(self: Box<&Alias>, f: &u32) -> &u32 {
+   |                                      ^
+help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 26:38
+   |
+LL |     async fn box_ref_Alias(self: Box<&Alias>, f: &u32) -> &u32 + '_ {
+   |                                                           ^^^^^^^^^
+
+error: cannot infer an appropriate lifetime
+  --> $DIR/ref-alias-async.rs:32:47
+   |
+LL |     async fn pin_ref_Alias(self: Pin<&Alias>, f: &u32) -> &u32 {
+   |                                               ^           ---- this return type evaluates to the `'static` lifetime...
+   |                                               |
+   |                                               ...but this borrow...
+   |
+note: ...can't outlive the lifetime '_ as defined on the method body at 32:38
+  --> $DIR/ref-alias-async.rs:32:38
+   |
+LL |     async fn pin_ref_Alias(self: Pin<&Alias>, f: &u32) -> &u32 {
+   |                                      ^
+help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 32:38
+   |
+LL |     async fn pin_ref_Alias(self: Pin<&Alias>, f: &u32) -> &u32 + '_ {
+   |                                                           ^^^^^^^^^
+
+error: cannot infer an appropriate lifetime
+  --> $DIR/ref-alias-async.rs:38:56
+   |
+LL |     async fn box_box_ref_Alias(self: Box<Box<&Alias>>, f: &u32) -> &u32 {
+   |                                                        ^           ---- this return type evaluates to the `'static` lifetime...
+   |                                                        |
+   |                                                        ...but this borrow...
+   |
+note: ...can't outlive the lifetime '_ as defined on the method body at 38:46
+  --> $DIR/ref-alias-async.rs:38:46
+   |
+LL |     async fn box_box_ref_Alias(self: Box<Box<&Alias>>, f: &u32) -> &u32 {
+   |                                              ^
+help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 38:46
+   |
+LL |     async fn box_box_ref_Alias(self: Box<Box<&Alias>>, f: &u32) -> &u32 + '_ {
+   |                                                                    ^^^^^^^^^
+
+error: cannot infer an appropriate lifetime
+  --> $DIR/ref-alias-async.rs:44:56
+   |
+LL |     async fn box_pin_ref_Alias(self: Box<Pin<&Alias>>, f: &u32) -> &u32 {
+   |                                                        ^           ---- this return type evaluates to the `'static` lifetime...
+   |                                                        |
+   |                                                        ...but this borrow...
+   |
+note: ...can't outlive the lifetime '_ as defined on the method body at 44:46
+  --> $DIR/ref-alias-async.rs:44:46
+   |
+LL |     async fn box_pin_ref_Alias(self: Box<Pin<&Alias>>, f: &u32) -> &u32 {
+   |                                              ^
+help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 44:46
+   |
+LL |     async fn box_pin_ref_Alias(self: Box<Pin<&Alias>>, f: &u32) -> &u32 + '_ {
+   |                                                                    ^^^^^^^^^
+
+error: aborting due to 10 previous errors
+
+For more information about this error, try `rustc --explain E0106`.
diff --git a/src/test/ui/self/elision/ref-assoc-async.nll.stderr b/src/test/ui/self/elision/ref-assoc-async.nll.stderr
new file mode 100644
index 0000000000000..25c8bf652d84b
--- /dev/null
+++ b/src/test/ui/self/elision/ref-assoc-async.nll.stderr
@@ -0,0 +1,43 @@
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-assoc-async.rs:21:77
+   |
+LL |     async fn ref_AssocType(self: &<Struct as Trait>::AssocType, f: &u32) -> &u32 {
+   |                                                                             ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-assoc-async.rs:27:86
+   |
+LL |     async fn box_ref_AssocType(self: Box<&<Struct as Trait>::AssocType>, f: &u32) -> &u32 {
+   |                                                                                      ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-assoc-async.rs:33:86
+   |
+LL |     async fn pin_ref_AssocType(self: Pin<&<Struct as Trait>::AssocType>, f: &u32) -> &u32 {
+   |                                                                                      ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-assoc-async.rs:39:95
+   |
+LL |     async fn box_box_ref_AssocType(self: Box<Box<&<Struct as Trait>::AssocType>>, f: &u32) -> &u32 {
+   |                                                                                               ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-assoc-async.rs:45:95
+   |
+LL |     async fn box_pin_ref_AssocType(self: Box<Pin<&<Struct as Trait>::AssocType>>, f: &u32) -> &u32 {
+   |                                                                                               ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0106`.
diff --git a/src/test/ui/self/elision/ref-assoc-async.rs b/src/test/ui/self/elision/ref-assoc-async.rs
new file mode 100644
index 0000000000000..380937e61ca3f
--- /dev/null
+++ b/src/test/ui/self/elision/ref-assoc-async.rs
@@ -0,0 +1,52 @@
+// edition:2018
+
+#![feature(async_await)]
+
+#![feature(arbitrary_self_types)]
+#![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 {
+        //~^ ERROR missing lifetime specifier
+        //~| ERROR cannot infer an appropriate lifetime
+        f
+    }
+
+    async fn box_ref_AssocType(self: Box<&<Struct as Trait>::AssocType>, f: &u32) -> &u32 {
+        //~^ ERROR missing lifetime specifier
+        //~| ERROR cannot infer an appropriate lifetime
+        f
+    }
+
+    async fn pin_ref_AssocType(self: Pin<&<Struct as Trait>::AssocType>, f: &u32) -> &u32 {
+        //~^ ERROR missing lifetime specifier
+        //~| ERROR cannot infer an appropriate lifetime
+        f
+    }
+
+    async fn box_box_ref_AssocType(self: Box<Box<&<Struct as Trait>::AssocType>>, f: &u32) -> &u32 {
+        //~^ ERROR missing lifetime specifier
+        //~| ERROR cannot infer an appropriate lifetime
+        f
+    }
+
+    async fn box_pin_ref_AssocType(self: Box<Pin<&<Struct as Trait>::AssocType>>, f: &u32) -> &u32 {
+        //~^ ERROR missing lifetime specifier
+        //~| ERROR cannot infer an appropriate lifetime
+        f
+    }
+}
+
+fn main() { }
diff --git a/src/test/ui/self/elision/ref-assoc-async.stderr b/src/test/ui/self/elision/ref-assoc-async.stderr
new file mode 100644
index 0000000000000..c2e893a3f58bf
--- /dev/null
+++ b/src/test/ui/self/elision/ref-assoc-async.stderr
@@ -0,0 +1,133 @@
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-assoc-async.rs:21:77
+   |
+LL |     async fn ref_AssocType(self: &<Struct as Trait>::AssocType, f: &u32) -> &u32 {
+   |                                                                             ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-assoc-async.rs:27:86
+   |
+LL |     async fn box_ref_AssocType(self: Box<&<Struct as Trait>::AssocType>, f: &u32) -> &u32 {
+   |                                                                                      ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-assoc-async.rs:33:86
+   |
+LL |     async fn pin_ref_AssocType(self: Pin<&<Struct as Trait>::AssocType>, f: &u32) -> &u32 {
+   |                                                                                      ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-assoc-async.rs:39:95
+   |
+LL |     async fn box_box_ref_AssocType(self: Box<Box<&<Struct as Trait>::AssocType>>, f: &u32) -> &u32 {
+   |                                                                                               ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-assoc-async.rs:45:95
+   |
+LL |     async fn box_pin_ref_AssocType(self: Box<Pin<&<Struct as Trait>::AssocType>>, f: &u32) -> &u32 {
+   |                                                                                               ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error: cannot infer an appropriate lifetime
+  --> $DIR/ref-assoc-async.rs:21:65
+   |
+LL |     async fn ref_AssocType(self: &<Struct as Trait>::AssocType, f: &u32) -> &u32 {
+   |                                                                 ^           ---- this return type evaluates to the `'static` lifetime...
+   |                                                                 |
+   |                                                                 ...but this borrow...
+   |
+note: ...can't outlive the lifetime '_ as defined on the method body at 21:34
+  --> $DIR/ref-assoc-async.rs:21:34
+   |
+LL |     async fn ref_AssocType(self: &<Struct as Trait>::AssocType, f: &u32) -> &u32 {
+   |                                  ^
+help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 21:34
+   |
+LL |     async fn ref_AssocType(self: &<Struct as Trait>::AssocType, f: &u32) -> &u32 + '_ {
+   |                                                                             ^^^^^^^^^
+
+error: cannot infer an appropriate lifetime
+  --> $DIR/ref-assoc-async.rs:27:74
+   |
+LL |     async fn box_ref_AssocType(self: Box<&<Struct as Trait>::AssocType>, f: &u32) -> &u32 {
+   |                                                                          ^           ---- this return type evaluates to the `'static` lifetime...
+   |                                                                          |
+   |                                                                          ...but this borrow...
+   |
+note: ...can't outlive the lifetime '_ as defined on the method body at 27:42
+  --> $DIR/ref-assoc-async.rs:27:42
+   |
+LL |     async fn box_ref_AssocType(self: Box<&<Struct as Trait>::AssocType>, f: &u32) -> &u32 {
+   |                                          ^
+help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 27:42
+   |
+LL |     async fn box_ref_AssocType(self: Box<&<Struct as Trait>::AssocType>, f: &u32) -> &u32 + '_ {
+   |                                                                                      ^^^^^^^^^
+
+error: cannot infer an appropriate lifetime
+  --> $DIR/ref-assoc-async.rs:33:74
+   |
+LL |     async fn pin_ref_AssocType(self: Pin<&<Struct as Trait>::AssocType>, f: &u32) -> &u32 {
+   |                                                                          ^           ---- this return type evaluates to the `'static` lifetime...
+   |                                                                          |
+   |                                                                          ...but this borrow...
+   |
+note: ...can't outlive the lifetime '_ as defined on the method body at 33:42
+  --> $DIR/ref-assoc-async.rs:33:42
+   |
+LL |     async fn pin_ref_AssocType(self: Pin<&<Struct as Trait>::AssocType>, f: &u32) -> &u32 {
+   |                                          ^
+help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 33:42
+   |
+LL |     async fn pin_ref_AssocType(self: Pin<&<Struct as Trait>::AssocType>, f: &u32) -> &u32 + '_ {
+   |                                                                                      ^^^^^^^^^
+
+error: cannot infer an appropriate lifetime
+  --> $DIR/ref-assoc-async.rs:39:83
+   |
+LL |     async fn box_box_ref_AssocType(self: Box<Box<&<Struct as Trait>::AssocType>>, f: &u32) -> &u32 {
+   |                                                                                   ^           ---- this return type evaluates to the `'static` lifetime...
+   |                                                                                   |
+   |                                                                                   ...but this borrow...
+   |
+note: ...can't outlive the lifetime '_ as defined on the method body at 39:50
+  --> $DIR/ref-assoc-async.rs:39:50
+   |
+LL |     async fn box_box_ref_AssocType(self: Box<Box<&<Struct as Trait>::AssocType>>, f: &u32) -> &u32 {
+   |                                                  ^
+help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 39:50
+   |
+LL |     async fn box_box_ref_AssocType(self: Box<Box<&<Struct as Trait>::AssocType>>, f: &u32) -> &u32 + '_ {
+   |                                                                                               ^^^^^^^^^
+
+error: cannot infer an appropriate lifetime
+  --> $DIR/ref-assoc-async.rs:45:83
+   |
+LL |     async fn box_pin_ref_AssocType(self: Box<Pin<&<Struct as Trait>::AssocType>>, f: &u32) -> &u32 {
+   |                                                                                   ^           ---- this return type evaluates to the `'static` lifetime...
+   |                                                                                   |
+   |                                                                                   ...but this borrow...
+   |
+note: ...can't outlive the lifetime '_ as defined on the method body at 45:50
+  --> $DIR/ref-assoc-async.rs:45:50
+   |
+LL |     async fn box_pin_ref_AssocType(self: Box<Pin<&<Struct as Trait>::AssocType>>, f: &u32) -> &u32 {
+   |                                                  ^
+help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 45:50
+   |
+LL |     async fn box_pin_ref_AssocType(self: Box<Pin<&<Struct as Trait>::AssocType>>, f: &u32) -> &u32 + '_ {
+   |                                                                                               ^^^^^^^^^
+
+error: aborting due to 10 previous errors
+
+For more information about this error, try `rustc --explain E0106`.
diff --git a/src/test/ui/self/elision/ref-mut-alias-async.nll.stderr b/src/test/ui/self/elision/ref-mut-alias-async.nll.stderr
new file mode 100644
index 0000000000000..1026a0b492f34
--- /dev/null
+++ b/src/test/ui/self/elision/ref-mut-alias-async.nll.stderr
@@ -0,0 +1,43 @@
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-mut-alias-async.rs:17:54
+   |
+LL |     async fn ref_Alias(self: &mut Alias, f: &u32) -> &u32 {
+   |                                                      ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-mut-alias-async.rs:23:63
+   |
+LL |     async fn box_ref_Alias(self: Box<&mut Alias>, f: &u32) -> &u32 {
+   |                                                               ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-mut-alias-async.rs:29:63
+   |
+LL |     async fn pin_ref_Alias(self: Pin<&mut Alias>, f: &u32) -> &u32 {
+   |                                                               ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-mut-alias-async.rs:35:72
+   |
+LL |     async fn box_box_ref_Alias(self: Box<Box<&mut Alias>>, f: &u32) -> &u32 {
+   |                                                                        ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-mut-alias-async.rs:41:72
+   |
+LL |     async fn box_pin_ref_Alias(self: Box<Pin<&mut Alias>>, f: &u32) -> &u32 {
+   |                                                                        ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0106`.
diff --git a/src/test/ui/self/elision/ref-mut-alias-async.rs b/src/test/ui/self/elision/ref-mut-alias-async.rs
new file mode 100644
index 0000000000000..ce66313bddd12
--- /dev/null
+++ b/src/test/ui/self/elision/ref-mut-alias-async.rs
@@ -0,0 +1,48 @@
+// edition:2018
+
+#![feature(async_await)]
+
+#![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`:
+
+    async fn ref_Alias(self: &mut Alias, f: &u32) -> &u32 {
+        //~^ ERROR missing lifetime specifier
+        //~| ERROR cannot infer an appropriate lifetime
+        f
+    }
+
+    async fn box_ref_Alias(self: Box<&mut Alias>, f: &u32) -> &u32 {
+        //~^ ERROR missing lifetime specifier
+        //~| ERROR cannot infer an appropriate lifetime
+        f
+    }
+
+    async fn pin_ref_Alias(self: Pin<&mut Alias>, f: &u32) -> &u32 {
+        //~^ ERROR missing lifetime specifier
+        //~| ERROR cannot infer an appropriate lifetime
+        f
+    }
+
+    async fn box_box_ref_Alias(self: Box<Box<&mut Alias>>, f: &u32) -> &u32 {
+        //~^ ERROR missing lifetime specifier
+        //~| ERROR cannot infer an appropriate lifetime
+        f
+    }
+
+    async fn box_pin_ref_Alias(self: Box<Pin<&mut Alias>>, f: &u32) -> &u32 {
+        //~^ ERROR missing lifetime specifier
+        //~| ERROR cannot infer an appropriate lifetime
+        f
+    }
+}
+
+fn main() { }
diff --git a/src/test/ui/self/elision/ref-mut-alias-async.stderr b/src/test/ui/self/elision/ref-mut-alias-async.stderr
new file mode 100644
index 0000000000000..678bf74518606
--- /dev/null
+++ b/src/test/ui/self/elision/ref-mut-alias-async.stderr
@@ -0,0 +1,133 @@
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-mut-alias-async.rs:17:54
+   |
+LL |     async fn ref_Alias(self: &mut Alias, f: &u32) -> &u32 {
+   |                                                      ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-mut-alias-async.rs:23:63
+   |
+LL |     async fn box_ref_Alias(self: Box<&mut Alias>, f: &u32) -> &u32 {
+   |                                                               ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-mut-alias-async.rs:29:63
+   |
+LL |     async fn pin_ref_Alias(self: Pin<&mut Alias>, f: &u32) -> &u32 {
+   |                                                               ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-mut-alias-async.rs:35:72
+   |
+LL |     async fn box_box_ref_Alias(self: Box<Box<&mut Alias>>, f: &u32) -> &u32 {
+   |                                                                        ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-mut-alias-async.rs:41:72
+   |
+LL |     async fn box_pin_ref_Alias(self: Box<Pin<&mut Alias>>, f: &u32) -> &u32 {
+   |                                                                        ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error: cannot infer an appropriate lifetime
+  --> $DIR/ref-mut-alias-async.rs:17:42
+   |
+LL |     async fn ref_Alias(self: &mut Alias, f: &u32) -> &u32 {
+   |                                          ^           ---- this return type evaluates to the `'static` lifetime...
+   |                                          |
+   |                                          ...but this borrow...
+   |
+note: ...can't outlive the lifetime '_ as defined on the method body at 17:30
+  --> $DIR/ref-mut-alias-async.rs:17:30
+   |
+LL |     async fn ref_Alias(self: &mut Alias, f: &u32) -> &u32 {
+   |                              ^
+help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 17:30
+   |
+LL |     async fn ref_Alias(self: &mut Alias, f: &u32) -> &u32 + '_ {
+   |                                                      ^^^^^^^^^
+
+error: cannot infer an appropriate lifetime
+  --> $DIR/ref-mut-alias-async.rs:23:51
+   |
+LL |     async fn box_ref_Alias(self: Box<&mut Alias>, f: &u32) -> &u32 {
+   |                                                   ^           ---- this return type evaluates to the `'static` lifetime...
+   |                                                   |
+   |                                                   ...but this borrow...
+   |
+note: ...can't outlive the lifetime '_ as defined on the method body at 23:38
+  --> $DIR/ref-mut-alias-async.rs:23:38
+   |
+LL |     async fn box_ref_Alias(self: Box<&mut Alias>, f: &u32) -> &u32 {
+   |                                      ^
+help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 23:38
+   |
+LL |     async fn box_ref_Alias(self: Box<&mut Alias>, f: &u32) -> &u32 + '_ {
+   |                                                               ^^^^^^^^^
+
+error: cannot infer an appropriate lifetime
+  --> $DIR/ref-mut-alias-async.rs:29:51
+   |
+LL |     async fn pin_ref_Alias(self: Pin<&mut Alias>, f: &u32) -> &u32 {
+   |                                                   ^           ---- this return type evaluates to the `'static` lifetime...
+   |                                                   |
+   |                                                   ...but this borrow...
+   |
+note: ...can't outlive the lifetime '_ as defined on the method body at 29:38
+  --> $DIR/ref-mut-alias-async.rs:29:38
+   |
+LL |     async fn pin_ref_Alias(self: Pin<&mut Alias>, f: &u32) -> &u32 {
+   |                                      ^
+help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 29:38
+   |
+LL |     async fn pin_ref_Alias(self: Pin<&mut Alias>, f: &u32) -> &u32 + '_ {
+   |                                                               ^^^^^^^^^
+
+error: cannot infer an appropriate lifetime
+  --> $DIR/ref-mut-alias-async.rs:35:60
+   |
+LL |     async fn box_box_ref_Alias(self: Box<Box<&mut Alias>>, f: &u32) -> &u32 {
+   |                                                            ^           ---- this return type evaluates to the `'static` lifetime...
+   |                                                            |
+   |                                                            ...but this borrow...
+   |
+note: ...can't outlive the lifetime '_ as defined on the method body at 35:46
+  --> $DIR/ref-mut-alias-async.rs:35:46
+   |
+LL |     async fn box_box_ref_Alias(self: Box<Box<&mut Alias>>, f: &u32) -> &u32 {
+   |                                              ^
+help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 35:46
+   |
+LL |     async fn box_box_ref_Alias(self: Box<Box<&mut Alias>>, f: &u32) -> &u32 + '_ {
+   |                                                                        ^^^^^^^^^
+
+error: cannot infer an appropriate lifetime
+  --> $DIR/ref-mut-alias-async.rs:41:60
+   |
+LL |     async fn box_pin_ref_Alias(self: Box<Pin<&mut Alias>>, f: &u32) -> &u32 {
+   |                                                            ^           ---- this return type evaluates to the `'static` lifetime...
+   |                                                            |
+   |                                                            ...but this borrow...
+   |
+note: ...can't outlive the lifetime '_ as defined on the method body at 41:46
+  --> $DIR/ref-mut-alias-async.rs:41:46
+   |
+LL |     async fn box_pin_ref_Alias(self: Box<Pin<&mut Alias>>, f: &u32) -> &u32 {
+   |                                              ^
+help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 41:46
+   |
+LL |     async fn box_pin_ref_Alias(self: Box<Pin<&mut Alias>>, f: &u32) -> &u32 + '_ {
+   |                                                                        ^^^^^^^^^
+
+error: aborting due to 10 previous errors
+
+For more information about this error, try `rustc --explain E0106`.
diff --git a/src/test/ui/self/elision/ref-mut-self-async.nll.stderr b/src/test/ui/self/elision/ref-mut-self-async.nll.stderr
new file mode 100644
index 0000000000000..35969659b19d1
--- /dev/null
+++ b/src/test/ui/self/elision/ref-mut-self-async.nll.stderr
@@ -0,0 +1,51 @@
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-mut-self-async.rs:15:46
+   |
+LL |     async fn ref_self(&mut self, f: &u32) -> &u32 {
+   |                                              ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-mut-self-async.rs:23:52
+   |
+LL |     async fn ref_Self(self: &mut Self, f: &u32) -> &u32 {
+   |                                                    ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-mut-self-async.rs:29:61
+   |
+LL |     async fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 {
+   |                                                             ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-mut-self-async.rs:35:61
+   |
+LL |     async fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 {
+   |                                                             ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-mut-self-async.rs:41:70
+   |
+LL |     async fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 {
+   |                                                                      ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-mut-self-async.rs:47:70
+   |
+LL |     async fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 {
+   |                                                                      ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0106`.
diff --git a/src/test/ui/self/elision/ref-mut-self-async.rs b/src/test/ui/self/elision/ref-mut-self-async.rs
new file mode 100644
index 0000000000000..7d143e1b35e45
--- /dev/null
+++ b/src/test/ui/self/elision/ref-mut-self-async.rs
@@ -0,0 +1,54 @@
+// edition:2018
+
+#![feature(async_await)]
+
+#![feature(arbitrary_self_types)]
+#![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 {
+        //~^ ERROR missing lifetime specifier
+        //~| ERROR cannot infer an appropriate lifetime
+        f
+    }
+
+    // Test using `&mut Self` explicitly:
+
+    async fn ref_Self(self: &mut Self, f: &u32) -> &u32 {
+        //~^ ERROR missing lifetime specifier
+        //~| ERROR cannot infer an appropriate lifetime
+        f
+    }
+
+    async fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 {
+        //~^ ERROR missing lifetime specifier
+        //~| ERROR cannot infer an appropriate lifetime
+        f
+    }
+
+    async fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 {
+        //~^ ERROR missing lifetime specifier
+        //~| ERROR cannot infer an appropriate lifetime
+        f
+    }
+
+    async fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 {
+        //~^ ERROR missing lifetime specifier
+        //~| ERROR cannot infer an appropriate lifetime
+        f
+    }
+
+    async fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 {
+        //~^ ERROR missing lifetime specifier
+        //~| ERROR cannot infer an appropriate lifetime
+        f
+    }
+}
+
+fn main() { }
diff --git a/src/test/ui/self/elision/ref-mut-self-async.stderr b/src/test/ui/self/elision/ref-mut-self-async.stderr
new file mode 100644
index 0000000000000..15f5f8dd0dd48
--- /dev/null
+++ b/src/test/ui/self/elision/ref-mut-self-async.stderr
@@ -0,0 +1,159 @@
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-mut-self-async.rs:15:46
+   |
+LL |     async fn ref_self(&mut self, f: &u32) -> &u32 {
+   |                                              ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-mut-self-async.rs:23:52
+   |
+LL |     async fn ref_Self(self: &mut Self, f: &u32) -> &u32 {
+   |                                                    ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-mut-self-async.rs:29:61
+   |
+LL |     async fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 {
+   |                                                             ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-mut-self-async.rs:35:61
+   |
+LL |     async fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 {
+   |                                                             ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-mut-self-async.rs:41:70
+   |
+LL |     async fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 {
+   |                                                                      ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-mut-self-async.rs:47:70
+   |
+LL |     async fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 {
+   |                                                                      ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error: cannot infer an appropriate lifetime
+  --> $DIR/ref-mut-self-async.rs:15:34
+   |
+LL |     async fn ref_self(&mut self, f: &u32) -> &u32 {
+   |                                  ^           ---- this return type evaluates to the `'static` lifetime...
+   |                                  |
+   |                                  ...but this borrow...
+   |
+note: ...can't outlive the lifetime '_ as defined on the method body at 15:23
+  --> $DIR/ref-mut-self-async.rs:15:23
+   |
+LL |     async fn ref_self(&mut self, f: &u32) -> &u32 {
+   |                       ^
+help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 15:23
+   |
+LL |     async fn ref_self(&mut self, f: &u32) -> &u32 + '_ {
+   |                                              ^^^^^^^^^
+
+error: cannot infer an appropriate lifetime
+  --> $DIR/ref-mut-self-async.rs:23:40
+   |
+LL |     async fn ref_Self(self: &mut Self, f: &u32) -> &u32 {
+   |                                        ^           ---- this return type evaluates to the `'static` lifetime...
+   |                                        |
+   |                                        ...but this borrow...
+   |
+note: ...can't outlive the lifetime '_ as defined on the method body at 23:29
+  --> $DIR/ref-mut-self-async.rs:23:29
+   |
+LL |     async fn ref_Self(self: &mut Self, f: &u32) -> &u32 {
+   |                             ^
+help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 23:29
+   |
+LL |     async fn ref_Self(self: &mut Self, f: &u32) -> &u32 + '_ {
+   |                                                    ^^^^^^^^^
+
+error: cannot infer an appropriate lifetime
+  --> $DIR/ref-mut-self-async.rs:29:49
+   |
+LL |     async fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 {
+   |                                                 ^           ---- this return type evaluates to the `'static` lifetime...
+   |                                                 |
+   |                                                 ...but this borrow...
+   |
+note: ...can't outlive the lifetime '_ as defined on the method body at 29:37
+  --> $DIR/ref-mut-self-async.rs:29:37
+   |
+LL |     async fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 {
+   |                                     ^
+help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 29:37
+   |
+LL |     async fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 + '_ {
+   |                                                             ^^^^^^^^^
+
+error: cannot infer an appropriate lifetime
+  --> $DIR/ref-mut-self-async.rs:35:49
+   |
+LL |     async fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 {
+   |                                                 ^           ---- this return type evaluates to the `'static` lifetime...
+   |                                                 |
+   |                                                 ...but this borrow...
+   |
+note: ...can't outlive the lifetime '_ as defined on the method body at 35:37
+  --> $DIR/ref-mut-self-async.rs:35:37
+   |
+LL |     async fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 {
+   |                                     ^
+help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 35:37
+   |
+LL |     async fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 + '_ {
+   |                                                             ^^^^^^^^^
+
+error: cannot infer an appropriate lifetime
+  --> $DIR/ref-mut-self-async.rs:41:58
+   |
+LL |     async fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 {
+   |                                                          ^           ---- this return type evaluates to the `'static` lifetime...
+   |                                                          |
+   |                                                          ...but this borrow...
+   |
+note: ...can't outlive the lifetime '_ as defined on the method body at 41:45
+  --> $DIR/ref-mut-self-async.rs:41:45
+   |
+LL |     async fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 {
+   |                                             ^
+help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 41:45
+   |
+LL |     async fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 + '_ {
+   |                                                                      ^^^^^^^^^
+
+error: cannot infer an appropriate lifetime
+  --> $DIR/ref-mut-self-async.rs:47:58
+   |
+LL |     async fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 {
+   |                                                          ^           ---- this return type evaluates to the `'static` lifetime...
+   |                                                          |
+   |                                                          ...but this borrow...
+   |
+note: ...can't outlive the lifetime '_ as defined on the method body at 47:45
+  --> $DIR/ref-mut-self-async.rs:47:45
+   |
+LL |     async fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 {
+   |                                             ^
+help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 47:45
+   |
+LL |     async fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 + '_ {
+   |                                                                      ^^^^^^^^^
+
+error: aborting due to 12 previous errors
+
+For more information about this error, try `rustc --explain E0106`.
diff --git a/src/test/ui/self/elision/ref-mut-struct-async.nll.stderr b/src/test/ui/self/elision/ref-mut-struct-async.nll.stderr
new file mode 100644
index 0000000000000..a70dcf5b0ad19
--- /dev/null
+++ b/src/test/ui/self/elision/ref-mut-struct-async.nll.stderr
@@ -0,0 +1,43 @@
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-mut-struct-async.rs:15:56
+   |
+LL |     async fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 {
+   |                                                        ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-mut-struct-async.rs:21:65
+   |
+LL |     async fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 {
+   |                                                                 ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-mut-struct-async.rs:27:65
+   |
+LL |     async fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 {
+   |                                                                 ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-mut-struct-async.rs:33:74
+   |
+LL |     async fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u32 {
+   |                                                                          ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-mut-struct-async.rs:39:74
+   |
+LL |     async fn box_pin_ref_Struct(self: Box<Pin<&mut Struct>>, f: &u32) -> &u32 {
+   |                                                                          ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0106`.
diff --git a/src/test/ui/self/elision/ref-mut-struct-async.rs b/src/test/ui/self/elision/ref-mut-struct-async.rs
new file mode 100644
index 0000000000000..3ba9c95d35ff4
--- /dev/null
+++ b/src/test/ui/self/elision/ref-mut-struct-async.rs
@@ -0,0 +1,46 @@
+// edition:2018
+
+#![feature(async_await)]
+
+#![feature(arbitrary_self_types)]
+#![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 {
+        //~^ ERROR missing lifetime specifier
+        //~| ERROR cannot infer an appropriate lifetime
+        f
+    }
+
+    async fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 {
+        //~^ ERROR missing lifetime specifier
+        //~| ERROR cannot infer an appropriate lifetime
+        f
+    }
+
+    async fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 {
+        //~^ ERROR missing lifetime specifier
+        //~| ERROR cannot infer an appropriate lifetime
+        f
+    }
+
+    async fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u32 {
+        //~^ ERROR missing lifetime specifier
+        //~| ERROR cannot infer an appropriate lifetime
+        f
+    }
+
+    async fn box_pin_ref_Struct(self: Box<Pin<&mut Struct>>, f: &u32) -> &u32 {
+        //~^ ERROR missing lifetime specifier
+        //~| ERROR cannot infer an appropriate lifetime
+        f
+    }
+}
+
+fn main() { }
diff --git a/src/test/ui/self/elision/ref-mut-struct-async.stderr b/src/test/ui/self/elision/ref-mut-struct-async.stderr
new file mode 100644
index 0000000000000..fd2581eba9434
--- /dev/null
+++ b/src/test/ui/self/elision/ref-mut-struct-async.stderr
@@ -0,0 +1,133 @@
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-mut-struct-async.rs:15:56
+   |
+LL |     async fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 {
+   |                                                        ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-mut-struct-async.rs:21:65
+   |
+LL |     async fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 {
+   |                                                                 ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-mut-struct-async.rs:27:65
+   |
+LL |     async fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 {
+   |                                                                 ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-mut-struct-async.rs:33:74
+   |
+LL |     async fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u32 {
+   |                                                                          ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-mut-struct-async.rs:39:74
+   |
+LL |     async fn box_pin_ref_Struct(self: Box<Pin<&mut Struct>>, f: &u32) -> &u32 {
+   |                                                                          ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error: cannot infer an appropriate lifetime
+  --> $DIR/ref-mut-struct-async.rs:15:44
+   |
+LL |     async fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 {
+   |                                            ^           ---- this return type evaluates to the `'static` lifetime...
+   |                                            |
+   |                                            ...but this borrow...
+   |
+note: ...can't outlive the lifetime '_ as defined on the method body at 15:31
+  --> $DIR/ref-mut-struct-async.rs:15:31
+   |
+LL |     async fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 {
+   |                               ^
+help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 15:31
+   |
+LL |     async fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 + '_ {
+   |                                                        ^^^^^^^^^
+
+error: cannot infer an appropriate lifetime
+  --> $DIR/ref-mut-struct-async.rs:21:53
+   |
+LL |     async fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 {
+   |                                                     ^           ---- this return type evaluates to the `'static` lifetime...
+   |                                                     |
+   |                                                     ...but this borrow...
+   |
+note: ...can't outlive the lifetime '_ as defined on the method body at 21:39
+  --> $DIR/ref-mut-struct-async.rs:21:39
+   |
+LL |     async fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 {
+   |                                       ^
+help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 21:39
+   |
+LL |     async fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 + '_ {
+   |                                                                 ^^^^^^^^^
+
+error: cannot infer an appropriate lifetime
+  --> $DIR/ref-mut-struct-async.rs:27:53
+   |
+LL |     async fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 {
+   |                                                     ^           ---- this return type evaluates to the `'static` lifetime...
+   |                                                     |
+   |                                                     ...but this borrow...
+   |
+note: ...can't outlive the lifetime '_ as defined on the method body at 27:39
+  --> $DIR/ref-mut-struct-async.rs:27:39
+   |
+LL |     async fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 {
+   |                                       ^
+help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 27:39
+   |
+LL |     async fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 + '_ {
+   |                                                                 ^^^^^^^^^
+
+error: cannot infer an appropriate lifetime
+  --> $DIR/ref-mut-struct-async.rs:33:62
+   |
+LL |     async fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u32 {
+   |                                                              ^           ---- this return type evaluates to the `'static` lifetime...
+   |                                                              |
+   |                                                              ...but this borrow...
+   |
+note: ...can't outlive the lifetime '_ as defined on the method body at 33:47
+  --> $DIR/ref-mut-struct-async.rs:33:47
+   |
+LL |     async fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u32 {
+   |                                               ^
+help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 33:47
+   |
+LL |     async fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u32 + '_ {
+   |                                                                          ^^^^^^^^^
+
+error: cannot infer an appropriate lifetime
+  --> $DIR/ref-mut-struct-async.rs:39:62
+   |
+LL |     async fn box_pin_ref_Struct(self: Box<Pin<&mut Struct>>, f: &u32) -> &u32 {
+   |                                                              ^           ---- this return type evaluates to the `'static` lifetime...
+   |                                                              |
+   |                                                              ...but this borrow...
+   |
+note: ...can't outlive the lifetime '_ as defined on the method body at 39:47
+  --> $DIR/ref-mut-struct-async.rs:39:47
+   |
+LL |     async fn box_pin_ref_Struct(self: Box<Pin<&mut Struct>>, f: &u32) -> &u32 {
+   |                                               ^
+help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 39:47
+   |
+LL |     async fn box_pin_ref_Struct(self: Box<Pin<&mut Struct>>, f: &u32) -> &u32 + '_ {
+   |                                                                          ^^^^^^^^^
+
+error: aborting due to 10 previous errors
+
+For more information about this error, try `rustc --explain E0106`.
diff --git a/src/test/ui/self/elision/ref-self-async.nll.stderr b/src/test/ui/self/elision/ref-self-async.nll.stderr
new file mode 100644
index 0000000000000..ae17ba9839d22
--- /dev/null
+++ b/src/test/ui/self/elision/ref-self-async.nll.stderr
@@ -0,0 +1,59 @@
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-self-async.rs:24:42
+   |
+LL |     async fn ref_self(&self, f: &u32) -> &u32 {
+   |                                          ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-self-async.rs:32:48
+   |
+LL |     async fn ref_Self(self: &Self, f: &u32) -> &u32 {
+   |                                                ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-self-async.rs:38:57
+   |
+LL |     async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
+   |                                                         ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-self-async.rs:44:57
+   |
+LL |     async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
+   |                                                         ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-self-async.rs:50:66
+   |
+LL |     async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
+   |                                                                  ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-self-async.rs:56:66
+   |
+LL |     async fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
+   |                                                                  ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-self-async.rs:62:69
+   |
+LL |     async fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 {
+   |                                                                     ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error: aborting due to 7 previous errors
+
+For more information about this error, try `rustc --explain E0106`.
diff --git a/src/test/ui/self/elision/ref-self-async.rs b/src/test/ui/self/elision/ref-self-async.rs
new file mode 100644
index 0000000000000..6cca5494ff784
--- /dev/null
+++ b/src/test/ui/self/elision/ref-self-async.rs
@@ -0,0 +1,69 @@
+// edition:2018
+
+#![feature(async_await)]
+
+#![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:
+
+    async fn ref_self(&self, f: &u32) -> &u32 {
+        //~^ ERROR missing lifetime specifier
+        //~| ERROR cannot infer an appropriate lifetime
+        f
+    }
+
+    // Test using `&Self` explicitly:
+
+    async fn ref_Self(self: &Self, f: &u32) -> &u32 {
+        //~^ ERROR missing lifetime specifier
+        //~| ERROR cannot infer an appropriate lifetime
+        f
+    }
+
+    async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
+        //~^ ERROR missing lifetime specifier
+        //~| ERROR cannot infer an appropriate lifetime
+        f
+    }
+
+    async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
+        //~^ ERROR missing lifetime specifier
+        //~| ERROR cannot infer an appropriate lifetime
+        f
+    }
+
+    async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
+        //~^ ERROR missing lifetime specifier
+        //~| ERROR cannot infer an appropriate lifetime
+        f
+    }
+
+    async fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
+        //~^ ERROR missing lifetime specifier
+        //~| ERROR cannot infer an appropriate lifetime
+        f
+    }
+
+    async fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 {
+        //~^ ERROR missing lifetime specifier
+        //~| ERROR cannot infer an appropriate lifetime
+        f
+    }
+}
+
+fn main() { }
diff --git a/src/test/ui/self/elision/ref-self-async.stderr b/src/test/ui/self/elision/ref-self-async.stderr
new file mode 100644
index 0000000000000..eab77cfacd956
--- /dev/null
+++ b/src/test/ui/self/elision/ref-self-async.stderr
@@ -0,0 +1,185 @@
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-self-async.rs:24:42
+   |
+LL |     async fn ref_self(&self, f: &u32) -> &u32 {
+   |                                          ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-self-async.rs:32:48
+   |
+LL |     async fn ref_Self(self: &Self, f: &u32) -> &u32 {
+   |                                                ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-self-async.rs:38:57
+   |
+LL |     async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
+   |                                                         ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-self-async.rs:44:57
+   |
+LL |     async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
+   |                                                         ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-self-async.rs:50:66
+   |
+LL |     async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
+   |                                                                  ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-self-async.rs:56:66
+   |
+LL |     async fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
+   |                                                                  ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-self-async.rs:62:69
+   |
+LL |     async fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 {
+   |                                                                     ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error: cannot infer an appropriate lifetime
+  --> $DIR/ref-self-async.rs:24:30
+   |
+LL |     async fn ref_self(&self, f: &u32) -> &u32 {
+   |                              ^           ---- this return type evaluates to the `'static` lifetime...
+   |                              |
+   |                              ...but this borrow...
+   |
+note: ...can't outlive the lifetime '_ as defined on the method body at 24:23
+  --> $DIR/ref-self-async.rs:24:23
+   |
+LL |     async fn ref_self(&self, f: &u32) -> &u32 {
+   |                       ^
+help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 24:23
+   |
+LL |     async fn ref_self(&self, f: &u32) -> &u32 + '_ {
+   |                                          ^^^^^^^^^
+
+error: cannot infer an appropriate lifetime
+  --> $DIR/ref-self-async.rs:32:36
+   |
+LL |     async fn ref_Self(self: &Self, f: &u32) -> &u32 {
+   |                                    ^           ---- this return type evaluates to the `'static` lifetime...
+   |                                    |
+   |                                    ...but this borrow...
+   |
+note: ...can't outlive the lifetime '_ as defined on the method body at 32:29
+  --> $DIR/ref-self-async.rs:32:29
+   |
+LL |     async fn ref_Self(self: &Self, f: &u32) -> &u32 {
+   |                             ^
+help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 32:29
+   |
+LL |     async fn ref_Self(self: &Self, f: &u32) -> &u32 + '_ {
+   |                                                ^^^^^^^^^
+
+error: cannot infer an appropriate lifetime
+  --> $DIR/ref-self-async.rs:38:45
+   |
+LL |     async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
+   |                                             ^           ---- this return type evaluates to the `'static` lifetime...
+   |                                             |
+   |                                             ...but this borrow...
+   |
+note: ...can't outlive the lifetime '_ as defined on the method body at 38:37
+  --> $DIR/ref-self-async.rs:38:37
+   |
+LL |     async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
+   |                                     ^
+help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 38:37
+   |
+LL |     async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 + '_ {
+   |                                                         ^^^^^^^^^
+
+error: cannot infer an appropriate lifetime
+  --> $DIR/ref-self-async.rs:44:45
+   |
+LL |     async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
+   |                                             ^           ---- this return type evaluates to the `'static` lifetime...
+   |                                             |
+   |                                             ...but this borrow...
+   |
+note: ...can't outlive the lifetime '_ as defined on the method body at 44:37
+  --> $DIR/ref-self-async.rs:44:37
+   |
+LL |     async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
+   |                                     ^
+help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 44:37
+   |
+LL |     async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 + '_ {
+   |                                                         ^^^^^^^^^
+
+error: cannot infer an appropriate lifetime
+  --> $DIR/ref-self-async.rs:50:54
+   |
+LL |     async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
+   |                                                      ^           ---- this return type evaluates to the `'static` lifetime...
+   |                                                      |
+   |                                                      ...but this borrow...
+   |
+note: ...can't outlive the lifetime '_ as defined on the method body at 50:45
+  --> $DIR/ref-self-async.rs:50:45
+   |
+LL |     async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
+   |                                             ^
+help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 50:45
+   |
+LL |     async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 + '_ {
+   |                                                                  ^^^^^^^^^
+
+error: cannot infer an appropriate lifetime
+  --> $DIR/ref-self-async.rs:56:54
+   |
+LL |     async fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
+   |                                                      ^           ---- this return type evaluates to the `'static` lifetime...
+   |                                                      |
+   |                                                      ...but this borrow...
+   |
+note: ...can't outlive the lifetime '_ as defined on the method body at 56:45
+  --> $DIR/ref-self-async.rs:56:45
+   |
+LL |     async fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
+   |                                             ^
+help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 56:45
+   |
+LL |     async fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 + '_ {
+   |                                                                  ^^^^^^^^^
+
+error: cannot infer an appropriate lifetime
+  --> $DIR/ref-self-async.rs:62:58
+   |
+LL |     async fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 {
+   |                                                          ^          --- this return type evaluates to the `'static` lifetime...
+   |                                                          |
+   |                                                          ...but this borrow...
+   |
+note: ...can't outlive the lifetime '_ as defined on the method body at 62:44
+  --> $DIR/ref-self-async.rs:62:44
+   |
+LL |     async fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 {
+   |                                            ^
+help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 62:44
+   |
+LL |     async fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 + '_ {
+   |                                                                     ^^^^^^^^
+
+error: aborting due to 14 previous errors
+
+For more information about this error, try `rustc --explain E0106`.
diff --git a/src/test/ui/self/elision/ref-struct-async.nll.stderr b/src/test/ui/self/elision/ref-struct-async.nll.stderr
new file mode 100644
index 0000000000000..b4f12d7057db4
--- /dev/null
+++ b/src/test/ui/self/elision/ref-struct-async.nll.stderr
@@ -0,0 +1,43 @@
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-struct-async.rs:15:52
+   |
+LL |     async fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
+   |                                                    ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-struct-async.rs:21:61
+   |
+LL |     async fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 {
+   |                                                             ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-struct-async.rs:27:61
+   |
+LL |     async fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 {
+   |                                                             ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-struct-async.rs:33:70
+   |
+LL |     async fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 {
+   |                                                                      ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-struct-async.rs:39:66
+   |
+LL |     async fn box_pin_Struct(self: Box<Pin<&Struct>>, f: &u32) -> &u32 {
+   |                                                                  ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0106`.
diff --git a/src/test/ui/self/elision/ref-struct-async.rs b/src/test/ui/self/elision/ref-struct-async.rs
new file mode 100644
index 0000000000000..cd0f5a2a6058d
--- /dev/null
+++ b/src/test/ui/self/elision/ref-struct-async.rs
@@ -0,0 +1,46 @@
+// edition:2018
+
+#![feature(async_await)]
+
+#![feature(arbitrary_self_types)]
+#![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 {
+        //~^ ERROR missing lifetime specifier
+        //~| ERROR cannot infer an appropriate lifetime
+        f
+    }
+
+    async fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 {
+        //~^ ERROR missing lifetime specifier
+        //~| ERROR cannot infer an appropriate lifetime
+        f
+    }
+
+    async fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 {
+        //~^ ERROR missing lifetime specifier
+        //~| ERROR cannot infer an appropriate lifetime
+        f
+    }
+
+    async fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 {
+        //~^ ERROR missing lifetime specifier
+        //~| ERROR cannot infer an appropriate lifetime
+        f
+    }
+
+    async fn box_pin_Struct(self: Box<Pin<&Struct>>, f: &u32) -> &u32 {
+        //~^ ERROR missing lifetime specifier
+        //~| ERROR cannot infer an appropriate lifetime
+        f
+    }
+}
+
+fn main() { }
diff --git a/src/test/ui/self/elision/ref-struct-async.stderr b/src/test/ui/self/elision/ref-struct-async.stderr
new file mode 100644
index 0000000000000..966e102fa5f27
--- /dev/null
+++ b/src/test/ui/self/elision/ref-struct-async.stderr
@@ -0,0 +1,133 @@
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-struct-async.rs:15:52
+   |
+LL |     async fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
+   |                                                    ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-struct-async.rs:21:61
+   |
+LL |     async fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 {
+   |                                                             ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-struct-async.rs:27:61
+   |
+LL |     async fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 {
+   |                                                             ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-struct-async.rs:33:70
+   |
+LL |     async fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 {
+   |                                                                      ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/ref-struct-async.rs:39:66
+   |
+LL |     async fn box_pin_Struct(self: Box<Pin<&Struct>>, f: &u32) -> &u32 {
+   |                                                                  ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error: cannot infer an appropriate lifetime
+  --> $DIR/ref-struct-async.rs:15:40
+   |
+LL |     async fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
+   |                                        ^           ---- this return type evaluates to the `'static` lifetime...
+   |                                        |
+   |                                        ...but this borrow...
+   |
+note: ...can't outlive the lifetime '_ as defined on the method body at 15:31
+  --> $DIR/ref-struct-async.rs:15:31
+   |
+LL |     async fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
+   |                               ^
+help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 15:31
+   |
+LL |     async fn ref_Struct(self: &Struct, f: &u32) -> &u32 + '_ {
+   |                                                    ^^^^^^^^^
+
+error: cannot infer an appropriate lifetime
+  --> $DIR/ref-struct-async.rs:21:49
+   |
+LL |     async fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 {
+   |                                                 ^           ---- this return type evaluates to the `'static` lifetime...
+   |                                                 |
+   |                                                 ...but this borrow...
+   |
+note: ...can't outlive the lifetime '_ as defined on the method body at 21:39
+  --> $DIR/ref-struct-async.rs:21:39
+   |
+LL |     async fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 {
+   |                                       ^
+help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 21:39
+   |
+LL |     async fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 + '_ {
+   |                                                             ^^^^^^^^^
+
+error: cannot infer an appropriate lifetime
+  --> $DIR/ref-struct-async.rs:27:49
+   |
+LL |     async fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 {
+   |                                                 ^           ---- this return type evaluates to the `'static` lifetime...
+   |                                                 |
+   |                                                 ...but this borrow...
+   |
+note: ...can't outlive the lifetime '_ as defined on the method body at 27:39
+  --> $DIR/ref-struct-async.rs:27:39
+   |
+LL |     async fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 {
+   |                                       ^
+help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 27:39
+   |
+LL |     async fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 + '_ {
+   |                                                             ^^^^^^^^^
+
+error: cannot infer an appropriate lifetime
+  --> $DIR/ref-struct-async.rs:33:58
+   |
+LL |     async fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 {
+   |                                                          ^           ---- this return type evaluates to the `'static` lifetime...
+   |                                                          |
+   |                                                          ...but this borrow...
+   |
+note: ...can't outlive the lifetime '_ as defined on the method body at 33:47
+  --> $DIR/ref-struct-async.rs:33:47
+   |
+LL |     async fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 {
+   |                                               ^
+help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 33:47
+   |
+LL |     async fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 + '_ {
+   |                                                                      ^^^^^^^^^
+
+error: cannot infer an appropriate lifetime
+  --> $DIR/ref-struct-async.rs:39:54
+   |
+LL |     async fn box_pin_Struct(self: Box<Pin<&Struct>>, f: &u32) -> &u32 {
+   |                                                      ^           ---- this return type evaluates to the `'static` lifetime...
+   |                                                      |
+   |                                                      ...but this borrow...
+   |
+note: ...can't outlive the lifetime '_ as defined on the method body at 39:43
+  --> $DIR/ref-struct-async.rs:39:43
+   |
+LL |     async fn box_pin_Struct(self: Box<Pin<&Struct>>, f: &u32) -> &u32 {
+   |                                           ^
+help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 39:43
+   |
+LL |     async fn box_pin_Struct(self: Box<Pin<&Struct>>, f: &u32) -> &u32 + '_ {
+   |                                                                  ^^^^^^^^^
+
+error: aborting due to 10 previous errors
+
+For more information about this error, try `rustc --explain E0106`.

From d9294a284d6f10170effe2f29c2cd7ae94992d36 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Thu, 8 Aug 2019 16:00:46 +0200
Subject: [PATCH 3/5] lifetime elision: document conformance of 'async fn' to
 'fn'.

---
 src/test/ui/self/elision/README.md | 31 ++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/src/test/ui/self/elision/README.md b/src/test/ui/self/elision/README.md
index 7ace2e0c89039..c4f06433ba709 100644
--- a/src/test/ui/self/elision/README.md
+++ b/src/test/ui/self/elision/README.md
@@ -42,3 +42,34 @@ In each case, we test the following patterns:
 - `self: Box<Pin<XXX>>`
 
 In the non-reference cases, `Pin` causes errors so we substitute `Rc`.
+
+### `async fn`
+
+For each of the tests above we also check that `async fn` behaves as an `fn` would.
+These tests are in files named `*-async.rs`.
+
+Legends:
+- ✓ ⟹ Yes / Pass
+- X ⟹ No
+- α ⟹ lifetime mismatch
+- β ⟹ cannot infer an appropriate lifetime
+- γ ⟹ missing lifetime specifier
+
+| `async` file | Pass? | Conforms to `fn`? | How does it diverge? <br/> `fn` ⟶ `async fn` |
+| --- | --- | --- | --- |
+| `self-async.rs` | ✓ | ✓ | N/A |
+| `struct-async.rs`| ✓ | ✓ | N/A |
+| `alias-async.rs`| ✓ | ✓ | N/A |
+| `assoc-async.rs`| ✓ | ✓ | N/A |
+| `ref-self-async.rs` | X | X | α ⟶ β + γ |
+| `ref-mut-self-async.rs` | X | X | α ⟶ β + γ |
+| `ref-struct-async.rs` | X | X | α ⟶ β + γ |
+| `ref-mut-struct-async.rs` | X | X | α ⟶ β + γ |
+| `ref-alias-async.rs` | X | X | ✓ ⟶ β + γ |
+| `ref-assoc-async.rs` | X | X | ✓ ⟶ β + γ |
+| `ref-mut-alias-async.rs` | X | X | ✓ ⟶ β + γ |
+| `lt-self-async.rs` | ✓ | ✓ | N/A
+| `lt-struct-async.rs` | ✓ | ✓ | N/A
+| `lt-alias-async.rs` | ✓ | ✓ | N/A
+| `lt-assoc-async.rs` | ✓ | ✓ | N/A
+| `lt-ref-self-async.rs` | X | X | α ⟶ β + γ

From f3957876c81ce45c31895316060e23149c6fb964 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Thu, 8 Aug 2019 17:08:30 +0200
Subject: [PATCH 4/5] Add async version of self_lifetime.rs test.

---
 .../ui/self/self_lifetime-async.nll.stderr    | 11 ++++++
 src/test/ui/self/self_lifetime-async.rs       | 20 ++++++++++
 src/test/ui/self/self_lifetime-async.stderr   | 39 +++++++++++++++++++
 3 files changed, 70 insertions(+)
 create mode 100644 src/test/ui/self/self_lifetime-async.nll.stderr
 create mode 100644 src/test/ui/self/self_lifetime-async.rs
 create mode 100644 src/test/ui/self/self_lifetime-async.stderr

diff --git a/src/test/ui/self/self_lifetime-async.nll.stderr b/src/test/ui/self/self_lifetime-async.nll.stderr
new file mode 100644
index 0000000000000..805d2433f87ac
--- /dev/null
+++ b/src/test/ui/self/self_lifetime-async.nll.stderr
@@ -0,0 +1,11 @@
+error[E0106]: missing lifetime specifier
+  --> $DIR/self_lifetime-async.rs:9:44
+   |
+LL |     async fn foo<'b>(self: &'b Foo<'a>) -> &() { self.0 }
+   |                                            ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found none.
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0106`.
diff --git a/src/test/ui/self/self_lifetime-async.rs b/src/test/ui/self/self_lifetime-async.rs
new file mode 100644
index 0000000000000..71eba01fe1a02
--- /dev/null
+++ b/src/test/ui/self/self_lifetime-async.rs
@@ -0,0 +1,20 @@
+// FIXME: Investigate why `self_lifetime.rs` is check-pass but this isn't.
+
+// edition:2018
+
+#![feature(async_await)]
+
+struct Foo<'a>(&'a ());
+impl<'a> Foo<'a> {
+    async fn foo<'b>(self: &'b Foo<'a>) -> &() { self.0 }
+    //~^ ERROR missing lifetime specifier
+    //~| ERROR cannot infer an appropriate lifetime
+}
+
+type Alias = Foo<'static>;
+impl Alias {
+    async fn bar<'a>(self: &Alias, arg: &'a ()) -> &() { arg }
+    //~^ ERROR lifetime mismatch
+}
+
+fn main() {}
diff --git a/src/test/ui/self/self_lifetime-async.stderr b/src/test/ui/self/self_lifetime-async.stderr
new file mode 100644
index 0000000000000..e3ec1abd44763
--- /dev/null
+++ b/src/test/ui/self/self_lifetime-async.stderr
@@ -0,0 +1,39 @@
+error[E0106]: missing lifetime specifier
+  --> $DIR/self_lifetime-async.rs:9:44
+   |
+LL |     async fn foo<'b>(self: &'b Foo<'a>) -> &() { self.0 }
+   |                                            ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found none.
+
+error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
+  --> $DIR/self_lifetime-async.rs:9:22
+   |
+LL |     async fn foo<'b>(self: &'b Foo<'a>) -> &() { self.0 }
+   |                      ^^^^
+   |
+note: first, the lifetime cannot outlive the lifetime 'a as defined on the impl at 8:6...
+  --> $DIR/self_lifetime-async.rs:8:6
+   |
+LL | impl<'a> Foo<'a> {
+   |      ^^
+   = note: ...so that the expression is assignable:
+           expected &Foo<'_>
+              found &'b Foo<'a>
+   = note: but, the lifetime must be valid for the static lifetime...
+   = note: ...so that the types are compatible:
+           expected &()
+              found &'static ()
+
+error[E0623]: lifetime mismatch
+  --> $DIR/self_lifetime-async.rs:16:52
+   |
+LL |     async fn bar<'a>(self: &Alias, arg: &'a ()) -> &() { arg }
+   |                            ------                  ^^^
+   |                            |                       |
+   |                            |                       ...but data from `arg` is returned here
+   |                            this parameter and the return type are declared with different lifetimes...
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0106`.

From 5ce8f7a1f98072d9df9fb562526151b83ecfe879 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Thu, 8 Aug 2019 18:21:08 +0200
Subject: [PATCH 5/5] Add async versions of arbitrary_self_types_pin_lifetime
 tests.

---
 ...arbitrary_self_types_pin_lifetime-async.rs | 37 ++++++++
 ...s_pin_lifetime_impl_trait-async.nll.stderr | 14 +++
 ...elf_types_pin_lifetime_impl_trait-async.rs | 16 ++++
 ...types_pin_lifetime_impl_trait-async.stderr | 20 +++++
 ...pes_pin_lifetime_mismatch-async.nll.stderr | 27 ++++++
 ..._self_types_pin_lifetime_mismatch-async.rs | 28 ++++++
 ...f_types_pin_lifetime_mismatch-async.stderr | 88 +++++++++++++++++++
 7 files changed, 230 insertions(+)
 create mode 100644 src/test/ui/self/arbitrary_self_types_pin_lifetime-async.rs
 create mode 100644 src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.nll.stderr
 create mode 100644 src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.rs
 create mode 100644 src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr
 create mode 100644 src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.nll.stderr
 create mode 100644 src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.rs
 create mode 100644 src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.stderr

diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime-async.rs b/src/test/ui/self/arbitrary_self_types_pin_lifetime-async.rs
new file mode 100644
index 0000000000000..b853f88a96dde
--- /dev/null
+++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime-async.rs
@@ -0,0 +1,37 @@
+// check-pass
+// edition:2018
+
+#![feature(async_await)]
+
+use std::pin::Pin;
+use std::task::{Context, Poll};
+
+struct Foo;
+
+impl Foo {
+    async fn pin_ref(self: Pin<&Self>) -> Pin<&Self> { self }
+
+    async fn pin_mut(self: Pin<&mut Self>) -> Pin<&mut Self> { self }
+
+    async fn pin_pin_pin_ref(self: Pin<Pin<Pin<&Self>>>) -> Pin<Pin<Pin<&Self>>> { self }
+
+    async fn pin_ref_impl_trait(self: Pin<&Self>) -> impl Clone + '_ { self }
+
+    fn b(self: Pin<&Foo>, f: &Foo) -> Pin<&Foo> { self }
+}
+
+type Alias<T> = Pin<T>;
+impl Foo {
+    async fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> Alias<&Self> { self }
+}
+
+// FIXME(Centril): extend with the rest of the non-`async fn` test
+// when we allow `async fn`s inside traits and trait implementations.
+
+fn main() {
+    let mut foo = Foo;
+    { Pin::new(&foo).pin_ref() };
+    { Pin::new(&mut foo).pin_mut() };
+    { Pin::new(Pin::new(Pin::new(&foo))).pin_pin_pin_ref() };
+    { Pin::new(&foo).pin_ref_impl_trait() };
+}
diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.nll.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.nll.stderr
new file mode 100644
index 0000000000000..2421632c664c1
--- /dev/null
+++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.nll.stderr
@@ -0,0 +1,14 @@
+error: lifetime may not live long enough
+  --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:10:48
+   |
+LL |     async fn f(self: Pin<&Self>) -> impl Clone { self }
+   |                          -                     ^^^^^^^^ returning this value requires that `'_` must outlive `'static`
+   |                          |
+   |                          lifetime `'_` defined here
+help: to allow this `impl Trait` to capture borrowed data with lifetime `'_`, add `'_` as a constraint
+   |
+LL |     async fn f(self: Pin<&Self>) -> impl Clone + '_ { self }
+   |                                     ^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.rs b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.rs
new file mode 100644
index 0000000000000..aecb82325c1f2
--- /dev/null
+++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.rs
@@ -0,0 +1,16 @@
+// edition:2018
+
+#![feature(async_await)]
+
+use std::pin::Pin;
+
+struct Foo;
+
+impl Foo {
+    async fn f(self: Pin<&Self>) -> impl Clone { self }
+    //~^ ERROR cannot infer an appropriate lifetime
+}
+
+fn main() {
+    { Pin::new(&Foo).f() };
+}
diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr
new file mode 100644
index 0000000000000..f0032449db14e
--- /dev/null
+++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr
@@ -0,0 +1,20 @@
+error: cannot infer an appropriate lifetime
+  --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:10:16
+   |
+LL |     async fn f(self: Pin<&Self>) -> impl Clone { self }
+   |                ^^^^                 ---------- this return type evaluates to the `'static` lifetime...
+   |                |
+   |                ...but this borrow...
+   |
+note: ...can't outlive the lifetime '_ as defined on the method body at 10:26
+  --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:10:26
+   |
+LL |     async fn f(self: Pin<&Self>) -> impl Clone { self }
+   |                          ^
+help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 10:26
+   |
+LL |     async fn f(self: Pin<&Self>) -> impl Clone + '_ { self }
+   |                                     ^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.nll.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.nll.stderr
new file mode 100644
index 0000000000000..6585609555675
--- /dev/null
+++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.nll.stderr
@@ -0,0 +1,27 @@
+error[E0106]: missing lifetime specifier
+  --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:10:45
+   |
+LL |     async fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f }
+   |                                             ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:15:60
+   |
+LL |     async fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) }
+   |                                                            ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:15:67
+   |
+LL |     async fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) }
+   |                                                                   ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0106`.
diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.rs b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.rs
new file mode 100644
index 0000000000000..93870b7cdcf28
--- /dev/null
+++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.rs
@@ -0,0 +1,28 @@
+// edition:2018
+
+#![feature(async_await)]
+
+use std::pin::Pin;
+
+struct Foo;
+
+impl Foo {
+    async fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f }
+    //~^ ERROR missing lifetime specifier
+    //~| ERROR cannot infer an appropriate lifetime
+    // FIXME: should be E0623?
+
+    async fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) }
+    //~^ ERROR missing lifetime specifier
+    //~| ERROR cannot infer an appropriate lifetime
+    //~| ERROR missing lifetime specifier
+    //~| ERROR cannot infer an appropriate lifetime
+    // FIXME: should be E0623?
+}
+
+type Alias<T> = Pin<T>;
+impl Foo {
+    async fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg } //~ ERROR E0623
+}
+
+fn main() {}
diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.stderr
new file mode 100644
index 0000000000000..c7d10e7fc780d
--- /dev/null
+++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.stderr
@@ -0,0 +1,88 @@
+error[E0106]: missing lifetime specifier
+  --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:10:45
+   |
+LL |     async fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f }
+   |                                             ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:15:60
+   |
+LL |     async fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) }
+   |                                                            ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:15:67
+   |
+LL |     async fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) }
+   |                                                                   ^
+   |
+   = note: return-position elided lifetimes require exactly one input-position elided lifetime, found multiple.
+
+error: cannot infer an appropriate lifetime
+  --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:10:33
+   |
+LL |     async fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f }
+   |                                 ^           ---- this return type evaluates to the `'static` lifetime...
+   |                                 |
+   |                                 ...but this borrow...
+   |
+note: ...can't outlive the lifetime '_ as defined on the method body at 10:26
+  --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:10:26
+   |
+LL |     async fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f }
+   |                          ^
+help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 10:26
+   |
+LL |     async fn a(self: Pin<&Foo>, f: &Foo) -> &Foo + '_ { f }
+   |                                             ^^^^^^^^^
+
+error: cannot infer an appropriate lifetime
+  --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:15:16
+   |
+LL |     async fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) }
+   |                ^^^^ ...but this borrow...             ----------------- this return type evaluates to the `'static` lifetime...
+   |
+note: ...can't outlive the lifetime '_ as defined on the method body at 15:26
+  --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:15:26
+   |
+LL |     async fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) }
+   |                          ^
+help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 15:26
+   |
+LL |     async fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) + '_ { (self, f) }
+   |                                                       ^^^^^^^^^^^^^^^^^^^^^^
+
+error: cannot infer an appropriate lifetime
+  --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:15:34
+   |
+LL |     async fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) }
+   |                                  ^                    ----------------- this return type evaluates to the `'static` lifetime...
+   |                                  |
+   |                                  ...but this borrow...
+   |
+note: ...can't outlive the lifetime '_ as defined on the method body at 15:26
+  --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:15:26
+   |
+LL |     async fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) }
+   |                          ^
+help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 15:26
+   |
+LL |     async fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) + '_ { (self, f) }
+   |                                                       ^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0623]: lifetime mismatch
+  --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:25:58
+   |
+LL |     async fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg }
+   |                                  -----                   ^^^
+   |                                  |                       |
+   |                                  |                       ...but data from `arg` is returned here
+   |                                  this parameter and the return type are declared with different lifetimes...
+
+error: aborting due to 7 previous errors
+
+For more information about this error, try `rustc --explain E0106`.