about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--RELEASES.md2
-rw-r--r--src/ci/azure-pipelines/auto.yml12
-rw-r--r--src/ci/azure-pipelines/steps/install-clang.yml2
-rw-r--r--src/ci/azure-pipelines/steps/install-sccache.yml4
-rw-r--r--src/ci/azure-pipelines/steps/install-windows-build-deps.yml6
-rw-r--r--src/ci/docker/armhf-gnu/Dockerfile2
-rwxr-xr-xsrc/ci/docker/dist-various-1/install-mips-musl.sh2
-rwxr-xr-xsrc/ci/docker/dist-various-2/build-wasi-toolchain.sh2
-rwxr-xr-xsrc/ci/docker/dist-x86_64-linux/build-openssl.sh2
-rwxr-xr-xsrc/ci/docker/dist-x86_64-netbsd/build-netbsd-toolchain.sh2
-rwxr-xr-xsrc/ci/docker/scripts/android-sdk-manager.py8
-rwxr-xr-xsrc/ci/docker/scripts/freebsd-toolchain.sh2
-rw-r--r--src/ci/docker/scripts/sccache.sh2
-rwxr-xr-xsrc/ci/install-awscli.sh2
-rwxr-xr-xsrc/ci/run.sh15
-rw-r--r--src/liballoc/collections/binary_heap.rs3
-rw-r--r--src/libcore/ascii.rs9
-rw-r--r--src/libcore/hash/mod.rs2
-rw-r--r--src/libcore/task/poll.rs28
-rw-r--r--src/librustc/hir/lowering.rs242
-rw-r--r--src/librustc/hir/lowering/item.rs34
-rw-r--r--src/librustc_errors/diagnostic.rs6
-rw-r--r--src/librustc_mir/const_eval.rs11
-rw-r--r--src/librustc_mir/interpret/intern.rs6
-rw-r--r--src/librustc_typeck/check/mod.rs84
-rw-r--r--src/libsyntax/parse/parser.rs2
-rw-r--r--src/libsyntax/parse/parser/expr.rs19
-rw-r--r--src/libsyntax/source_map.rs15
-rw-r--r--src/libsyntax/util/parser.rs2
-rw-r--r--src/test/ui/async-await/async-fn-elided-impl-lifetime-parameter.rs17
-rw-r--r--src/test/ui/async-await/issue-61949-self-return-type.rs28
-rw-r--r--src/test/ui/async-await/issue-61949-self-return-type.stderr8
-rw-r--r--src/test/ui/async-await/issues/issue-63388-1.nll.stderr24
-rw-r--r--src/test/ui/async-await/issues/issue-63388-1.rs20
-rw-r--r--src/test/ui/async-await/issues/issue-63388-1.stderr12
-rw-r--r--src/test/ui/async-await/issues/issue-63388-2.nll.stderr11
-rw-r--r--src/test/ui/async-await/issues/issue-63388-2.rs20
-rw-r--r--src/test/ui/async-await/issues/issue-63388-2.stderr29
-rw-r--r--src/test/ui/async-await/issues/issue-63388-3.rs19
-rw-r--r--src/test/ui/async-await/issues/issue-63388-4.rs12
-rw-r--r--src/test/ui/async-await/nested-in-impl.rs17
-rw-r--r--src/test/ui/c-variadic/variadic-ffi-no-fixed-args.rs6
-rw-r--r--src/test/ui/c-variadic/variadic-ffi-no-fixed-args.stderr8
-rw-r--r--src/test/ui/impl-trait/bound-normalization-fail.rs4
-rw-r--r--src/test/ui/impl-trait/bound-normalization-fail.stderr14
-rw-r--r--src/test/ui/in-band-lifetimes/nested-items.rs20
-rw-r--r--src/test/ui/issues/issue-13483.stderr4
-rw-r--r--src/test/ui/obsolete-in-place/bad.rs2
-rw-r--r--src/test/ui/obsolete-in-place/bad.stderr8
-rw-r--r--src/test/ui/placement-syntax.rs2
-rw-r--r--src/test/ui/placement-syntax.stderr10
-rw-r--r--src/test/ui/self/arbitrary_self_types_pin_lifetime-async.rs37
-rw-r--r--src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.nll.stderr14
-rw-r--r--src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.rs16
-rw-r--r--src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr20
-rw-r--r--src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.nll.stderr46
-rw-r--r--src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.rs22
-rw-r--r--src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.stderr29
-rw-r--r--src/test/ui/self/elision/README.md31
-rw-r--r--src/test/ui/self/elision/alias-async.rs39
-rw-r--r--src/test/ui/self/elision/assoc-async.rs43
-rw-r--r--src/test/ui/self/elision/lt-alias-async.rs41
-rw-r--r--src/test/ui/self/elision/lt-assoc-async.rs53
-rw-r--r--src/test/ui/self/elision/lt-ref-self-async.nll.stderr123
-rw-r--r--src/test/ui/self/elision/lt-ref-self-async.rs42
-rw-r--r--src/test/ui/self/elision/lt-ref-self-async.stderr56
-rw-r--r--src/test/ui/self/elision/lt-self-async.rs52
-rw-r--r--src/test/ui/self/elision/lt-struct-async.rs39
-rw-r--r--src/test/ui/self/elision/multiple-ref-self-async.rs46
-rw-r--r--src/test/ui/self/elision/ref-alias-async.rs42
-rw-r--r--src/test/ui/self/elision/ref-assoc-async.rs43
-rw-r--r--src/test/ui/self/elision/ref-mut-alias-async.rs38
-rw-r--r--src/test/ui/self/elision/ref-mut-self-async.nll.stderr123
-rw-r--r--src/test/ui/self/elision/ref-mut-self-async.rs42
-rw-r--r--src/test/ui/self/elision/ref-mut-self-async.stderr56
-rw-r--r--src/test/ui/self/elision/ref-mut-struct-async.nll.stderr103
-rw-r--r--src/test/ui/self/elision/ref-mut-struct-async.rs36
-rw-r--r--src/test/ui/self/elision/ref-mut-struct-async.stderr47
-rw-r--r--src/test/ui/self/elision/ref-self-async.nll.stderr143
-rw-r--r--src/test/ui/self/elision/ref-self-async.rs55
-rw-r--r--src/test/ui/self/elision/ref-self-async.stderr65
-rw-r--r--src/test/ui/self/elision/ref-struct-async.nll.stderr103
-rw-r--r--src/test/ui/self/elision/ref-struct-async.rs36
-rw-r--r--src/test/ui/self/elision/ref-struct-async.stderr47
-rw-r--r--src/test/ui/self/elision/self-async.rs39
-rw-r--r--src/test/ui/self/elision/struct-async.rs35
-rw-r--r--src/test/ui/self/self_lifetime-async.rs16
-rw-r--r--src/test/ui/suggestions/issue-61226.rs5
-rw-r--r--src/test/ui/suggestions/issue-61226.stderr9
89 files changed, 2462 insertions, 193 deletions
diff --git a/RELEASES.md b/RELEASES.md
index 7ad739d06d5..f26f6e6c888 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -22,7 +22,7 @@ Language
 - [You can now use `_` as an identifier for consts.][61347] e.g. You can write
   `const _: u32 = 5;`.
 - [You can now use `#[repr(align(X)]` on enums.][61229]
-- [The  `?`/_"Kleene"_ macro operator is now available in the
+- [The  `?` Kleene macro operator is now available in the
   2015 edition.][60932]
 
 Compiler
diff --git a/src/ci/azure-pipelines/auto.yml b/src/ci/azure-pipelines/auto.yml
index 687856cca6b..06fa3bd9f43 100644
--- a/src/ci/azure-pipelines/auto.yml
+++ b/src/ci/azure-pipelines/auto.yml
@@ -273,7 +273,7 @@ jobs:
         MSYS_BITS: 32
         RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu
         SCRIPT: make ci-subset-1
-        MINGW_URL: https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror
+        MINGW_URL: https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc
         MINGW_ARCHIVE: i686-6.3.0-release-posix-dwarf-rt_v5-rev2.7z
         MINGW_DIR: mingw32
         # FIXME(#59637)
@@ -283,14 +283,14 @@ jobs:
         MSYS_BITS: 32
         RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu
         SCRIPT: make ci-subset-2
-        MINGW_URL: https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror
+        MINGW_URL: https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc
         MINGW_ARCHIVE: i686-6.3.0-release-posix-dwarf-rt_v5-rev2.7z
         MINGW_DIR: mingw32
       x86_64-mingw-1:
         MSYS_BITS: 64
         SCRIPT: make ci-subset-1
         RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-gnu
-        MINGW_URL: https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror
+        MINGW_URL: https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc
         MINGW_ARCHIVE: x86_64-6.3.0-release-posix-seh-rt_v5-rev2.7z
         MINGW_DIR: mingw64
         # FIXME(#59637)
@@ -300,7 +300,7 @@ jobs:
         MSYS_BITS: 64
         SCRIPT: make ci-subset-2
         RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-gnu
-        MINGW_URL: https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror
+        MINGW_URL: https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc
         MINGW_ARCHIVE: x86_64-6.3.0-release-posix-seh-rt_v5-rev2.7z
         MINGW_DIR: mingw64
 
@@ -327,7 +327,7 @@ jobs:
         MSYS_BITS: 32
         RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu --enable-full-tools --enable-profiler
         SCRIPT: python x.py dist
-        MINGW_URL: https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror
+        MINGW_URL: https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc
         MINGW_ARCHIVE: i686-6.3.0-release-posix-dwarf-rt_v5-rev2.7z
         MINGW_DIR: mingw32
         DIST_REQUIRE_ALL_TOOLS: 1
@@ -336,7 +336,7 @@ jobs:
         MSYS_BITS: 64
         SCRIPT: python x.py dist
         RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-gnu --enable-full-tools --enable-profiler
-        MINGW_URL: https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror
+        MINGW_URL: https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc
         MINGW_ARCHIVE: x86_64-6.3.0-release-posix-seh-rt_v5-rev2.7z
         MINGW_DIR: mingw64
         DIST_REQUIRE_ALL_TOOLS: 1
diff --git a/src/ci/azure-pipelines/steps/install-clang.yml b/src/ci/azure-pipelines/steps/install-clang.yml
index 45ec767e0b8..14daf81b430 100644
--- a/src/ci/azure-pipelines/steps/install-clang.yml
+++ b/src/ci/azure-pipelines/steps/install-clang.yml
@@ -36,7 +36,7 @@ steps:
     set -e
     mkdir -p citools
     cd citools
-    curl -f https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror/LLVM-7.0.0-win64.tar.gz | tar xzf -
+    curl -f https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/LLVM-7.0.0-win64.tar.gz | tar xzf -
     echo "##vso[task.setvariable variable=RUST_CONFIGURE_ARGS]$RUST_CONFIGURE_ARGS --set llvm.clang-cl=`pwd`/clang-rust/bin/clang-cl.exe"
   condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'), eq(variables['MINGW_URL'],''))
   displayName: Install clang (Windows)
diff --git a/src/ci/azure-pipelines/steps/install-sccache.yml b/src/ci/azure-pipelines/steps/install-sccache.yml
index 427e50f571f..d4679c1c673 100644
--- a/src/ci/azure-pipelines/steps/install-sccache.yml
+++ b/src/ci/azure-pipelines/steps/install-sccache.yml
@@ -2,14 +2,14 @@ steps:
 
 - bash: |
     set -e
-    curl -fo /usr/local/bin/sccache https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror/2018-04-02-sccache-x86_64-apple-darwin
+    curl -fo /usr/local/bin/sccache https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/2018-04-02-sccache-x86_64-apple-darwin
     chmod +x /usr/local/bin/sccache
   displayName: Install sccache (OSX)
   condition: and(succeeded(), eq(variables['Agent.OS'], 'Darwin'))
 
 - script: |
     md sccache
-    powershell -Command "$ProgressPreference = 'SilentlyContinue'; iwr -outf sccache\sccache.exe https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror/2018-04-26-sccache-x86_64-pc-windows-msvc"
+    powershell -Command "$ProgressPreference = 'SilentlyContinue'; iwr -outf sccache\sccache.exe https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/2018-04-26-sccache-x86_64-pc-windows-msvc"
     echo ##vso[task.prependpath]%CD%\sccache
   displayName: Install sccache (Windows)
   condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
diff --git a/src/ci/azure-pipelines/steps/install-windows-build-deps.yml b/src/ci/azure-pipelines/steps/install-windows-build-deps.yml
index c42c2311b49..9aaeb4b79d6 100644
--- a/src/ci/azure-pipelines/steps/install-windows-build-deps.yml
+++ b/src/ci/azure-pipelines/steps/install-windows-build-deps.yml
@@ -4,7 +4,7 @@ steps:
 # https://github.com/wixtoolset/wix3 originally
 - bash: |
     set -e
-    curl -O https://rust-lang-ci2.s3-us-west-1.amazonaws.com/rust-ci-mirror/wix311-binaries.zip
+    curl -O https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/wix311-binaries.zip
     echo "##vso[task.setvariable variable=WIX]`pwd`/wix"
     mkdir -p wix/bin
     cd wix/bin
@@ -18,7 +18,7 @@ steps:
 # one is MSI installers and one is EXE, but they're not used so frequently at
 # this point anyway so perhaps it's a wash!
 - script: |
-    powershell -Command "$ProgressPreference = 'SilentlyContinue'; iwr -outf is-install.exe https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror/2017-08-22-is.exe"
+    powershell -Command "$ProgressPreference = 'SilentlyContinue'; iwr -outf is-install.exe https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/2017-08-22-is.exe"
     is-install.exe /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /SP-
     echo ##vso[task.prependpath]C:\Program Files (x86)\Inno Setup 5
   displayName: Install InnoSetup
@@ -109,7 +109,7 @@ steps:
 # Note that this is originally from the github releases patch of Ninja
 - script: |
     md ninja
-    powershell -Command "$ProgressPreference = 'SilentlyContinue'; iwr -outf 2017-03-15-ninja-win.zip https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror/2017-03-15-ninja-win.zip"
+    powershell -Command "$ProgressPreference = 'SilentlyContinue'; iwr -outf 2017-03-15-ninja-win.zip https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/2017-03-15-ninja-win.zip"
     7z x -oninja 2017-03-15-ninja-win.zip
     del 2017-03-15-ninja-win.zip
     set RUST_CONFIGURE_ARGS=%RUST_CONFIGURE_ARGS% --enable-ninja
diff --git a/src/ci/docker/armhf-gnu/Dockerfile b/src/ci/docker/armhf-gnu/Dockerfile
index 235920833f8..9493b336987 100644
--- a/src/ci/docker/armhf-gnu/Dockerfile
+++ b/src/ci/docker/armhf-gnu/Dockerfile
@@ -72,7 +72,7 @@ RUN arm-linux-gnueabihf-gcc addentropy.c -o rootfs/addentropy -static
 
 # TODO: What is this?!
 # Source of the file: https://github.com/vfdev-5/qemu-rpi2-vexpress/raw/master/vexpress-v2p-ca15-tc1.dtb
-RUN curl -O https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror/vexpress-v2p-ca15-tc1.dtb
+RUN curl -O https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/vexpress-v2p-ca15-tc1.dtb
 
 COPY scripts/sccache.sh /scripts/
 RUN sh /scripts/sccache.sh
diff --git a/src/ci/docker/dist-various-1/install-mips-musl.sh b/src/ci/docker/dist-various-1/install-mips-musl.sh
index 60a96e3b8e9..29cfb5d9608 100755
--- a/src/ci/docker/dist-various-1/install-mips-musl.sh
+++ b/src/ci/docker/dist-various-1/install-mips-musl.sh
@@ -5,7 +5,7 @@ mkdir /usr/local/mips-linux-musl
 # originally from
 # https://downloads.openwrt.org/snapshots/trunk/ar71xx/generic/
 # OpenWrt-Toolchain-ar71xx-generic_gcc-5.3.0_musl-1.1.16.Linux-x86_64.tar.bz2
-URL="https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror"
+URL="https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc"
 FILE="OpenWrt-Toolchain-ar71xx-generic_gcc-5.3.0_musl-1.1.16.Linux-x86_64.tar.bz2"
 curl -L "$URL/$FILE" | tar xjf - -C /usr/local/mips-linux-musl --strip-components=2
 
diff --git a/src/ci/docker/dist-various-2/build-wasi-toolchain.sh b/src/ci/docker/dist-various-2/build-wasi-toolchain.sh
index 7bf8946c4f1..f04ee781571 100755
--- a/src/ci/docker/dist-various-2/build-wasi-toolchain.sh
+++ b/src/ci/docker/dist-various-2/build-wasi-toolchain.sh
@@ -5,7 +5,7 @@
 set -ex
 
 # Originally from https://releases.llvm.org/8.0.0/clang+llvm-8.0.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz
-curl https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror/clang%2Bllvm-8.0.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz | \
+curl https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/clang%2Bllvm-8.0.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz | \
   tar xJf -
 export PATH=`pwd`/clang+llvm-8.0.0-x86_64-linux-gnu-ubuntu-14.04/bin:$PATH
 
diff --git a/src/ci/docker/dist-x86_64-linux/build-openssl.sh b/src/ci/docker/dist-x86_64-linux/build-openssl.sh
index 13dae616905..be8a6c93945 100755
--- a/src/ci/docker/dist-x86_64-linux/build-openssl.sh
+++ b/src/ci/docker/dist-x86_64-linux/build-openssl.sh
@@ -4,7 +4,7 @@ set -ex
 source shared.sh
 
 VERSION=1.0.2k
-URL=https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror/openssl-$VERSION.tar.gz
+URL=https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/openssl-$VERSION.tar.gz
 
 curl $URL | tar xzf -
 
diff --git a/src/ci/docker/dist-x86_64-netbsd/build-netbsd-toolchain.sh b/src/ci/docker/dist-x86_64-netbsd/build-netbsd-toolchain.sh
index 2e9b9dcc234..797f674b954 100755
--- a/src/ci/docker/dist-x86_64-netbsd/build-netbsd-toolchain.sh
+++ b/src/ci/docker/dist-x86_64-netbsd/build-netbsd-toolchain.sh
@@ -25,7 +25,7 @@ cd netbsd
 
 mkdir -p /x-tools/x86_64-unknown-netbsd/sysroot
 
-URL=https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror
+URL=https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc
 
 # Originally from ftp://ftp.netbsd.org/pub/NetBSD/NetBSD-$BSD/source/sets/*.tgz
 curl $URL/2018-03-01-netbsd-src.tgz | tar xzf -
diff --git a/src/ci/docker/scripts/android-sdk-manager.py b/src/ci/docker/scripts/android-sdk-manager.py
index 7c9a8b82e92..c9e2961f6eb 100755
--- a/src/ci/docker/scripts/android-sdk-manager.py
+++ b/src/ci/docker/scripts/android-sdk-manager.py
@@ -23,8 +23,9 @@ REPOSITORIES = [
 HOST_OS = "linux"
 
 # Mirroring options
-MIRROR_BUCKET = "rust-lang-ci2"
-MIRROR_BASE_DIR = "rust-ci-mirror/android/"
+MIRROR_BUCKET = "rust-lang-ci-mirrors"
+MIRROR_BUCKET_REGION = "us-west-1"
+MIRROR_BASE_DIR = "rustc/android/"
 
 import argparse
 import hashlib
@@ -144,7 +145,8 @@ def cli_install(args):
     lockfile = Lockfile(args.lockfile)
     for package in lockfile.packages.values():
         # Download the file from the mirror into a temp file
-        url = "https://" + MIRROR_BUCKET + ".s3.amazonaws.com/" + MIRROR_BASE_DIR
+        url = "https://" + MIRROR_BUCKET + ".s3-" + MIRROR_BUCKET_REGION + \
+              ".amazonaws.com/" + MIRROR_BASE_DIR
         downloaded = package.download(url)
         # Extract the file in a temporary directory
         extract_dir = tempfile.mkdtemp()
diff --git a/src/ci/docker/scripts/freebsd-toolchain.sh b/src/ci/docker/scripts/freebsd-toolchain.sh
index 8cef69d9c26..70155e770a9 100755
--- a/src/ci/docker/scripts/freebsd-toolchain.sh
+++ b/src/ci/docker/scripts/freebsd-toolchain.sh
@@ -59,7 +59,7 @@ done
 
 # Originally downloaded from:
 # https://download.freebsd.org/ftp/releases/${freebsd_arch}/${freebsd_version}-RELEASE/base.txz
-URL=https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror/2019-04-04-freebsd-${freebsd_arch}-${freebsd_version}-RELEASE-base.txz
+URL=https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/2019-04-04-freebsd-${freebsd_arch}-${freebsd_version}-RELEASE-base.txz
 curl "$URL" | tar xJf - -C "$sysroot" --wildcards "${files_to_extract[@]}"
 
 # Fix up absolute symlinks from the system image.  This can be removed
diff --git a/src/ci/docker/scripts/sccache.sh b/src/ci/docker/scripts/sccache.sh
index 194de3c339f..efeb0ed0d72 100644
--- a/src/ci/docker/scripts/sccache.sh
+++ b/src/ci/docker/scripts/sccache.sh
@@ -1,6 +1,6 @@
 set -ex
 
 curl -fo /usr/local/bin/sccache \
-  https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror/2018-04-02-sccache-x86_64-unknown-linux-musl
+  https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/2018-04-02-sccache-x86_64-unknown-linux-musl
 
 chmod +x /usr/local/bin/sccache
diff --git a/src/ci/install-awscli.sh b/src/ci/install-awscli.sh
index d491b9fbcdc..69c8d2e3099 100755
--- a/src/ci/install-awscli.sh
+++ b/src/ci/install-awscli.sh
@@ -16,7 +16,7 @@
 set -euo pipefail
 IFS=$'\n\t'
 
-MIRROR="https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror/2019-07-27-awscli.tar"
+MIRROR="https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/2019-07-27-awscli.tar"
 DEPS_DIR="/tmp/awscli-deps"
 
 pip="pip"
diff --git a/src/ci/run.sh b/src/ci/run.sh
index f1eb417cdf9..457ba971712 100755
--- a/src/ci/run.sh
+++ b/src/ci/run.sh
@@ -78,6 +78,21 @@ if [ "$RUST_RELEASE_CHANNEL" = "nightly" ] || [ "$DIST_REQUIRE_ALL_TOOLS" = "" ]
     RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-missing-tools"
 fi
 
+# Print the date from the local machine and the date from an external source to
+# check for clock drifts. An HTTP URL is used instead of HTTPS since on Azure
+# Pipelines it happened that the certificates were marked as expired.
+datecheck() {
+  echo "== clock drift check =="
+  echo -n "  local time: "
+  date
+  echo -n "  network time: "
+  curl -fs --head http://detectportal.firefox.com/success.txt | grep ^Date: \
+      | sed 's/Date: //g' || true
+  echo "== end clock drift check =="
+}
+datecheck
+trap datecheck EXIT
+
 # We've had problems in the past of shell scripts leaking fds into the sccache
 # server (#48192) which causes Cargo to erroneously think that a build script
 # hasn't finished yet. Try to solve that problem by starting a very long-lived
diff --git a/src/liballoc/collections/binary_heap.rs b/src/liballoc/collections/binary_heap.rs
index 9f531f5b83c..3d04f30e7bd 100644
--- a/src/liballoc/collections/binary_heap.rs
+++ b/src/liballoc/collections/binary_heap.rs
@@ -1163,6 +1163,9 @@ impl<T> FusedIterator for Drain<'_, T> {}
 
 #[stable(feature = "binary_heap_extras_15", since = "1.5.0")]
 impl<T: Ord> From<Vec<T>> for BinaryHeap<T> {
+    /// Converts a `Vec<T>` into a `BinaryHeap<T>`.
+    ///
+    /// This conversion happens in-place, and has `O(n)` time complexity.
     fn from(vec: Vec<T>) -> BinaryHeap<T> {
         let mut heap = BinaryHeap { data: vec };
         heap.rebuild();
diff --git a/src/libcore/ascii.rs b/src/libcore/ascii.rs
index e6a6fdde540..4087333e2cf 100644
--- a/src/libcore/ascii.rs
+++ b/src/libcore/ascii.rs
@@ -14,6 +14,7 @@
 use crate::fmt;
 use crate::ops::Range;
 use crate::iter::FusedIterator;
+use crate::str::from_utf8_unchecked;
 
 /// An iterator over the escaped version of a byte.
 ///
@@ -22,6 +23,7 @@ use crate::iter::FusedIterator;
 ///
 /// [`escape_default`]: fn.escape_default.html
 #[stable(feature = "rust1", since = "1.0.0")]
+#[derive(Clone)]
 pub struct EscapeDefault {
     range: Range<usize>,
     data: [u8; 4],
@@ -130,6 +132,13 @@ impl ExactSizeIterator for EscapeDefault {}
 #[stable(feature = "fused", since = "1.26.0")]
 impl FusedIterator for EscapeDefault {}
 
+#[stable(feature = "ascii_escape_display", since = "1.39.0")]
+impl fmt::Display for EscapeDefault {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.write_str(unsafe { from_utf8_unchecked(&self.data[self.range.clone()]) })
+    }
+}
+
 #[stable(feature = "std_debug", since = "1.16.0")]
 impl fmt::Debug for EscapeDefault {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
diff --git a/src/libcore/hash/mod.rs b/src/libcore/hash/mod.rs
index c4cbf40a93a..685540ba6fc 100644
--- a/src/libcore/hash/mod.rs
+++ b/src/libcore/hash/mod.rs
@@ -553,8 +553,6 @@ impl<H> PartialEq for BuildHasherDefault<H> {
 #[stable(since = "1.29.0", feature = "build_hasher_eq")]
 impl<H> Eq for BuildHasherDefault<H> {}
 
-//////////////////////////////////////////////////////////////////////////////
-
 mod impls {
     use crate::mem;
     use crate::slice;
diff --git a/src/libcore/task/poll.rs b/src/libcore/task/poll.rs
index 3db70d5e764..fec17c4d1a4 100644
--- a/src/libcore/task/poll.rs
+++ b/src/libcore/task/poll.rs
@@ -81,6 +81,34 @@ impl<T, E> Poll<Result<T, E>> {
     }
 }
 
+impl<T, E> Poll<Option<Result<T, E>>> {
+    /// Changes the success value of this `Poll` with the closure provided.
+    #[unstable(feature = "poll_map", issue = "63514")]
+    pub fn map_ok<U, F>(self, f: F) -> Poll<Option<Result<U, E>>>
+        where F: FnOnce(T) -> U
+    {
+        match self {
+            Poll::Ready(Some(Ok(t))) => Poll::Ready(Some(Ok(f(t)))),
+            Poll::Ready(Some(Err(e))) => Poll::Ready(Some(Err(e))),
+            Poll::Ready(None) => Poll::Ready(None),
+            Poll::Pending => Poll::Pending,
+        }
+    }
+
+    /// Changes the error value of this `Poll` with the closure provided.
+    #[unstable(feature = "poll_map", issue = "63514")]
+    pub fn map_err<U, F>(self, f: F) -> Poll<Option<Result<T, U>>>
+        where F: FnOnce(E) -> U
+    {
+        match self {
+            Poll::Ready(Some(Ok(t))) => Poll::Ready(Some(Ok(t))),
+            Poll::Ready(Some(Err(e))) => Poll::Ready(Some(Err(f(e)))),
+            Poll::Ready(None) => Poll::Ready(None),
+            Poll::Pending => Poll::Pending,
+        }
+    }
+}
+
 #[stable(feature = "futures_api", since = "1.36.0")]
 impl<T> From<T> for Poll<T> {
     fn from(t: T) -> Poll<T> {
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index fe69c9e6346..a1f38d7dd13 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -136,7 +136,10 @@ pub struct LoweringContext<'a> {
     /// When `is_collectin_in_band_lifetimes` is true, each lifetime is checked
     /// against this list to see if it is already in-scope, or if a definition
     /// needs to be created for it.
-    in_scope_lifetimes: Vec<Ident>,
+    ///
+    /// We always store a `modern()` version of the param-name in this
+    /// vector.
+    in_scope_lifetimes: Vec<ParamName>,
 
     current_module: NodeId,
 
@@ -337,49 +340,6 @@ enum AnonymousLifetimeMode {
 
     /// Pass responsibility to `resolve_lifetime` code for all cases.
     PassThrough,
-
-    /// Used in the return types of `async fn` where there exists
-    /// exactly one argument-position elided lifetime.
-    ///
-    /// In `async fn`, we lower the arguments types using the `CreateParameter`
-    /// mode, meaning that non-`dyn` elided lifetimes are assigned a fresh name.
-    /// If any corresponding elided lifetimes appear in the output, we need to
-    /// replace them with references to the fresh name assigned to the corresponding
-    /// elided lifetime in the arguments.
-    ///
-    /// For **Modern cases**, replace the anonymous parameter with a
-    /// reference to a specific freshly-named lifetime that was
-    /// introduced in argument
-    ///
-    /// For **Dyn Bound** cases, pass responsibility to
-    /// `resole_lifetime` code.
-    Replace(LtReplacement),
-}
-
-/// The type of elided lifetime replacement to perform on `async fn` return types.
-#[derive(Copy, Clone)]
-enum LtReplacement {
-    /// Fresh name introduced by the single non-dyn elided lifetime
-    /// in the arguments of the async fn.
-    Some(ParamName),
-
-    /// There is no single non-dyn elided lifetime because no lifetimes
-    /// appeared in the arguments.
-    NoLifetimes,
-
-    /// There is no single non-dyn elided lifetime because multiple
-    /// lifetimes appeared in the arguments.
-    MultipleLifetimes,
-}
-
-/// Calculates the `LtReplacement` to use for elided lifetimes in the return
-/// type based on the fresh elided lifetimes introduced in argument position.
-fn get_elided_lt_replacement(arg_position_lifetimes: &[(Span, ParamName)]) -> LtReplacement {
-    match arg_position_lifetimes {
-        [] => LtReplacement::NoLifetimes,
-        [(_span, param)] => LtReplacement::Some(*param),
-        _ => LtReplacement::MultipleLifetimes,
-    }
 }
 
 struct ImplTraitTypeIdVisitor<'a> { ids: &'a mut SmallVec<[NodeId; 1]> }
@@ -865,7 +825,7 @@ impl<'a> LoweringContext<'a> {
             return;
         }
 
-        if self.in_scope_lifetimes.contains(&ident.modern()) {
+        if self.in_scope_lifetimes.contains(&ParamName::Plain(ident.modern())) {
             return;
         }
 
@@ -899,7 +859,7 @@ impl<'a> LoweringContext<'a> {
     {
         let old_len = self.in_scope_lifetimes.len();
         let lt_def_names = params.iter().filter_map(|param| match param.kind {
-            GenericParamKind::Lifetime { .. } => Some(param.ident.modern()),
+            GenericParamKind::Lifetime { .. } => Some(ParamName::Plain(param.ident.modern())),
             _ => None,
         });
         self.in_scope_lifetimes.extend(lt_def_names);
@@ -1953,8 +1913,7 @@ impl<'a> LoweringContext<'a> {
                         err.emit();
                     }
                     AnonymousLifetimeMode::PassThrough |
-                    AnonymousLifetimeMode::ReportError |
-                    AnonymousLifetimeMode::Replace(_) => {
+                    AnonymousLifetimeMode::ReportError => {
                         self.sess.buffer_lint_with_diagnostic(
                             ELIDED_LIFETIMES_IN_PATHS,
                             CRATE_NODE_ID,
@@ -2141,7 +2100,6 @@ impl<'a> LoweringContext<'a> {
 
         // Remember how many lifetimes were already around so that we can
         // only look at the lifetime parameters introduced by the arguments.
-        let lifetime_count_before_args = self.lifetimes_to_define.len();
         let inputs = self.with_anonymous_lifetime_mode(lt_mode, |this| {
             decl.inputs
                 .iter()
@@ -2156,16 +2114,10 @@ impl<'a> LoweringContext<'a> {
         });
 
         let output = if let Some(ret_id) = make_ret_async {
-            // Calculate the `LtReplacement` to use for any return-position elided
-            // lifetimes based on the elided lifetime parameters introduced in the args.
-            let lt_replacement = get_elided_lt_replacement(
-                &self.lifetimes_to_define[lifetime_count_before_args..]
-            );
             self.lower_async_fn_ret_ty(
                 &decl.output,
                 in_band_ty_params.expect("`make_ret_async` but no `fn_def_id`").0,
                 ret_id,
-                lt_replacement,
             )
         } else {
             match decl.output {
@@ -2230,7 +2182,6 @@ impl<'a> LoweringContext<'a> {
         output: &FunctionRetTy,
         fn_def_id: DefId,
         opaque_ty_node_id: NodeId,
-        elided_lt_replacement: LtReplacement,
     ) -> hir::FunctionRetTy {
         let span = output.span();
 
@@ -2248,9 +2199,65 @@ impl<'a> LoweringContext<'a> {
 
         self.allocate_hir_id_counter(opaque_ty_node_id);
 
+        // When we create the opaque type for this async fn, it is going to have
+        // to capture all the lifetimes involved in the signature (including in the
+        // return type). This is done by introducing lifetime parameters for:
+        //
+        // - all the explicitly declared lifetimes from the impl and function itself;
+        // - all the elided lifetimes in the fn arguments;
+        // - all the elided lifetimes in the return type.
+        //
+        // So for example in this snippet:
+        //
+        // ```rust
+        // impl<'a> Foo<'a> {
+        //   async fn bar<'b>(&self, x: &'b Vec<f64>, y: &str) -> &u32 {
+        //   //               ^ '0                       ^ '1     ^ '2
+        //   // elided lifetimes used below
+        //   }
+        // }
+        // ```
+        //
+        // we would create an opaque type like:
+        //
+        // ```
+        // type Bar<'a, 'b, '0, '1, '2> = impl Future<Output = &'2 u32>;
+        // ```
+        //
+        // and we would then desugar `bar` to the equivalent of:
+        //
+        // ```rust
+        // impl<'a> Foo<'a> {
+        //   fn bar<'b, '0, '1>(&'0 self, x: &'b Vec<f64>, y: &'1 str) -> Bar<'a, 'b, '0, '1, '_>
+        // }
+        // ```
+        //
+        // Note that the final parameter to `Bar` is `'_`, not `'2` --
+        // this is because the elided lifetimes from the return type
+        // should be figured out using the ordinary elision rules, and
+        // this desugaring achieves that.
+        //
+        // The variable `input_lifetimes_count` tracks the number of
+        // lifetime parameters to the opaque type *not counting* those
+        // lifetimes elided in the return type. This includes those
+        // that are explicitly declared (`in_scope_lifetimes`) and
+        // those elided lifetimes we found in the arguments (current
+        // content of `lifetimes_to_define`). Next, we will process
+        // the return type, which will cause `lifetimes_to_define` to
+        // grow.
+        let input_lifetimes_count = self.in_scope_lifetimes.len() + self.lifetimes_to_define.len();
+
         let (opaque_ty_id, lifetime_params) = self.with_hir_id_owner(opaque_ty_node_id, |this| {
+            // We have to be careful to get elision right here. The
+            // idea is that we create a lifetime parameter for each
+            // lifetime in the return type.  So, given a return type
+            // like `async fn foo(..) -> &[&u32]`, we lower to `impl
+            // Future<Output = &'1 [ &'2 u32 ]>`.
+            //
+            // Then, we will create `fn foo(..) -> Foo<'_, '_>`, and
+            // hence the elision takes place at the fn site.
             let future_bound = this.with_anonymous_lifetime_mode(
-                AnonymousLifetimeMode::Replace(elided_lt_replacement),
+                AnonymousLifetimeMode::CreateParameter,
                 |this| this.lower_async_fn_output_type_to_future_bound(
                     output,
                     fn_def_id,
@@ -2267,10 +2274,14 @@ impl<'a> LoweringContext<'a> {
             let lifetime_params: Vec<(Span, ParamName)> =
                 this.in_scope_lifetimes
                     .iter().cloned()
-                    .map(|ident| (ident.span, ParamName::Plain(ident)))
+                    .map(|name| (name.ident().span, name))
                     .chain(this.lifetimes_to_define.iter().cloned())
                     .collect();
 
+            debug!("lower_async_fn_ret_ty: in_scope_lifetimes={:#?}", this.in_scope_lifetimes);
+            debug!("lower_async_fn_ret_ty: lifetimes_to_define={:#?}", this.lifetimes_to_define);
+            debug!("lower_async_fn_ret_ty: lifetime_params={:#?}", lifetime_params);
+
             let generic_params =
                 lifetime_params
                     .iter().cloned()
@@ -2304,19 +2315,52 @@ impl<'a> LoweringContext<'a> {
             (opaque_ty_id, lifetime_params)
         });
 
-        let generic_args =
-            lifetime_params
-                .iter().cloned()
-                .map(|(span, hir_name)| {
-                    GenericArg::Lifetime(hir::Lifetime {
-                        hir_id: self.next_id(),
-                        span,
-                        name: hir::LifetimeName::Param(hir_name),
-                    })
+        // As documented above on the variable
+        // `input_lifetimes_count`, we need to create the lifetime
+        // arguments to our opaque type. Continuing with our example,
+        // we're creating the type arguments for the return type:
+        //
+        // ```
+        // Bar<'a, 'b, '0, '1, '_>
+        // ```
+        //
+        // For the "input" lifetime parameters, we wish to create
+        // references to the parameters themselves, including the
+        // "implicit" ones created from parameter types (`'a`, `'b`,
+        // '`0`, `'1`).
+        //
+        // For the "output" lifetime parameters, we just want to
+        // generate `'_`.
+        let mut generic_args: Vec<_> =
+            lifetime_params[..input_lifetimes_count]
+            .iter()
+            .map(|&(span, hir_name)| {
+                // Input lifetime like `'a` or `'1`:
+                GenericArg::Lifetime(hir::Lifetime {
+                    hir_id: self.next_id(),
+                    span,
+                    name: hir::LifetimeName::Param(hir_name),
                 })
-                .collect();
+            })
+            .collect();
+        generic_args.extend(
+            lifetime_params[input_lifetimes_count..]
+            .iter()
+            .map(|&(span, _)| {
+                // Output lifetime like `'_`.
+                GenericArg::Lifetime(hir::Lifetime {
+                    hir_id: self.next_id(),
+                    span,
+                    name: hir::LifetimeName::Implicit,
+                })
+            })
+        );
 
-        let opaque_ty_ref = hir::TyKind::Def(hir::ItemId { id: opaque_ty_id }, generic_args);
+        // Create the `Foo<...>` refernece itself. Note that the `type
+        // Foo = impl Trait` is, internally, created as a child of the
+        // async fn, so the *type parameters* are inherited.  It's
+        // only the lifetime parameters that we must supply.
+        let opaque_ty_ref = hir::TyKind::Def(hir::ItemId { id: opaque_ty_id }, generic_args.into());
 
         hir::FunctionRetTy::Return(P(hir::Ty {
             node: opaque_ty_ref,
@@ -2412,11 +2456,6 @@ impl<'a> LoweringContext<'a> {
                     }
 
                     AnonymousLifetimeMode::ReportError => self.new_error_lifetime(Some(l.id), span),
-
-                    AnonymousLifetimeMode::Replace(replacement) => {
-                        let hir_id = self.lower_node_id(l.id);
-                        self.replace_elided_lifetime(hir_id, span, replacement)
-                    }
                 },
             ident => {
                 self.maybe_collect_in_band_lifetime(ident);
@@ -2439,39 +2478,6 @@ impl<'a> LoweringContext<'a> {
         }
     }
 
-    /// Replace a return-position elided lifetime with the elided lifetime
-    /// from the arguments.
-    fn replace_elided_lifetime(
-        &mut self,
-        hir_id: hir::HirId,
-        span: Span,
-        replacement: LtReplacement,
-    ) -> hir::Lifetime {
-        let multiple_or_none = match replacement {
-            LtReplacement::Some(name) => {
-                return hir::Lifetime {
-                    hir_id,
-                    span,
-                    name: hir::LifetimeName::Param(name),
-                };
-            }
-            LtReplacement::MultipleLifetimes => "multiple",
-            LtReplacement::NoLifetimes => "none",
-        };
-
-        let mut err = crate::middle::resolve_lifetime::report_missing_lifetime_specifiers(
-            self.sess,
-            span,
-            1,
-        );
-        err.note(&format!(
-            "return-position elided lifetimes require exactly one \
-             input-position elided lifetime, found {}.", multiple_or_none));
-        err.emit();
-
-        hir::Lifetime { hir_id, span, name: hir::LifetimeName::Error }
-    }
-
     fn lower_generic_params(
         &mut self,
         params: &[GenericParam],
@@ -3174,10 +3180,6 @@ impl<'a> LoweringContext<'a> {
             AnonymousLifetimeMode::ReportError => self.new_error_lifetime(None, span),
 
             AnonymousLifetimeMode::PassThrough => self.new_implicit_lifetime(span),
-
-            AnonymousLifetimeMode::Replace(replacement) => {
-                self.new_replacement_lifetime(replacement, span)
-            }
         }
     }
 
@@ -3231,10 +3233,6 @@ impl<'a> LoweringContext<'a> {
             // This is the normal case.
             AnonymousLifetimeMode::PassThrough => self.new_implicit_lifetime(span),
 
-            AnonymousLifetimeMode::Replace(replacement) => {
-                self.new_replacement_lifetime(replacement, span)
-            }
-
             AnonymousLifetimeMode::ReportError => self.new_error_lifetime(None, span),
         }
     }
@@ -3266,25 +3264,11 @@ impl<'a> LoweringContext<'a> {
 
             // This is the normal case.
             AnonymousLifetimeMode::PassThrough => {}
-
-            // We don't need to do any replacement here as this lifetime
-            // doesn't refer to an elided lifetime elsewhere in the function
-            // signature.
-            AnonymousLifetimeMode::Replace(_) => {}
         }
 
         self.new_implicit_lifetime(span)
     }
 
-    fn new_replacement_lifetime(
-        &mut self,
-        replacement: LtReplacement,
-        span: Span,
-    ) -> hir::Lifetime {
-        let hir_id = self.next_id();
-        self.replace_elided_lifetime(hir_id, span, replacement)
-    }
-
     fn new_implicit_lifetime(&mut self, span: Span) -> hir::Lifetime {
         hir::Lifetime {
             hir_id: self.next_id(),
diff --git a/src/librustc/hir/lowering/item.rs b/src/librustc/hir/lowering/item.rs
index 6b717e75199..dd95d99d4e1 100644
--- a/src/librustc/hir/lowering/item.rs
+++ b/src/librustc/hir/lowering/item.rs
@@ -60,10 +60,12 @@ impl<'tcx, 'interner> Visitor<'tcx> for ItemLowerer<'tcx, 'interner> {
     fn visit_item(&mut self, item: &'tcx Item) {
         let mut item_hir_id = None;
         self.lctx.with_hir_id_owner(item.id, |lctx| {
-            if let Some(hir_item) = lctx.lower_item(item) {
-                item_hir_id = Some(hir_item.hir_id);
-                lctx.insert_item(hir_item);
-            }
+            lctx.without_in_scope_lifetime_defs(|lctx| {
+                if let Some(hir_item) = lctx.lower_item(item) {
+                    item_hir_id = Some(hir_item.hir_id);
+                    lctx.insert_item(hir_item);
+                }
+            })
         });
 
         if let Some(hir_id) = item_hir_id {
@@ -123,7 +125,7 @@ impl LoweringContext<'_> {
             _ => &[],
         };
         let lt_def_names = parent_generics.iter().filter_map(|param| match param.kind {
-            hir::GenericParamKind::Lifetime { .. } => Some(param.name.ident().modern()),
+            hir::GenericParamKind::Lifetime { .. } => Some(param.name.modern()),
             _ => None,
         });
         self.in_scope_lifetimes.extend(lt_def_names);
@@ -134,6 +136,28 @@ impl LoweringContext<'_> {
         res
     }
 
+    // Clears (and restores) the `in_scope_lifetimes` field. Used when
+    // visiting nested items, which never inherit in-scope lifetimes
+    // from their surrounding environment.
+    fn without_in_scope_lifetime_defs<T>(
+        &mut self,
+        f: impl FnOnce(&mut LoweringContext<'_>) -> T,
+    ) -> T {
+        let old_in_scope_lifetimes = std::mem::replace(&mut self.in_scope_lifetimes, vec![]);
+
+        // this vector is only used when walking over impl headers,
+        // input types, and the like, and should not be non-empty in
+        // between items
+        assert!(self.lifetimes_to_define.is_empty());
+
+        let res = f(self);
+
+        assert!(self.in_scope_lifetimes.is_empty());
+        self.in_scope_lifetimes = old_in_scope_lifetimes;
+
+        res
+    }
+
     pub(super) fn lower_mod(&mut self, m: &Mod) -> hir::Mod {
         hir::Mod {
             inner: m.inner,
diff --git a/src/librustc_errors/diagnostic.rs b/src/librustc_errors/diagnostic.rs
index 424d7c00383..e11ba75da98 100644
--- a/src/librustc_errors/diagnostic.rs
+++ b/src/librustc_errors/diagnostic.rs
@@ -120,6 +120,9 @@ impl Diagnostic {
     }
 
     /// Adds a span/label to be included in the resulting snippet.
+    /// This label will be shown together with the original span/label used when creating the
+    /// diagnostic, *not* a span added by one of the `span_*` methods.
+    ///
     /// This is pushed onto the `MultiSpan` that was created when the
     /// diagnostic was first built. If you don't call this function at
     /// all, and you just supplied a `Span` to create the diagnostic,
@@ -196,6 +199,7 @@ impl Diagnostic {
         self
     }
 
+    /// Prints the span with a note above it.
     pub fn span_note<S: Into<MultiSpan>>(&mut self,
                                          sp: S,
                                          msg: &str)
@@ -209,6 +213,7 @@ impl Diagnostic {
         self
     }
 
+    /// Prints the span with a warn above it.
     pub fn span_warn<S: Into<MultiSpan>>(&mut self,
                                          sp: S,
                                          msg: &str)
@@ -222,6 +227,7 @@ impl Diagnostic {
         self
     }
 
+    /// Prints the span with some help above it.
     pub fn span_help<S: Into<MultiSpan>>(&mut self,
                                          sp: S,
                                          msg: &str)
diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs
index 36d80d0cb57..52225ea8f02 100644
--- a/src/librustc_mir/const_eval.rs
+++ b/src/librustc_mir/const_eval.rs
@@ -540,6 +540,12 @@ pub fn error_to_const_error<'mir, 'tcx>(
     ConstEvalErr { error: error.kind, stacktrace, span: ecx.tcx.span }
 }
 
+pub fn note_on_undefined_behavior_error() -> &'static str {
+    "The rules on what exactly is undefined behavior aren't clear, \
+    so this check might be overzealous. Please open an issue on the rust compiler \
+    repository if you believe it should not be considered undefined behavior"
+}
+
 fn validate_and_turn_into_const<'tcx>(
     tcx: TyCtxt<'tcx>,
     constant: RawConst<'tcx>,
@@ -579,10 +585,7 @@ fn validate_and_turn_into_const<'tcx>(
         let err = error_to_const_error(&ecx, error);
         match err.struct_error(ecx.tcx, "it is undefined behavior to use this value") {
             Ok(mut diag) => {
-                diag.note("The rules on what exactly is undefined behavior aren't clear, \
-                    so this check might be overzealous. Please open an issue on the rust compiler \
-                    repository if you believe it should not be considered undefined behavior",
-                );
+                diag.note(note_on_undefined_behavior_error());
                 diag.emit();
                 ErrorHandled::Reported
             }
diff --git a/src/librustc_mir/interpret/intern.rs b/src/librustc_mir/interpret/intern.rs
index 1074ab941a7..32ba70a81c9 100644
--- a/src/librustc_mir/interpret/intern.rs
+++ b/src/librustc_mir/interpret/intern.rs
@@ -296,11 +296,7 @@ pub fn intern_const_alloc_recursive(
                 let err = crate::const_eval::error_to_const_error(&ecx, error);
                 match err.struct_error(ecx.tcx, "it is undefined behavior to use this value") {
                     Ok(mut diag) => {
-                        diag.note("The rules on what exactly is undefined behavior aren't clear, \
-                            so this check might be overzealous. Please open an issue on the rust \
-                            compiler repository if you believe it should not be considered \
-                            undefined behavior",
-                        );
+                        diag.note(crate::const_eval::note_on_undefined_behavior_error());
                         diag.emit();
                     }
                     Err(ErrorHandled::TooGeneric) |
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 4fb28db6e94..14fc0d6347e 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -1325,12 +1325,94 @@ fn check_union(tcx: TyCtxt<'_>, id: hir::HirId, span: Span) {
     check_packed(tcx, span, def_id);
 }
 
+/// Checks that an opaque type does not contain cycles and does not use `Self` or `T::Foo`
+/// projections that would result in "inheriting lifetimes".
 fn check_opaque<'tcx>(
     tcx: TyCtxt<'tcx>,
     def_id: DefId,
     substs: SubstsRef<'tcx>,
     span: Span,
-    origin: &hir::OpaqueTyOrigin
+    origin: &hir::OpaqueTyOrigin,
+) {
+    check_opaque_for_inheriting_lifetimes(tcx, def_id, span);
+    check_opaque_for_cycles(tcx, def_id, substs, span, origin);
+}
+
+/// Checks that an opaque type does not use `Self` or `T::Foo` projections that would result
+/// in "inheriting lifetimes".
+fn check_opaque_for_inheriting_lifetimes(
+    tcx: TyCtxt<'tcx>,
+    def_id: DefId,
+    span: Span,
+) {
+    let item = tcx.hir().expect_item(
+        tcx.hir().as_local_hir_id(def_id).expect("opaque type is not local"));
+    debug!("check_opaque_for_inheriting_lifetimes: def_id={:?} span={:?} item={:?}",
+           def_id, span, item);
+
+    #[derive(Debug)]
+    struct ProhibitOpaqueVisitor<'tcx> {
+        opaque_identity_ty: Ty<'tcx>,
+        generics: &'tcx ty::Generics,
+    };
+
+    impl<'tcx> ty::fold::TypeVisitor<'tcx> for ProhibitOpaqueVisitor<'tcx> {
+        fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
+            debug!("check_opaque_for_inheriting_lifetimes: (visit_ty) t={:?}", t);
+            if t == self.opaque_identity_ty { false } else { t.super_visit_with(self) }
+        }
+
+        fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
+            debug!("check_opaque_for_inheriting_lifetimes: (visit_region) r={:?}", r);
+            if let RegionKind::ReEarlyBound(ty::EarlyBoundRegion { index, .. }) = r {
+                return *index < self.generics.parent_count as u32;
+            }
+
+            r.super_visit_with(self)
+        }
+    }
+
+    let prohibit_opaque = match item.node {
+        ItemKind::OpaqueTy(hir::OpaqueTy { origin: hir::OpaqueTyOrigin::AsyncFn, .. }) |
+        ItemKind::OpaqueTy(hir::OpaqueTy { origin: hir::OpaqueTyOrigin::FnReturn, .. }) => {
+            let mut visitor = ProhibitOpaqueVisitor {
+                opaque_identity_ty: tcx.mk_opaque(
+                    def_id, InternalSubsts::identity_for_item(tcx, def_id)),
+                generics: tcx.generics_of(def_id),
+            };
+            debug!("check_opaque_for_inheriting_lifetimes: visitor={:?}", visitor);
+
+            tcx.predicates_of(def_id).predicates.iter().any(
+                |(predicate, _)| predicate.visit_with(&mut visitor))
+        },
+        _ => false,
+    };
+
+    debug!("check_opaque_for_inheriting_lifetimes: prohibit_opaque={:?}", prohibit_opaque);
+    if prohibit_opaque {
+        let is_async = match item.node {
+            ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => match origin {
+                hir::OpaqueTyOrigin::AsyncFn => true,
+                _ => false,
+            },
+            _ => unreachable!(),
+        };
+
+        tcx.sess.span_err(span, &format!(
+            "`{}` return type cannot contain a projection or `Self` that references lifetimes from \
+             a parent scope",
+            if is_async { "async fn" } else { "impl Trait" },
+        ));
+    }
+}
+
+/// Checks that an opaque type does not contain cycles.
+fn check_opaque_for_cycles<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    def_id: DefId,
+    substs: SubstsRef<'tcx>,
+    span: Span,
+    origin: &hir::OpaqueTyOrigin,
 ) {
     if let Err(partially_expanded_type) = tcx.try_expand_impl_trait_type(def_id, substs) {
         if let hir::OpaqueTyOrigin::AsyncFn = origin {
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 1c1428c5713..2286e74e633 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -1236,7 +1236,7 @@ impl<'a> Parser<'a> {
 
         let args: Vec<_> = args.into_iter().filter_map(|x| x).collect();
 
-        if c_variadic && args.is_empty() {
+        if c_variadic && args.len() <= 1 {
             self.span_err(sp,
                           "C-variadic function must be declared with at least one named argument");
         }
diff --git a/src/libsyntax/parse/parser/expr.rs b/src/libsyntax/parse/parser/expr.rs
index 4432c1329cb..5376ac2eeee 100644
--- a/src/libsyntax/parse/parser/expr.rs
+++ b/src/libsyntax/parse/parser/expr.rs
@@ -224,6 +224,10 @@ impl<'a> Parser<'a> {
                 self.err_dotdotdot_syntax(self.token.span);
             }
 
+            if self.token == token::LArrow {
+                self.err_larrow_operator(self.token.span);
+            }
+
             self.bump();
             if op.is_comparison() {
                 self.check_no_chained_comparison(&lhs, &op);
@@ -1199,7 +1203,7 @@ impl<'a> Parser<'a> {
         if self.eat_keyword(kw::Else) || !cond.returns() {
             let sp = self.sess.source_map().next_point(lo);
             let mut err = self.diagnostic()
-                .struct_span_err(sp, "missing condition for `if` statemement");
+                .struct_span_err(sp, "missing condition for `if` expression");
             err.span_label(sp, "expected if condition here");
             return Err(err)
         }
@@ -1702,6 +1706,19 @@ impl<'a> Parser<'a> {
             .emit();
     }
 
+    fn err_larrow_operator(&self, span: Span) {
+        self.struct_span_err(
+            span,
+            "unexpected token: `<-`"
+        ).span_suggestion(
+            span,
+            "if you meant to write a comparison against a negative value, add a \
+             space in between `<` and `-`",
+            "< -".to_string(),
+            Applicability::MaybeIncorrect
+        ).emit();
+    }
+
     fn mk_assign_op(&self, binop: BinOp, lhs: P<Expr>, rhs: P<Expr>) -> ExprKind {
         ExprKind::AssignOp(binop, lhs, rhs)
     }
diff --git a/src/libsyntax/source_map.rs b/src/libsyntax/source_map.rs
index 4e29c77c89e..74cab00d3c1 100644
--- a/src/libsyntax/source_map.rs
+++ b/src/libsyntax/source_map.rs
@@ -519,7 +519,7 @@ impl SourceMap {
     /// extract function takes three arguments: a string slice containing the source, an index in
     /// the slice for the beginning of the span and an index in the slice for the end of the span.
     fn span_to_source<F>(&self, sp: Span, extract_source: F) -> Result<String, SpanSnippetError>
-        where F: Fn(&str, usize, usize) -> String
+        where F: Fn(&str, usize, usize) -> Result<String, SpanSnippetError>
     {
         if sp.lo() > sp.hi() {
             return Err(SpanSnippetError::IllFormedSpan(sp));
@@ -554,9 +554,9 @@ impl SourceMap {
             }
 
             if let Some(ref src) = local_begin.sf.src {
-                return Ok(extract_source(src, start_index, end_index));
+                return extract_source(src, start_index, end_index);
             } else if let Some(src) = local_begin.sf.external_src.borrow().get_source() {
-                return Ok(extract_source(src, start_index, end_index));
+                return extract_source(src, start_index, end_index);
             } else {
                 return Err(SpanSnippetError::SourceNotAvailable {
                     filename: local_begin.sf.name.clone()
@@ -567,8 +567,9 @@ impl SourceMap {
 
     /// Returns the source snippet as `String` corresponding to the given `Span`
     pub fn span_to_snippet(&self, sp: Span) -> Result<String, SpanSnippetError> {
-        self.span_to_source(sp, |src, start_index, end_index| src[start_index..end_index]
-                                                                .to_string())
+        self.span_to_source(sp, |src, start_index, end_index| src.get(start_index..end_index)
+            .map(|s| s.to_string())
+            .ok_or_else(|| SpanSnippetError::IllFormedSpan(sp)))
     }
 
     pub fn span_to_margin(&self, sp: Span) -> Option<usize> {
@@ -582,7 +583,9 @@ impl SourceMap {
 
     /// Returns the source snippet as `String` before the given `Span`
     pub fn span_to_prev_source(&self, sp: Span) -> Result<String, SpanSnippetError> {
-        self.span_to_source(sp, |src, start_index, _| src[..start_index].to_string())
+        self.span_to_source(sp, |src, start_index, _| src.get(..start_index)
+            .map(|s| s.to_string())
+            .ok_or_else(|| SpanSnippetError::IllFormedSpan(sp)))
     }
 
     /// Extend the given `Span` to just after the previous occurrence of `c`. Return the same span
diff --git a/src/libsyntax/util/parser.rs b/src/libsyntax/util/parser.rs
index d71358f45c4..a501541c959 100644
--- a/src/libsyntax/util/parser.rs
+++ b/src/libsyntax/util/parser.rs
@@ -97,6 +97,8 @@ impl AssocOp {
             // DotDotDot is no longer supported, but we need some way to display the error
             token::DotDotDot => Some(DotDotEq),
             token::Colon => Some(Colon),
+            // `<-` should probably be `< -`
+            token::LArrow => Some(Less),
             _ if t.is_keyword(kw::As) => Some(As),
             _ => None
         }
diff --git a/src/test/ui/async-await/async-fn-elided-impl-lifetime-parameter.rs b/src/test/ui/async-await/async-fn-elided-impl-lifetime-parameter.rs
new file mode 100644
index 00000000000..1cbc5133a07
--- /dev/null
+++ b/src/test/ui/async-await/async-fn-elided-impl-lifetime-parameter.rs
@@ -0,0 +1,17 @@
+// Check that `async fn` inside of an impl with `'_`
+// in the header compiles correctly.
+//
+// Regression test for #63500.
+//
+// check-pass
+// edition:2018
+
+#![feature(async_await)]
+
+struct Foo<'a>(&'a u8);
+
+impl Foo<'_> {
+    async fn bar() {}
+}
+
+fn main() { }
diff --git a/src/test/ui/async-await/issue-61949-self-return-type.rs b/src/test/ui/async-await/issue-61949-self-return-type.rs
new file mode 100644
index 00000000000..c5a66d5d4a3
--- /dev/null
+++ b/src/test/ui/async-await/issue-61949-self-return-type.rs
@@ -0,0 +1,28 @@
+// ignore-tidy-linelength
+// edition:2018
+#![feature(async_await)]
+
+// This test checks that `Self` is prohibited as a return type. See #61949 for context.
+
+pub struct Foo<'a> {
+    pub bar: &'a i32,
+}
+
+impl<'a> Foo<'a> {
+    pub async fn new(_bar: &'a i32) -> Self {
+    //~^ ERROR `async fn` return type cannot contain a projection or `Self` that references lifetimes from a parent scope
+        Foo {
+            bar: &22
+        }
+    }
+}
+
+async fn foo() {
+    let x = {
+        let bar = 22;
+        Foo::new(&bar).await
+    };
+    drop(x);
+}
+
+fn main() { }
diff --git a/src/test/ui/async-await/issue-61949-self-return-type.stderr b/src/test/ui/async-await/issue-61949-self-return-type.stderr
new file mode 100644
index 00000000000..a9ae544502d
--- /dev/null
+++ b/src/test/ui/async-await/issue-61949-self-return-type.stderr
@@ -0,0 +1,8 @@
+error: `async fn` return type cannot contain a projection or `Self` that references lifetimes from a parent scope
+  --> $DIR/issue-61949-self-return-type.rs:12:40
+   |
+LL |     pub async fn new(_bar: &'a i32) -> Self {
+   |                                        ^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/async-await/issues/issue-63388-1.nll.stderr b/src/test/ui/async-await/issues/issue-63388-1.nll.stderr
new file mode 100644
index 00000000000..fab5892dae1
--- /dev/null
+++ b/src/test/ui/async-await/issues/issue-63388-1.nll.stderr
@@ -0,0 +1,24 @@
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/issue-63388-1.rs:14:10
+   |
+LL |     ) -> &dyn Foo
+   |          ^^^^^^^^
+   |
+   = note: hidden type `impl std::future::Future` captures lifetime '_#27r
+
+error: lifetime may not live long enough
+  --> $DIR/issue-63388-1.rs:15:5
+   |
+LL |       async fn do_sth<'a>(
+   |                       -- lifetime `'a` defined here
+LL |           &'a self, foo: &dyn Foo
+   |                          - lifetime `'_` defined here
+LL |       ) -> &dyn Foo
+LL | /     {
+LL | |         foo
+LL | |     }
+   | |_____^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'_`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0700`.
diff --git a/src/test/ui/async-await/issues/issue-63388-1.rs b/src/test/ui/async-await/issues/issue-63388-1.rs
new file mode 100644
index 00000000000..80003b0d701
--- /dev/null
+++ b/src/test/ui/async-await/issues/issue-63388-1.rs
@@ -0,0 +1,20 @@
+// edition:2018
+
+#![feature(async_await)]
+
+struct Xyz {
+    a: u64,
+}
+
+trait Foo {}
+
+impl Xyz {
+    async fn do_sth<'a>(
+        &'a self, foo: &dyn Foo
+    ) -> &dyn Foo //~ ERROR lifetime mismatch
+    {
+        foo
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/issues/issue-63388-1.stderr b/src/test/ui/async-await/issues/issue-63388-1.stderr
new file mode 100644
index 00000000000..5302adce5a0
--- /dev/null
+++ b/src/test/ui/async-await/issues/issue-63388-1.stderr
@@ -0,0 +1,12 @@
+error[E0623]: lifetime mismatch
+  --> $DIR/issue-63388-1.rs:14:10
+   |
+LL |         &'a self, foo: &dyn Foo
+   |         -------- this parameter and the return type are declared with different lifetimes...
+LL |     ) -> &dyn Foo
+   |          ^^^^^^^^
+   |          |
+   |          ...but data from `foo` is returned here
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/async-await/issues/issue-63388-2.nll.stderr b/src/test/ui/async-await/issues/issue-63388-2.nll.stderr
new file mode 100644
index 00000000000..b91cdc1b770
--- /dev/null
+++ b/src/test/ui/async-await/issues/issue-63388-2.nll.stderr
@@ -0,0 +1,11 @@
+error[E0106]: missing lifetime specifier
+  --> $DIR/issue-63388-2.rs:14:10
+   |
+LL |     ) -> &dyn Foo
+   |          ^ help: consider using the named lifetime: `&'a`
+   |
+   = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `foo` or `bar`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0106`.
diff --git a/src/test/ui/async-await/issues/issue-63388-2.rs b/src/test/ui/async-await/issues/issue-63388-2.rs
new file mode 100644
index 00000000000..ca9bbef0d50
--- /dev/null
+++ b/src/test/ui/async-await/issues/issue-63388-2.rs
@@ -0,0 +1,20 @@
+// edition:2018
+
+#![feature(async_await)]
+
+struct Xyz {
+    a: u64,
+}
+
+trait Foo {}
+
+impl Xyz {
+    async fn do_sth<'a>(
+        foo: &dyn Foo, bar: &'a dyn Foo //~ ERROR cannot infer
+    ) -> &dyn Foo //~ ERROR missing lifetime specifier
+    {
+        foo
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/issues/issue-63388-2.stderr b/src/test/ui/async-await/issues/issue-63388-2.stderr
new file mode 100644
index 00000000000..1810138dc80
--- /dev/null
+++ b/src/test/ui/async-await/issues/issue-63388-2.stderr
@@ -0,0 +1,29 @@
+error[E0106]: missing lifetime specifier
+  --> $DIR/issue-63388-2.rs:14:10
+   |
+LL |     ) -> &dyn Foo
+   |          ^ help: consider using the named lifetime: `&'a`
+   |
+   = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `foo` or `bar`
+
+error: cannot infer an appropriate lifetime
+  --> $DIR/issue-63388-2.rs:13:9
+   |
+LL |         foo: &dyn Foo, bar: &'a dyn Foo
+   |         ^^^ ...but this borrow...
+LL |     ) -> &dyn Foo
+   |          -------- this return type evaluates to the `'static` lifetime...
+   |
+note: ...can't outlive the lifetime '_ as defined on the method body at 13:14
+  --> $DIR/issue-63388-2.rs:13:14
+   |
+LL |         foo: &dyn Foo, bar: &'a dyn Foo
+   |              ^
+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 13:14
+   |
+LL |     ) -> &dyn Foo + '_
+   |          ^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0106`.
diff --git a/src/test/ui/async-await/issues/issue-63388-3.rs b/src/test/ui/async-await/issues/issue-63388-3.rs
new file mode 100644
index 00000000000..05f23f95965
--- /dev/null
+++ b/src/test/ui/async-await/issues/issue-63388-3.rs
@@ -0,0 +1,19 @@
+// edition:2018
+// check-pass
+
+#![feature(async_await)]
+
+struct Xyz {
+    a: u64,
+}
+
+trait Foo {}
+
+impl Xyz {
+    async fn do_sth(
+        &self, foo: &dyn Foo
+    ) {
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/issues/issue-63388-4.rs b/src/test/ui/async-await/issues/issue-63388-4.rs
new file mode 100644
index 00000000000..0939242d7fc
--- /dev/null
+++ b/src/test/ui/async-await/issues/issue-63388-4.rs
@@ -0,0 +1,12 @@
+// check-pass
+// edition:2018
+
+#![feature(async_await)]
+
+struct A;
+
+impl A {
+    async fn foo(&self, f: &u32) -> &A { self }
+}
+
+fn main() { }
diff --git a/src/test/ui/async-await/nested-in-impl.rs b/src/test/ui/async-await/nested-in-impl.rs
new file mode 100644
index 00000000000..3c82160595f
--- /dev/null
+++ b/src/test/ui/async-await/nested-in-impl.rs
@@ -0,0 +1,17 @@
+// Test that async fn works when nested inside of
+// impls with lifetime parameters.
+//
+// check-pass
+// edition:2018
+
+#![feature(async_await)]
+
+struct Foo<'a>(&'a ());
+
+impl<'a> Foo<'a> {
+    fn test() {
+        async fn test() {}
+    }
+}
+
+fn main() { }
diff --git a/src/test/ui/c-variadic/variadic-ffi-no-fixed-args.rs b/src/test/ui/c-variadic/variadic-ffi-no-fixed-args.rs
new file mode 100644
index 00000000000..e3b642a9d41
--- /dev/null
+++ b/src/test/ui/c-variadic/variadic-ffi-no-fixed-args.rs
@@ -0,0 +1,6 @@
+extern {
+    fn foo(...);
+    //~^ ERROR C-variadic function must be declared with at least one named argument
+}
+
+fn main() {}
diff --git a/src/test/ui/c-variadic/variadic-ffi-no-fixed-args.stderr b/src/test/ui/c-variadic/variadic-ffi-no-fixed-args.stderr
new file mode 100644
index 00000000000..cb6060525fc
--- /dev/null
+++ b/src/test/ui/c-variadic/variadic-ffi-no-fixed-args.stderr
@@ -0,0 +1,8 @@
+error: C-variadic function must be declared with at least one named argument
+  --> $DIR/variadic-ffi-no-fixed-args.rs:2:11
+   |
+LL |     fn foo(...);
+   |           ^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/impl-trait/bound-normalization-fail.rs b/src/test/ui/impl-trait/bound-normalization-fail.rs
index c33261bfd09..9ba7c91fc72 100644
--- a/src/test/ui/impl-trait/bound-normalization-fail.rs
+++ b/src/test/ui/impl-trait/bound-normalization-fail.rs
@@ -1,4 +1,5 @@
 // compile-fail
+// ignore-tidy-linelength
 // edition:2018
 
 #![feature(async_await)]
@@ -44,7 +45,8 @@ mod lifetimes {
 
     /// Missing bound constraining `Assoc`, `T::Assoc` can't be normalized further.
     fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike<Output=T::Assoc> {
-        //~^ ERROR: type mismatch
+    //~^ ERROR: type mismatch
+    //~^^ ERROR `impl Trait` return type cannot contain a projection or `Self` that references lifetimes from a parent scope
         Foo(())
     }
 }
diff --git a/src/test/ui/impl-trait/bound-normalization-fail.stderr b/src/test/ui/impl-trait/bound-normalization-fail.stderr
index aa306a7e08a..b5c8e078f0f 100644
--- a/src/test/ui/impl-trait/bound-normalization-fail.stderr
+++ b/src/test/ui/impl-trait/bound-normalization-fail.stderr
@@ -1,5 +1,5 @@
 warning: the feature `impl_trait_in_bindings` is incomplete and may cause the compiler to crash
-  --> $DIR/bound-normalization-fail.rs:5:12
+  --> $DIR/bound-normalization-fail.rs:6:12
    |
 LL | #![feature(impl_trait_in_bindings)]
    |            ^^^^^^^^^^^^^^^^^^^^^^
@@ -7,7 +7,7 @@ LL | #![feature(impl_trait_in_bindings)]
    = note: `#[warn(incomplete_features)]` on by default
 
 error[E0271]: type mismatch resolving `<Foo<()> as FooLike>::Output == <T as impl_trait::Trait>::Assoc`
-  --> $DIR/bound-normalization-fail.rs:29:32
+  --> $DIR/bound-normalization-fail.rs:30:32
    |
 LL |     fn foo_fail<T: Trait>() -> impl FooLike<Output=T::Assoc> {
    |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected (), found associated type
@@ -16,8 +16,14 @@ LL |     fn foo_fail<T: Trait>() -> impl FooLike<Output=T::Assoc> {
               found type `<T as impl_trait::Trait>::Assoc`
    = note: the return type of a function must have a statically known size
 
+error: `impl Trait` return type cannot contain a projection or `Self` that references lifetimes from a parent scope
+  --> $DIR/bound-normalization-fail.rs:47:41
+   |
+LL |     fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike<Output=T::Assoc> {
+   |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
 error[E0271]: type mismatch resolving `<Foo<()> as FooLike>::Output == <T as lifetimes::Trait<'static>>::Assoc`
-  --> $DIR/bound-normalization-fail.rs:46:41
+  --> $DIR/bound-normalization-fail.rs:47:41
    |
 LL |     fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike<Output=T::Assoc> {
    |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected (), found associated type
@@ -26,6 +32,6 @@ LL |     fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike<Output=T::Assoc> {
               found type `<T as lifetimes::Trait<'static>>::Assoc`
    = note: the return type of a function must have a statically known size
 
-error: aborting due to 2 previous errors
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0271`.
diff --git a/src/test/ui/in-band-lifetimes/nested-items.rs b/src/test/ui/in-band-lifetimes/nested-items.rs
new file mode 100644
index 00000000000..7de20712fba
--- /dev/null
+++ b/src/test/ui/in-band-lifetimes/nested-items.rs
@@ -0,0 +1,20 @@
+// Test that the `'a` from the impl doesn't
+// prevent us from creating a `'a` parameter
+// on the `blah` function.
+//
+// check-pass
+
+#![feature(in_band_lifetimes)]
+
+struct Foo<'a> {
+    x: &'a u32
+
+}
+
+impl Foo<'a> {
+    fn method(&self) {
+        fn blah(f: Foo<'a>) { }
+    }
+}
+
+fn main() { }
diff --git a/src/test/ui/issues/issue-13483.stderr b/src/test/ui/issues/issue-13483.stderr
index 739f0612366..df9f1dd0115 100644
--- a/src/test/ui/issues/issue-13483.stderr
+++ b/src/test/ui/issues/issue-13483.stderr
@@ -1,10 +1,10 @@
-error: missing condition for `if` statemement
+error: missing condition for `if` expression
   --> $DIR/issue-13483.rs:3:14
    |
 LL |     } else if {
    |              ^ expected if condition here
 
-error: missing condition for `if` statemement
+error: missing condition for `if` expression
   --> $DIR/issue-13483.rs:10:14
    |
 LL |     } else if {
diff --git a/src/test/ui/obsolete-in-place/bad.rs b/src/test/ui/obsolete-in-place/bad.rs
index 3530862f767..a491bb21a57 100644
--- a/src/test/ui/obsolete-in-place/bad.rs
+++ b/src/test/ui/obsolete-in-place/bad.rs
@@ -2,7 +2,7 @@
 
 fn foo() {
     let (x, y) = (0, 0);
-    x <- y; //~ ERROR expected one of
+    x <- y; //~ ERROR unexpected token: `<-`
 }
 
 fn main() {
diff --git a/src/test/ui/obsolete-in-place/bad.stderr b/src/test/ui/obsolete-in-place/bad.stderr
index 373b7ea4218..8a731b6240b 100644
--- a/src/test/ui/obsolete-in-place/bad.stderr
+++ b/src/test/ui/obsolete-in-place/bad.stderr
@@ -1,8 +1,12 @@
-error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `<-`
+error: unexpected token: `<-`
   --> $DIR/bad.rs:5:7
    |
 LL |     x <- y;
-   |       ^^ expected one of 8 possible tokens here
+   |       ^^
+help: if you meant to write a comparison against a negative value, add a space in between `<` and `-`
+   |
+LL |     x < - y;
+   |       ^^^
 
 error: expected expression, found keyword `in`
   --> $DIR/bad.rs:10:5
diff --git a/src/test/ui/placement-syntax.rs b/src/test/ui/placement-syntax.rs
index 2edd78ec8ab..4df96dedbd4 100644
--- a/src/test/ui/placement-syntax.rs
+++ b/src/test/ui/placement-syntax.rs
@@ -1,6 +1,6 @@
 fn main() {
     let x = -5;
-    if x<-1 { //~ ERROR expected `{`, found `<-`
+    if x<-1 { //~ ERROR unexpected token: `<-`
         println!("ok");
     }
 }
diff --git a/src/test/ui/placement-syntax.stderr b/src/test/ui/placement-syntax.stderr
index e90acce168e..e26931e60d8 100644
--- a/src/test/ui/placement-syntax.stderr
+++ b/src/test/ui/placement-syntax.stderr
@@ -1,10 +1,12 @@
-error: expected `{`, found `<-`
+error: unexpected token: `<-`
   --> $DIR/placement-syntax.rs:3:9
    |
 LL |     if x<-1 {
-   |     --  ^^ expected `{`
-   |     |
-   |     this `if` statement has a condition, but no block
+   |         ^^
+help: if you meant to write a comparison against a negative value, add a space in between `<` and `-`
+   |
+LL |     if x< -1 {
+   |         ^^^
 
 error: aborting due to previous error
 
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 00000000000..b853f88a96d
--- /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 00000000000..2421632c664
--- /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 00000000000..aecb82325c1
--- /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 00000000000..f0032449db1
--- /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 00000000000..94646c2cfe0
--- /dev/null
+++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.nll.stderr
@@ -0,0 +1,46 @@
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:10:45
+   |
+LL |     async fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f }
+   |                                             ^^^^
+   |
+   = note: hidden type `impl std::future::Future` captures lifetime '_#18r
+
+error: lifetime may not live long enough
+  --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:10:50
+   |
+LL |     async fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f }
+   |                          -                       ^^^^^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
+   |                          |
+   |                          lifetime `'_` defined here
+   |                          lifetime `'_` defined here
+
+error: lifetime may not live long enough
+  --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:13:73
+   |
+LL |     async fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) }
+   |                          -                                              ^^^^^^^^^^^^^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
+   |                          |
+   |                          lifetime `'_` defined here
+   |                          lifetime `'_` defined here
+
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:19:58
+   |
+LL |     async fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg }
+   |                                                          ^^^
+   |
+   = note: hidden type `impl std::future::Future` captures lifetime '_#18r
+
+error: lifetime may not live long enough
+  --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:19:62
+   |
+LL |     async fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg }
+   |                  --              -                           ^^^^^^^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'a`
+   |                  |               |
+   |                  |               lifetime `'_` defined here
+   |                  lifetime `'a` defined here
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0700`.
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 00000000000..53ab75ee16b
--- /dev/null
+++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.rs
@@ -0,0 +1,22 @@
+// edition:2018
+
+#![feature(async_await)]
+
+use std::pin::Pin;
+
+struct Foo;
+
+impl Foo {
+    async fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f }
+    //~^ ERROR lifetime mismatch
+
+    async fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) }
+    //~^ ERROR lifetime mismatch
+}
+
+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 00000000000..74fc4741349
--- /dev/null
+++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.stderr
@@ -0,0 +1,29 @@
+error[E0623]: lifetime mismatch
+  --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:10:45
+   |
+LL |     async fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f }
+   |                          ----               ^^^^
+   |                          |                  |
+   |                          |                  ...but data from `f` is returned here
+   |                          this parameter and the return type are declared with different lifetimes...
+
+error[E0623]: lifetime mismatch
+  --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:13:55
+   |
+LL |     async fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) }
+   |                          -----                        ^^^^^^^^^^^^^^^^^
+   |                          |                            |
+   |                          |                            ...but data from `f` is returned here
+   |                          this parameter and the return type are declared with different lifetimes...
+
+error[E0623]: lifetime mismatch
+  --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:19: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 3 previous errors
+
diff --git a/src/test/ui/self/elision/README.md b/src/test/ui/self/elision/README.md
index 7ace2e0c890..3bd7a6c00b2 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 | ✓ | N/A |
+| `ref-mut-self-async.rs` | X | ✓ | N/A |
+| `ref-struct-async.rs` | X | ✓ | N/A |
+| `ref-mut-struct-async.rs` | X | ✓ | N/A |
+| `ref-alias-async.rs` | ✓ | ✓ | N/A |
+| `ref-assoc-async.rs` | ✓ | ✓ | N/A |
+| `ref-mut-alias-async.rs` | ✓ | ✓ | N/A |
+| `lt-self-async.rs` | ✓ | ✓ | N/A
+| `lt-struct-async.rs` | ✓ | ✓ | N/A
+| `lt-alias-async.rs` | ✓ | ✓ | N/A
+| `lt-assoc-async.rs` | ✓ | ✓ | N/A
+| `lt-ref-self-async.rs` | X | ✓ | N/A |
diff --git a/src/test/ui/self/elision/alias-async.rs b/src/test/ui/self/elision/alias-async.rs
new file mode 100644
index 00000000000..3d5b24a8946
--- /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 00000000000..0f33f288772
--- /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 00000000000..5a8989f078e
--- /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 00000000000..98c9aa3b6c2
--- /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-ref-self-async.nll.stderr b/src/test/ui/self/elision/lt-ref-self-async.nll.stderr
new file mode 100644
index 00000000000..779b21e21a0
--- /dev/null
+++ b/src/test/ui/self/elision/lt-ref-self-async.nll.stderr
@@ -0,0 +1,123 @@
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/lt-ref-self-async.rs:15:42
+   |
+LL |     async fn ref_self(&self, f: &u32) -> &u32 {
+   |                                          ^^^^
+   |
+   = note: hidden type `impl std::future::Future` captures lifetime '_#28r
+
+error: lifetime may not live long enough
+  --> $DIR/lt-ref-self-async.rs:15:47
+   |
+LL |       async fn ref_self(&self, f: &u32) -> &u32 {
+   |  _______________________-_______________________^
+   | |                       |
+   | |                       lifetime `'_` defined here
+   | |                       lifetime `'_` defined here
+LL | |         f
+LL | |     }
+   | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
+
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/lt-ref-self-async.rs:21:48
+   |
+LL |     async fn ref_Self(self: &Self, f: &u32) -> &u32 {
+   |                                                ^^^^
+   |
+   = note: hidden type `impl std::future::Future` captures lifetime '_#28r
+
+error: lifetime may not live long enough
+  --> $DIR/lt-ref-self-async.rs:21:53
+   |
+LL |       async fn ref_Self(self: &Self, f: &u32) -> &u32 {
+   |  _____________________________-_______________________^
+   | |                             |
+   | |                             lifetime `'_` defined here
+   | |                             lifetime `'_` defined here
+LL | |         f
+LL | |     }
+   | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
+
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/lt-ref-self-async.rs:25:57
+   |
+LL |     async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
+   |                                                         ^^^^
+   |
+   = note: hidden type `impl std::future::Future` captures lifetime '_#28r
+
+error: lifetime may not live long enough
+  --> $DIR/lt-ref-self-async.rs:25:62
+   |
+LL |       async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
+   |  _____________________________________-________________________^
+   | |                                     |
+   | |                                     lifetime `'_` defined here
+   | |                                     lifetime `'_` defined here
+LL | |         f
+LL | |     }
+   | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
+
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/lt-ref-self-async.rs:29:57
+   |
+LL |     async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
+   |                                                         ^^^^
+   |
+   = note: hidden type `impl std::future::Future` captures lifetime '_#28r
+
+error: lifetime may not live long enough
+  --> $DIR/lt-ref-self-async.rs:29:62
+   |
+LL |       async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
+   |  _____________________________________-________________________^
+   | |                                     |
+   | |                                     lifetime `'_` defined here
+   | |                                     lifetime `'_` defined here
+LL | |         f
+LL | |     }
+   | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
+
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/lt-ref-self-async.rs:33:66
+   |
+LL |     async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
+   |                                                                  ^^^^
+   |
+   = note: hidden type `impl std::future::Future` captures lifetime '_#28r
+
+error: lifetime may not live long enough
+  --> $DIR/lt-ref-self-async.rs:33:71
+   |
+LL |       async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
+   |  _____________________________________________-_________________________^
+   | |                                             |
+   | |                                             lifetime `'_` defined here
+   | |                                             lifetime `'_` defined here
+LL | |         f
+LL | |     }
+   | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
+
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/lt-ref-self-async.rs:37:62
+   |
+LL |     async fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
+   |                                                              ^^^^
+   |
+   = note: hidden type `impl std::future::Future` captures lifetime '_#28r
+
+error: lifetime may not live long enough
+  --> $DIR/lt-ref-self-async.rs:37:67
+   |
+LL |       async fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
+   |  _________________________________________-_________________________^
+   | |                                         |
+   | |                                         lifetime `'_` defined here
+   | |                                         lifetime `'_` defined here
+LL | |         f
+LL | |     }
+   | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
+
+error: aborting due to 12 previous errors
+
+For more information about this error, try `rustc --explain E0700`.
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 00000000000..79a4771978a
--- /dev/null
+++ b/src/test/ui/self/elision/lt-ref-self-async.rs
@@ -0,0 +1,42 @@
+// 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 {
+        f //~^ ERROR lifetime mismatch
+    }
+
+    // Test using `&Self` explicitly:
+
+    async fn ref_Self(self: &Self, f: &u32) -> &u32 {
+        f //~^ ERROR lifetime mismatch
+    }
+
+    async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
+        f //~^ ERROR lifetime mismatch
+    }
+
+    async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
+        f //~^ ERROR lifetime mismatch
+    }
+
+    async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
+        f //~^ ERROR lifetime mismatch
+    }
+
+    async fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
+        f //~^ ERROR lifetime mismatch
+    }
+}
+
+fn main() { }
diff --git a/src/test/ui/self/elision/lt-ref-self-async.stderr b/src/test/ui/self/elision/lt-ref-self-async.stderr
new file mode 100644
index 00000000000..0a459257fa7
--- /dev/null
+++ b/src/test/ui/self/elision/lt-ref-self-async.stderr
@@ -0,0 +1,56 @@
+error[E0623]: lifetime mismatch
+  --> $DIR/lt-ref-self-async.rs:15:42
+   |
+LL |     async fn ref_self(&self, f: &u32) -> &u32 {
+   |                       -----              ^^^^
+   |                       |                  |
+   |                       |                  ...but data from `f` is returned here
+   |                       this parameter and the return type are declared with different lifetimes...
+
+error[E0623]: lifetime mismatch
+  --> $DIR/lt-ref-self-async.rs:21:48
+   |
+LL |     async fn ref_Self(self: &Self, f: &u32) -> &u32 {
+   |                             -----              ^^^^
+   |                             |                  |
+   |                             |                  ...but data from `f` is returned here
+   |                             this parameter and the return type are declared with different lifetimes...
+
+error[E0623]: lifetime mismatch
+  --> $DIR/lt-ref-self-async.rs:25:57
+   |
+LL |     async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
+   |                                     -----               ^^^^
+   |                                     |                   |
+   |                                     |                   ...but data from `f` is returned here
+   |                                     this parameter and the return type are declared with different lifetimes...
+
+error[E0623]: lifetime mismatch
+  --> $DIR/lt-ref-self-async.rs:29:57
+   |
+LL |     async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
+   |                                     -----               ^^^^
+   |                                     |                   |
+   |                                     |                   ...but data from `f` is returned here
+   |                                     this parameter and the return type are declared with different lifetimes...
+
+error[E0623]: lifetime mismatch
+  --> $DIR/lt-ref-self-async.rs:33:66
+   |
+LL |     async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
+   |                                             -----                ^^^^
+   |                                             |                    |
+   |                                             |                    ...but data from `f` is returned here
+   |                                             this parameter and the return type are declared with different lifetimes...
+
+error[E0623]: lifetime mismatch
+  --> $DIR/lt-ref-self-async.rs:37:62
+   |
+LL |     async fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
+   |                                         -----                ^^^^
+   |                                         |                    |
+   |                                         |                    ...but data from `f` is returned here
+   |                                         this parameter and the return type are declared with different lifetimes...
+
+error: aborting due to 6 previous errors
+
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 00000000000..0202db8a635
--- /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 00000000000..c0fc63d4232
--- /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/multiple-ref-self-async.rs b/src/test/ui/self/elision/multiple-ref-self-async.rs
new file mode 100644
index 00000000000..eb8c25277e1
--- /dev/null
+++ b/src/test/ui/self/elision/multiple-ref-self-async.rs
@@ -0,0 +1,46 @@
+// check-pass
+// 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 {
+        f
+    }
+
+    async fn box_wrap_ref_Self_ref_Self(self: Box<Wrap<&Self, &Self>>, f: &u32) -> &u32 {
+        f
+    }
+
+    async fn pin_wrap_ref_Self_ref_Self(self: Pin<Wrap<&Self, &Self>>, f: &u32) -> &u32 {
+        f
+    }
+
+    async fn box_box_wrap_ref_Self_ref_Self(self: Box<Box<Wrap<&Self, &Self>>>, f: &u32) -> &u32 {
+        f
+    }
+
+    async fn box_pin_wrap_ref_Self_ref_Self(self: Box<Pin<Wrap<&Self, &Self>>>, f: &u32) -> &u32 {
+        f
+    }
+}
+
+fn main() { }
diff --git a/src/test/ui/self/elision/ref-alias-async.rs b/src/test/ui/self/elision/ref-alias-async.rs
new file mode 100644
index 00000000000..acc4b2153ef
--- /dev/null
+++ b/src/test/ui/self/elision/ref-alias-async.rs
@@ -0,0 +1,42 @@
+// edition:2018
+// check-pass
+
+#![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 {
+        f
+    }
+
+    async fn box_ref_Alias(self: Box<&Alias>, f: &u32) -> &u32 {
+        f
+    }
+
+    async fn pin_ref_Alias(self: Pin<&Alias>, f: &u32) -> &u32 {
+        f
+    }
+
+    async fn box_box_ref_Alias(self: Box<Box<&Alias>>, f: &u32) -> &u32 {
+        f
+    }
+
+    async fn box_pin_ref_Alias(self: Box<Pin<&Alias>>, f: &u32) -> &u32 {
+        f
+    }
+}
+
+fn main() { }
diff --git a/src/test/ui/self/elision/ref-assoc-async.rs b/src/test/ui/self/elision/ref-assoc-async.rs
new file mode 100644
index 00000000000..a6b6cbd6da3
--- /dev/null
+++ b/src/test/ui/self/elision/ref-assoc-async.rs
@@ -0,0 +1,43 @@
+// edition:2018
+// check-pass
+
+#![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 {
+        f
+    }
+
+    async fn box_ref_AssocType(self: Box<&<Struct as Trait>::AssocType>, f: &u32) -> &u32 {
+        f
+    }
+
+    async fn pin_ref_AssocType(self: Pin<&<Struct as Trait>::AssocType>, f: &u32) -> &u32 {
+        f
+    }
+
+    async fn box_box_ref_AssocType(self: Box<Box<&<Struct as Trait>::AssocType>>, f: &u32) -> &u32 {
+        f
+    }
+
+    async fn box_pin_ref_AssocType(self: Box<Pin<&<Struct as Trait>::AssocType>>, f: &u32) -> &u32 {
+        f
+    }
+}
+
+fn main() { }
diff --git a/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 00000000000..873e92bc6d3
--- /dev/null
+++ b/src/test/ui/self/elision/ref-mut-alias-async.rs
@@ -0,0 +1,38 @@
+// edition:2018
+// check-pass
+
+#![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 {
+        f
+    }
+
+    async fn box_ref_Alias(self: Box<&mut Alias>, f: &u32) -> &u32 {
+        f
+    }
+
+    async fn pin_ref_Alias(self: Pin<&mut Alias>, f: &u32) -> &u32 {
+        f
+    }
+
+    async fn box_box_ref_Alias(self: Box<Box<&mut Alias>>, f: &u32) -> &u32 {
+        f
+    }
+
+    async fn box_pin_ref_Alias(self: Box<Pin<&mut Alias>>, f: &u32) -> &u32 {
+        f
+    }
+}
+
+fn main() { }
diff --git a/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 00000000000..cfe91dde373
--- /dev/null
+++ b/src/test/ui/self/elision/ref-mut-self-async.nll.stderr
@@ -0,0 +1,123 @@
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/ref-mut-self-async.rs:15:46
+   |
+LL |     async fn ref_self(&mut self, f: &u32) -> &u32 {
+   |                                              ^^^^
+   |
+   = note: hidden type `impl std::future::Future` captures lifetime '_#18r
+
+error: lifetime may not live long enough
+  --> $DIR/ref-mut-self-async.rs:15:51
+   |
+LL |       async fn ref_self(&mut self, f: &u32) -> &u32 {
+   |  _______________________-___________________________^
+   | |                       |
+   | |                       lifetime `'_` defined here
+   | |                       lifetime `'_` defined here
+LL | |         f
+LL | |     }
+   | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
+
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/ref-mut-self-async.rs:21:52
+   |
+LL |     async fn ref_Self(self: &mut Self, f: &u32) -> &u32 {
+   |                                                    ^^^^
+   |
+   = note: hidden type `impl std::future::Future` captures lifetime '_#18r
+
+error: lifetime may not live long enough
+  --> $DIR/ref-mut-self-async.rs:21:57
+   |
+LL |       async fn ref_Self(self: &mut Self, f: &u32) -> &u32 {
+   |  _____________________________-___________________________^
+   | |                             |
+   | |                             lifetime `'_` defined here
+   | |                             lifetime `'_` defined here
+LL | |         f
+LL | |     }
+   | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
+
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/ref-mut-self-async.rs:25:61
+   |
+LL |     async fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 {
+   |                                                             ^^^^
+   |
+   = note: hidden type `impl std::future::Future` captures lifetime '_#18r
+
+error: lifetime may not live long enough
+  --> $DIR/ref-mut-self-async.rs:25:66
+   |
+LL |       async fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 {
+   |  _____________________________________-____________________________^
+   | |                                     |
+   | |                                     lifetime `'_` defined here
+   | |                                     lifetime `'_` defined here
+LL | |         f
+LL | |     }
+   | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
+
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/ref-mut-self-async.rs:29:61
+   |
+LL |     async fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 {
+   |                                                             ^^^^
+   |
+   = note: hidden type `impl std::future::Future` captures lifetime '_#18r
+
+error: lifetime may not live long enough
+  --> $DIR/ref-mut-self-async.rs:29:66
+   |
+LL |       async fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 {
+   |  _____________________________________-____________________________^
+   | |                                     |
+   | |                                     lifetime `'_` defined here
+   | |                                     lifetime `'_` defined here
+LL | |         f
+LL | |     }
+   | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
+
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/ref-mut-self-async.rs:33:70
+   |
+LL |     async fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 {
+   |                                                                      ^^^^
+   |
+   = note: hidden type `impl std::future::Future` captures lifetime '_#18r
+
+error: lifetime may not live long enough
+  --> $DIR/ref-mut-self-async.rs:33:75
+   |
+LL |       async fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 {
+   |  _____________________________________________-_____________________________^
+   | |                                             |
+   | |                                             lifetime `'_` defined here
+   | |                                             lifetime `'_` defined here
+LL | |         f
+LL | |     }
+   | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
+
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/ref-mut-self-async.rs:37:70
+   |
+LL |     async fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 {
+   |                                                                      ^^^^
+   |
+   = note: hidden type `impl std::future::Future` captures lifetime '_#18r
+
+error: lifetime may not live long enough
+  --> $DIR/ref-mut-self-async.rs:37:75
+   |
+LL |       async fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 {
+   |  _____________________________________________-_____________________________^
+   | |                                             |
+   | |                                             lifetime `'_` defined here
+   | |                                             lifetime `'_` defined here
+LL | |         f
+LL | |     }
+   | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
+
+error: aborting due to 12 previous errors
+
+For more information about this error, try `rustc --explain E0700`.
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 00000000000..a6bd9d69316
--- /dev/null
+++ b/src/test/ui/self/elision/ref-mut-self-async.rs
@@ -0,0 +1,42 @@
+// 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 lifetime mismatch
+        f
+    }
+
+    // Test using `&mut Self` explicitly:
+
+    async fn ref_Self(self: &mut Self, f: &u32) -> &u32 {
+        f //~^ ERROR lifetime mismatch
+    }
+
+    async fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 {
+        f //~^ ERROR lifetime mismatch
+    }
+
+    async fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 {
+        f //~^ ERROR lifetime mismatch
+    }
+
+    async fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 {
+        f //~^ ERROR lifetime mismatch
+    }
+
+    async fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 {
+        f //~^ ERROR lifetime mismatch
+    }
+}
+
+fn main() { }
diff --git a/src/test/ui/self/elision/ref-mut-self-async.stderr b/src/test/ui/self/elision/ref-mut-self-async.stderr
new file mode 100644
index 00000000000..805833f9472
--- /dev/null
+++ b/src/test/ui/self/elision/ref-mut-self-async.stderr
@@ -0,0 +1,56 @@
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-mut-self-async.rs:15:46
+   |
+LL |     async fn ref_self(&mut self, f: &u32) -> &u32 {
+   |                       ---------              ^^^^
+   |                       |                      |
+   |                       |                      ...but data from `f` is returned here
+   |                       this parameter and the return type are declared with different lifetimes...
+
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-mut-self-async.rs:21:52
+   |
+LL |     async fn ref_Self(self: &mut Self, f: &u32) -> &u32 {
+   |                             ---------              ^^^^
+   |                             |                      |
+   |                             |                      ...but data from `f` is returned here
+   |                             this parameter and the return type are declared with different lifetimes...
+
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-mut-self-async.rs:25:61
+   |
+LL |     async fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 {
+   |                                     ---------               ^^^^
+   |                                     |                       |
+   |                                     |                       ...but data from `f` is returned here
+   |                                     this parameter and the return type are declared with different lifetimes...
+
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-mut-self-async.rs:29:61
+   |
+LL |     async fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 {
+   |                                     ---------               ^^^^
+   |                                     |                       |
+   |                                     |                       ...but data from `f` is returned here
+   |                                     this parameter and the return type are declared with different lifetimes...
+
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-mut-self-async.rs:33:70
+   |
+LL |     async fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 {
+   |                                             ---------                ^^^^
+   |                                             |                        |
+   |                                             |                        ...but data from `f` is returned here
+   |                                             this parameter and the return type are declared with different lifetimes...
+
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-mut-self-async.rs:37:70
+   |
+LL |     async fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 {
+   |                                             ---------                ^^^^
+   |                                             |                        |
+   |                                             |                        ...but data from `f` is returned here
+   |                                             this parameter and the return type are declared with different lifetimes...
+
+error: aborting due to 6 previous errors
+
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 00000000000..98fa5e25451
--- /dev/null
+++ b/src/test/ui/self/elision/ref-mut-struct-async.nll.stderr
@@ -0,0 +1,103 @@
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/ref-mut-struct-async.rs:15:56
+   |
+LL |     async fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 {
+   |                                                        ^^^^
+   |
+   = note: hidden type `impl std::future::Future` captures lifetime '_#18r
+
+error: lifetime may not live long enough
+  --> $DIR/ref-mut-struct-async.rs:15:61
+   |
+LL |       async fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 {
+   |  _______________________________-_____________________________^
+   | |                               |
+   | |                               lifetime `'_` defined here
+   | |                               lifetime `'_` defined here
+LL | |         f
+LL | |     }
+   | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
+
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/ref-mut-struct-async.rs:19:65
+   |
+LL |     async fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 {
+   |                                                                 ^^^^
+   |
+   = note: hidden type `impl std::future::Future` captures lifetime '_#18r
+
+error: lifetime may not live long enough
+  --> $DIR/ref-mut-struct-async.rs:19:70
+   |
+LL |       async fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 {
+   |  _______________________________________-______________________________^
+   | |                                       |
+   | |                                       lifetime `'_` defined here
+   | |                                       lifetime `'_` defined here
+LL | |         f
+LL | |     }
+   | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
+
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/ref-mut-struct-async.rs:23:65
+   |
+LL |     async fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 {
+   |                                                                 ^^^^
+   |
+   = note: hidden type `impl std::future::Future` captures lifetime '_#18r
+
+error: lifetime may not live long enough
+  --> $DIR/ref-mut-struct-async.rs:23:70
+   |
+LL |       async fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 {
+   |  _______________________________________-______________________________^
+   | |                                       |
+   | |                                       lifetime `'_` defined here
+   | |                                       lifetime `'_` defined here
+LL | |         f
+LL | |     }
+   | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
+
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/ref-mut-struct-async.rs:27:74
+   |
+LL |     async fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u32 {
+   |                                                                          ^^^^
+   |
+   = note: hidden type `impl std::future::Future` captures lifetime '_#18r
+
+error: lifetime may not live long enough
+  --> $DIR/ref-mut-struct-async.rs:27:79
+   |
+LL |       async fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u32 {
+   |  _______________________________________________-_______________________________^
+   | |                                               |
+   | |                                               lifetime `'_` defined here
+   | |                                               lifetime `'_` defined here
+LL | |         f
+LL | |     }
+   | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
+
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/ref-mut-struct-async.rs:31:74
+   |
+LL |     async fn box_pin_ref_Struct(self: Box<Pin<&mut Struct>>, f: &u32) -> &u32 {
+   |                                                                          ^^^^
+   |
+   = note: hidden type `impl std::future::Future` captures lifetime '_#18r
+
+error: lifetime may not live long enough
+  --> $DIR/ref-mut-struct-async.rs:31:79
+   |
+LL |       async fn box_pin_ref_Struct(self: Box<Pin<&mut Struct>>, f: &u32) -> &u32 {
+   |  _______________________________________________-_______________________________^
+   | |                                               |
+   | |                                               lifetime `'_` defined here
+   | |                                               lifetime `'_` defined here
+LL | |         f
+LL | |     }
+   | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
+
+error: aborting due to 10 previous errors
+
+For more information about this error, try `rustc --explain E0700`.
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 00000000000..7a89ef9596a
--- /dev/null
+++ b/src/test/ui/self/elision/ref-mut-struct-async.rs
@@ -0,0 +1,36 @@
+// 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 {
+        f //~^ ERROR lifetime mismatch
+    }
+
+    async fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 {
+        f //~^ ERROR lifetime mismatch
+    }
+
+    async fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 {
+        f //~^ ERROR lifetime mismatch
+    }
+
+    async fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u32 {
+        f //~^ ERROR lifetime mismatch
+    }
+
+    async fn box_pin_ref_Struct(self: Box<Pin<&mut Struct>>, f: &u32) -> &u32 {
+        f //~^ ERROR lifetime mismatch
+    }
+}
+
+fn main() { }
diff --git a/src/test/ui/self/elision/ref-mut-struct-async.stderr b/src/test/ui/self/elision/ref-mut-struct-async.stderr
new file mode 100644
index 00000000000..4c983872942
--- /dev/null
+++ b/src/test/ui/self/elision/ref-mut-struct-async.stderr
@@ -0,0 +1,47 @@
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-mut-struct-async.rs:15:56
+   |
+LL |     async fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 {
+   |                               -----------              ^^^^
+   |                               |                        |
+   |                               |                        ...but data from `f` is returned here
+   |                               this parameter and the return type are declared with different lifetimes...
+
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-mut-struct-async.rs:19:65
+   |
+LL |     async fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 {
+   |                                       -----------               ^^^^
+   |                                       |                         |
+   |                                       |                         ...but data from `f` is returned here
+   |                                       this parameter and the return type are declared with different lifetimes...
+
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-mut-struct-async.rs:23:65
+   |
+LL |     async fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 {
+   |                                       -----------               ^^^^
+   |                                       |                         |
+   |                                       |                         ...but data from `f` is returned here
+   |                                       this parameter and the return type are declared with different lifetimes...
+
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-mut-struct-async.rs:27:74
+   |
+LL |     async fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u32 {
+   |                                               -----------                ^^^^
+   |                                               |                          |
+   |                                               |                          ...but data from `f` is returned here
+   |                                               this parameter and the return type are declared with different lifetimes...
+
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-mut-struct-async.rs:31:74
+   |
+LL |     async fn box_pin_ref_Struct(self: Box<Pin<&mut Struct>>, f: &u32) -> &u32 {
+   |                                               -----------                ^^^^
+   |                                               |                          |
+   |                                               |                          ...but data from `f` is returned here
+   |                                               this parameter and the return type are declared with different lifetimes...
+
+error: aborting due to 5 previous errors
+
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 00000000000..f991f6d9f7f
--- /dev/null
+++ b/src/test/ui/self/elision/ref-self-async.nll.stderr
@@ -0,0 +1,143 @@
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/ref-self-async.rs:24:42
+   |
+LL |     async fn ref_self(&self, f: &u32) -> &u32 {
+   |                                          ^^^^
+   |
+   = note: hidden type `impl std::future::Future` captures lifetime '_#18r
+
+error: lifetime may not live long enough
+  --> $DIR/ref-self-async.rs:24:47
+   |
+LL |       async fn ref_self(&self, f: &u32) -> &u32 {
+   |  _______________________-_______________________^
+   | |                       |
+   | |                       lifetime `'_` defined here
+   | |                       lifetime `'_` defined here
+LL | |         f
+LL | |     }
+   | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
+
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/ref-self-async.rs:30:48
+   |
+LL |     async fn ref_Self(self: &Self, f: &u32) -> &u32 {
+   |                                                ^^^^
+   |
+   = note: hidden type `impl std::future::Future` captures lifetime '_#18r
+
+error: lifetime may not live long enough
+  --> $DIR/ref-self-async.rs:30:53
+   |
+LL |       async fn ref_Self(self: &Self, f: &u32) -> &u32 {
+   |  _____________________________-_______________________^
+   | |                             |
+   | |                             lifetime `'_` defined here
+   | |                             lifetime `'_` defined here
+LL | |         f
+LL | |     }
+   | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
+
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/ref-self-async.rs:34:57
+   |
+LL |     async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
+   |                                                         ^^^^
+   |
+   = note: hidden type `impl std::future::Future` captures lifetime '_#18r
+
+error: lifetime may not live long enough
+  --> $DIR/ref-self-async.rs:34:62
+   |
+LL |       async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
+   |  _____________________________________-________________________^
+   | |                                     |
+   | |                                     lifetime `'_` defined here
+   | |                                     lifetime `'_` defined here
+LL | |         f
+LL | |     }
+   | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
+
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/ref-self-async.rs:38:57
+   |
+LL |     async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
+   |                                                         ^^^^
+   |
+   = note: hidden type `impl std::future::Future` captures lifetime '_#18r
+
+error: lifetime may not live long enough
+  --> $DIR/ref-self-async.rs:38:62
+   |
+LL |       async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
+   |  _____________________________________-________________________^
+   | |                                     |
+   | |                                     lifetime `'_` defined here
+   | |                                     lifetime `'_` defined here
+LL | |         f
+LL | |     }
+   | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
+
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/ref-self-async.rs:42:66
+   |
+LL |     async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
+   |                                                                  ^^^^
+   |
+   = note: hidden type `impl std::future::Future` captures lifetime '_#18r
+
+error: lifetime may not live long enough
+  --> $DIR/ref-self-async.rs:42:71
+   |
+LL |       async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
+   |  _____________________________________________-_________________________^
+   | |                                             |
+   | |                                             lifetime `'_` defined here
+   | |                                             lifetime `'_` defined here
+LL | |         f
+LL | |     }
+   | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
+
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/ref-self-async.rs:46:66
+   |
+LL |     async fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
+   |                                                                  ^^^^
+   |
+   = note: hidden type `impl std::future::Future` captures lifetime '_#18r
+
+error: lifetime may not live long enough
+  --> $DIR/ref-self-async.rs:46:71
+   |
+LL |       async fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
+   |  _____________________________________________-_________________________^
+   | |                                             |
+   | |                                             lifetime `'_` defined here
+   | |                                             lifetime `'_` defined here
+LL | |         f
+LL | |     }
+   | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
+
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/ref-self-async.rs:50:69
+   |
+LL |     async fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 {
+   |                                                                     ^^^
+   |
+   = note: hidden type `impl std::future::Future` captures lifetime '_#18r
+
+error: lifetime may not live long enough
+  --> $DIR/ref-self-async.rs:50:73
+   |
+LL |       async fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 {
+   |  ____________________________________________-____________________________^
+   | |                                            |
+   | |                                            lifetime `'_` defined here
+   | |                                            lifetime `'_` defined here
+LL | |         f
+LL | |     }
+   | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
+
+error: aborting due to 14 previous errors
+
+For more information about this error, try `rustc --explain E0700`.
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 00000000000..5a5705d7e09
--- /dev/null
+++ b/src/test/ui/self/elision/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 `&self` sugar:
+
+    async fn ref_self(&self, f: &u32) -> &u32 { //~ ERROR lifetime mismatch
+        f
+    }
+
+    // Test using `&Self` explicitly:
+
+    async fn ref_Self(self: &Self, f: &u32) -> &u32 {
+        f //~^ ERROR lifetime mismatch
+    }
+
+    async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
+        f //~^ ERROR lifetime mismatch
+    }
+
+    async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
+        f //~^ ERROR lifetime mismatch
+    }
+
+    async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
+        f //~^ ERROR lifetime mismatch
+    }
+
+    async fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
+        f //~^ ERROR lifetime mismatch
+    }
+
+    async fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 {
+        f //~^ ERROR lifetime mismatch
+    }
+}
+
+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 00000000000..eb796a07a86
--- /dev/null
+++ b/src/test/ui/self/elision/ref-self-async.stderr
@@ -0,0 +1,65 @@
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-self-async.rs:24:42
+   |
+LL |     async fn ref_self(&self, f: &u32) -> &u32 {
+   |                       -----              ^^^^
+   |                       |                  |
+   |                       |                  ...but data from `f` is returned here
+   |                       this parameter and the return type are declared with different lifetimes...
+
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-self-async.rs:30:48
+   |
+LL |     async fn ref_Self(self: &Self, f: &u32) -> &u32 {
+   |                             -----              ^^^^
+   |                             |                  |
+   |                             |                  ...but data from `f` is returned here
+   |                             this parameter and the return type are declared with different lifetimes...
+
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-self-async.rs:34:57
+   |
+LL |     async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
+   |                                     -----               ^^^^
+   |                                     |                   |
+   |                                     |                   ...but data from `f` is returned here
+   |                                     this parameter and the return type are declared with different lifetimes...
+
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-self-async.rs:38:57
+   |
+LL |     async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
+   |                                     -----               ^^^^
+   |                                     |                   |
+   |                                     |                   ...but data from `f` is returned here
+   |                                     this parameter and the return type are declared with different lifetimes...
+
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-self-async.rs:42:66
+   |
+LL |     async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
+   |                                             -----                ^^^^
+   |                                             |                    |
+   |                                             |                    ...but data from `f` is returned here
+   |                                             this parameter and the return type are declared with different lifetimes...
+
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-self-async.rs:46:66
+   |
+LL |     async fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
+   |                                             -----                ^^^^
+   |                                             |                    |
+   |                                             |                    ...but data from `f` is returned here
+   |                                             this parameter and the return type are declared with different lifetimes...
+
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-self-async.rs:50:69
+   |
+LL |     async fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 {
+   |                                            -----                    ^^^
+   |                                            |                        |
+   |                                            |                        ...but data from `f` is returned here
+   |                                            this parameter and the return type are declared with different lifetimes...
+
+error: aborting due to 7 previous errors
+
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 00000000000..437d403e044
--- /dev/null
+++ b/src/test/ui/self/elision/ref-struct-async.nll.stderr
@@ -0,0 +1,103 @@
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/ref-struct-async.rs:15:52
+   |
+LL |     async fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
+   |                                                    ^^^^
+   |
+   = note: hidden type `impl std::future::Future` captures lifetime '_#18r
+
+error: lifetime may not live long enough
+  --> $DIR/ref-struct-async.rs:15:57
+   |
+LL |       async fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
+   |  _______________________________-_________________________^
+   | |                               |
+   | |                               lifetime `'_` defined here
+   | |                               lifetime `'_` defined here
+LL | |         f
+LL | |     }
+   | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
+
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/ref-struct-async.rs:19:61
+   |
+LL |     async fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 {
+   |                                                             ^^^^
+   |
+   = note: hidden type `impl std::future::Future` captures lifetime '_#18r
+
+error: lifetime may not live long enough
+  --> $DIR/ref-struct-async.rs:19:66
+   |
+LL |       async fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 {
+   |  _______________________________________-__________________________^
+   | |                                       |
+   | |                                       lifetime `'_` defined here
+   | |                                       lifetime `'_` defined here
+LL | |         f
+LL | |     }
+   | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
+
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/ref-struct-async.rs:23:61
+   |
+LL |     async fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 {
+   |                                                             ^^^^
+   |
+   = note: hidden type `impl std::future::Future` captures lifetime '_#18r
+
+error: lifetime may not live long enough
+  --> $DIR/ref-struct-async.rs:23:66
+   |
+LL |       async fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 {
+   |  _______________________________________-__________________________^
+   | |                                       |
+   | |                                       lifetime `'_` defined here
+   | |                                       lifetime `'_` defined here
+LL | |         f
+LL | |     }
+   | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
+
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/ref-struct-async.rs:27:70
+   |
+LL |     async fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 {
+   |                                                                      ^^^^
+   |
+   = note: hidden type `impl std::future::Future` captures lifetime '_#18r
+
+error: lifetime may not live long enough
+  --> $DIR/ref-struct-async.rs:27:75
+   |
+LL |       async fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 {
+   |  _______________________________________________-___________________________^
+   | |                                               |
+   | |                                               lifetime `'_` defined here
+   | |                                               lifetime `'_` defined here
+LL | |         f
+LL | |     }
+   | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
+
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/ref-struct-async.rs:31:66
+   |
+LL |     async fn box_pin_Struct(self: Box<Pin<&Struct>>, f: &u32) -> &u32 {
+   |                                                                  ^^^^
+   |
+   = note: hidden type `impl std::future::Future` captures lifetime '_#18r
+
+error: lifetime may not live long enough
+  --> $DIR/ref-struct-async.rs:31:71
+   |
+LL |       async fn box_pin_Struct(self: Box<Pin<&Struct>>, f: &u32) -> &u32 {
+   |  ___________________________________________-___________________________^
+   | |                                           |
+   | |                                           lifetime `'_` defined here
+   | |                                           lifetime `'_` defined here
+LL | |         f
+LL | |     }
+   | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
+
+error: aborting due to 10 previous errors
+
+For more information about this error, try `rustc --explain E0700`.
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 00000000000..f0410bbee90
--- /dev/null
+++ b/src/test/ui/self/elision/ref-struct-async.rs
@@ -0,0 +1,36 @@
+// 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 {
+        f //~^ ERROR lifetime mismatch
+    }
+
+    async fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 {
+        f //~^ ERROR lifetime mismatch
+    }
+
+    async fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 {
+        f //~^ ERROR lifetime mismatch
+    }
+
+    async fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 {
+        f //~^ ERROR lifetime mismatch
+    }
+
+    async fn box_pin_Struct(self: Box<Pin<&Struct>>, f: &u32) -> &u32 {
+        f //~^ ERROR lifetime mismatch
+    }
+}
+
+fn main() { }
diff --git a/src/test/ui/self/elision/ref-struct-async.stderr b/src/test/ui/self/elision/ref-struct-async.stderr
new file mode 100644
index 00000000000..574b0fddc1e
--- /dev/null
+++ b/src/test/ui/self/elision/ref-struct-async.stderr
@@ -0,0 +1,47 @@
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-struct-async.rs:15:52
+   |
+LL |     async fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
+   |                               -------              ^^^^
+   |                               |                    |
+   |                               |                    ...but data from `f` is returned here
+   |                               this parameter and the return type are declared with different lifetimes...
+
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-struct-async.rs:19:61
+   |
+LL |     async fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 {
+   |                                       -------               ^^^^
+   |                                       |                     |
+   |                                       |                     ...but data from `f` is returned here
+   |                                       this parameter and the return type are declared with different lifetimes...
+
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-struct-async.rs:23:61
+   |
+LL |     async fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 {
+   |                                       -------               ^^^^
+   |                                       |                     |
+   |                                       |                     ...but data from `f` is returned here
+   |                                       this parameter and the return type are declared with different lifetimes...
+
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-struct-async.rs:27:70
+   |
+LL |     async fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 {
+   |                                               -------                ^^^^
+   |                                               |                      |
+   |                                               |                      ...but data from `f` is returned here
+   |                                               this parameter and the return type are declared with different lifetimes...
+
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-struct-async.rs:31:66
+   |
+LL |     async fn box_pin_Struct(self: Box<Pin<&Struct>>, f: &u32) -> &u32 {
+   |                                           -------                ^^^^
+   |                                           |                      |
+   |                                           |                      ...but data from `f` is returned here
+   |                                           this parameter and the return type are declared with different lifetimes...
+
+error: aborting due to 5 previous errors
+
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 00000000000..d1dc050be0d
--- /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 00000000000..f7c8591ebd3
--- /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() { }
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 00000000000..ec4c3d15224
--- /dev/null
+++ b/src/test/ui/self/self_lifetime-async.rs
@@ -0,0 +1,16 @@
+// check-pass
+// edition:2018
+
+#![feature(async_await)]
+
+struct Foo<'a>(&'a ());
+impl<'a> Foo<'a> {
+    async fn foo<'b>(self: &'b Foo<'a>) -> &() { self.0 }
+}
+
+type Alias = Foo<'static>;
+impl Alias {
+    async fn bar<'a>(self: &Alias, arg: &'a ()) -> &() { arg }
+}
+
+fn main() {}
diff --git a/src/test/ui/suggestions/issue-61226.rs b/src/test/ui/suggestions/issue-61226.rs
new file mode 100644
index 00000000000..e83b0b4d630
--- /dev/null
+++ b/src/test/ui/suggestions/issue-61226.rs
@@ -0,0 +1,5 @@
+struct X {}
+fn main() {
+    vec![X]; //…
+    //~^ ERROR expected value, found struct `X`
+}
diff --git a/src/test/ui/suggestions/issue-61226.stderr b/src/test/ui/suggestions/issue-61226.stderr
new file mode 100644
index 00000000000..6d7d98ac6a1
--- /dev/null
+++ b/src/test/ui/suggestions/issue-61226.stderr
@@ -0,0 +1,9 @@
+error[E0423]: expected value, found struct `X`
+  --> $DIR/issue-61226.rs:3:10
+   |
+LL |     vec![X]; //…
+   |          ^ did you mean `X { /* fields */ }`?
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0423`.