From 501f828671f948b8e7eb58c605a2baca539de87e Mon Sep 17 00:00:00 2001
From: Eric Huss <eric@huss.org>
Date: Tue, 23 Jul 2019 14:12:55 -0700
Subject: [PATCH 01/20] [BETA] Update cargo

---
 src/tools/cargo | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/tools/cargo b/src/tools/cargo
index 4c1fa54d10f58..9edd089168f87 160000
--- a/src/tools/cargo
+++ b/src/tools/cargo
@@ -1 +1 @@
-Subproject commit 4c1fa54d10f58d69ac9ff55be68e1b1c25ecb816
+Subproject commit 9edd089168f8795b3890bc3daf5b99f03e9f8765

From d86bab47cc14b2858e8532c314c7fdc0cf0f6fa1 Mon Sep 17 00:00:00 2001
From: Erin Power <xampprocky@gmail.com>
Date: Sat, 13 Jul 2019 14:15:01 +0200
Subject: [PATCH 02/20] Updated RELEASES.md for 1.37.0

---
 RELEASES.md | 118 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 118 insertions(+)

diff --git a/RELEASES.md b/RELEASES.md
index 43a5fda61297a..6049a8ef4c9ea 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -1,3 +1,121 @@
+Version 1.37.0 (2019-08-15)
+==========================
+
+Language
+--------
+- `#[must_use]` will now warn if the type is contained in a [tuple][61100],
+  [`Box`][62228], or an [array][62235] and unused.
+- [You can now use the `cfg` and `cfg_attr` attributes on
+  generic parameters.][61547]
+- [You can now use enum variants through type alias.][61682] e.g. You can
+  write the following:
+  ```rust
+  type MyOption = Option<u8>;
+
+  fn increment_or_zero(x: MyOption) -> u8 {
+      match x {
+          MyOption::Some(y) => y + 1,
+          MyOption::None => 0,
+      }
+  }
+  ```
+- [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
+  2015 edition.][60932]
+
+Compiler
+--------
+- [You can now enable Profile-Guided Optimization with the `-C profile-generate`
+  and `-C profile-use` flags.][61268] For more information on how to use profile
+  guided optimization, please refer to the [rustc book][rustc-book-pgo].
+- [The `rust-lldb` wrapper script should now work again.][61827]
+
+Libraries
+---------
+- [`mem::MaybeUninit<T>` is now ABI-compatible with `T`.][61802]
+
+Stabilized APIs
+---------------
+- [`BufReader::buffer`]
+- [`BufWriter::buffer`]
+- [`Cell::from_mut`]
+- [`Cell<[T]>::as_slice_of_cells`][`Cell<slice>::as_slice_of_cells`]
+- [`DoubleEndedIterator::nth_back`]
+- [`Option::xor`]
+- [`Wrapping::reverse_bits`]
+- [`i128::reverse_bits`]
+- [`i16::reverse_bits`]
+- [`i32::reverse_bits`]
+- [`i64::reverse_bits`]
+- [`i8::reverse_bits`]
+- [`isize::reverse_bits`]
+- [`slice::copy_within`]
+- [`u128::reverse_bits`]
+- [`u16::reverse_bits`]
+- [`u32::reverse_bits`]
+- [`u64::reverse_bits`]
+- [`u8::reverse_bits`]
+- [`usize::reverse_bits`]
+
+Cargo
+-----
+- [`Cargo.lock` files are now included by default when publishing executable crates
+  with executables.][cargo/7026]
+- [You can now specify `default-run="foo"` in `[package]` to specify the
+  default executable to use for `cargo run`.][cargo/7056]
+
+Misc
+----
+
+Compatibility Notes
+-------------------
+- [Using `...` for inclusive range patterns will now warn by default.][61342]
+  Please transition your code to using the `..=` syntax for inclusive
+  ranges instead.
+- [Using a trait object without the `dyn` will now warn by default.][61203]
+  Please transition your code to use `dyn Trait` for trait objects instead.
+
+[62228]: https://github.com/rust-lang/rust/pull/62228/
+[62235]: https://github.com/rust-lang/rust/pull/62235/
+[61802]: https://github.com/rust-lang/rust/pull/61802/
+[61827]: https://github.com/rust-lang/rust/pull/61827/
+[61547]: https://github.com/rust-lang/rust/pull/61547/
+[61682]: https://github.com/rust-lang/rust/pull/61682/
+[61268]: https://github.com/rust-lang/rust/pull/61268/
+[61342]: https://github.com/rust-lang/rust/pull/61342/
+[61347]: https://github.com/rust-lang/rust/pull/61347/
+[61100]: https://github.com/rust-lang/rust/pull/61100/
+[61203]: https://github.com/rust-lang/rust/pull/61203/
+[61229]: https://github.com/rust-lang/rust/pull/61229/
+[60932]: https://github.com/rust-lang/rust/pull/60932/
+[cargo/7026]: https://github.com/rust-lang/cargo/pull/7026/
+[cargo/7056]: https://github.com/rust-lang/cargo/pull/7056/
+[`BufReader::buffer`]: https://doc.rust-lang.org/std/io/struct.BufReader.html#method.buffer
+[`BufWriter::buffer`]: https://doc.rust-lang.org/std/io/struct.BufWriter.html#method.buffer
+[`Cell::from_mut`]: https://doc.rust-lang.org/std/cell/struct.Cell.html#method.from_mut
+[`Cell<slice>::as_slice_of_cells`]: https://doc.rust-lang.org/std/cell/struct.Cell.html#method.as_slice_of_cells
+[`DoubleEndedIterator::nth_back`]: https://doc.rust-lang.org/std/iter/trait.DoubleEndedIterator.html#method.nth_back
+[`Option::xor`]: https://doc.rust-lang.org/std/option/enum.Option.html#method.xor
+[`RefCell::try_borrow_unguarded`]: https://doc.rust-lang.org/std/cell/struct.RefCell.html#method.try_borrow_unguarded
+[`Wrapping::reverse_bits`]: https://doc.rust-lang.org/std/num/struct.Wrapping.html#method.reverse_bits
+[`i128::reverse_bits`]: https://doc.rust-lang.org/std/primitive.i128.html#method.reverse_bits
+[`i16::reverse_bits`]: https://doc.rust-lang.org/std/primitive.i16.html#method.reverse_bits
+[`i32::reverse_bits`]: https://doc.rust-lang.org/std/primitive.i32.html#method.reverse_bits
+[`i64::reverse_bits`]: https://doc.rust-lang.org/std/primitive.i64.html#method.reverse_bits
+[`i8::reverse_bits`]: https://doc.rust-lang.org/std/primitive.i8.html#method.reverse_bits
+[`isize::reverse_bits`]: https://doc.rust-lang.org/std/primitive.isize.html#method.reverse_bits
+[`slice::copy_within`]: https://doc.rust-lang.org/std/primitive.slice.html#method.copy_within
+[`u128::reverse_bits`]: https://doc.rust-lang.org/std/primitive.u128.html#method.reverse_bits
+[`u16::reverse_bits`]: https://doc.rust-lang.org/std/primitive.u16.html#method.reverse_bits
+[`u32::reverse_bits`]: https://doc.rust-lang.org/std/primitive.u32.html#method.reverse_bits
+[`u64::reverse_bits`]: https://doc.rust-lang.org/std/primitive.u64.html#method.reverse_bits
+[`u8::reverse_bits`]: https://doc.rust-lang.org/std/primitive.u8.html#method.reverse_bits
+[`usize::reverse_bits`]: https://doc.rust-lang.org/std/primitive.usize.html#method.reverse_bits
+[rustc-book-pgo]: https://doc.rust-lang.org/rustc/profile-guided-optimization.html
+
+
 Version 1.36.0 (2019-07-04)
 ==========================
 

From 5310736e587bb35dacd3d1cfb934553d49fb4c64 Mon Sep 17 00:00:00 2001
From: Josh Stone <jistone@redhat.com>
Date: Tue, 23 Jul 2019 12:04:31 -0700
Subject: [PATCH 03/20] Require a value for configure --debuginfo-level

In `configure.py`, using the `o` function creates an enable/disable
boolean setting, and writes `true` or `false` in `config.toml`. However,
rustbuild is expecting to parse a `u32` debuginfo level. We can change
to the `v` function to have the options require a value.
---
 src/bootstrap/configure.py | 10 +++++-----
 src/ci/run.sh              |  2 +-
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py
index 53d3dbf60d1d7..907983d43ade7 100755
--- a/src/bootstrap/configure.py
+++ b/src/bootstrap/configure.py
@@ -76,11 +76,11 @@ def v(*args):
 o("llvm-assertions", "llvm.assertions", "build LLVM with assertions")
 o("debug-assertions", "rust.debug-assertions", "build with debugging assertions")
 o("llvm-release-debuginfo", "llvm.release-debuginfo", "build LLVM with debugger metadata")
-o("debuginfo-level", "rust.debuginfo-level", "debuginfo level for Rust code")
-o("debuginfo-level-rustc", "rust.debuginfo-level-rustc", "debuginfo level for the compiler")
-o("debuginfo-level-std", "rust.debuginfo-level-std", "debuginfo level for the standard library")
-o("debuginfo-level-tools", "rust.debuginfo-level-tools", "debuginfo level for the tools")
-o("debuginfo-level-tests", "rust.debuginfo-level-tests", "debuginfo level for the test suites run with compiletest")
+v("debuginfo-level", "rust.debuginfo-level", "debuginfo level for Rust code")
+v("debuginfo-level-rustc", "rust.debuginfo-level-rustc", "debuginfo level for the compiler")
+v("debuginfo-level-std", "rust.debuginfo-level-std", "debuginfo level for the standard library")
+v("debuginfo-level-tools", "rust.debuginfo-level-tools", "debuginfo level for the tools")
+v("debuginfo-level-tests", "rust.debuginfo-level-tests", "debuginfo level for the test suites run with compiletest")
 v("save-toolstates", "rust.save-toolstates", "save build and test status of external tools into this file")
 
 v("prefix", "install.prefix", "set installation prefix")
diff --git a/src/ci/run.sh b/src/ci/run.sh
index b91859bfceb78..e5e0e6cf6033d 100755
--- a/src/ci/run.sh
+++ b/src/ci/run.sh
@@ -50,7 +50,7 @@ if [ "$DEPLOY$DEPLOY_ALT" = "1" ]; then
   RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --release-channel=$RUST_RELEASE_CHANNEL"
   RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-llvm-static-stdcpp"
   RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set rust.remap-debuginfo"
-  RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set rust.debuginfo-level-std=1"
+  RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --debuginfo-level-std=1"
 
   if [ "$NO_LLVM_ASSERTIONS" = "1" ]; then
     RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --disable-llvm-assertions"

From 16a69ed36de737670ecd35affd0a44c183c59978 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Mon, 22 Jul 2019 18:29:49 -0700
Subject: [PATCH 04/20] Make the parser TokenStream more resilient after
 mismatched delimiter recovery

---
 src/libsyntax/parse/parser.rs         |  3 +++
 src/test/ui/issues/issue-62881.rs     |  6 ++++++
 src/test/ui/issues/issue-62881.stderr | 29 +++++++++++++++++++++++++++
 3 files changed, 38 insertions(+)
 create mode 100644 src/test/ui/issues/issue-62881.rs
 create mode 100644 src/test/ui/issues/issue-62881.stderr

diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 26c76ae560654..143179fb46fea 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -7716,6 +7716,9 @@ impl<'a> Parser<'a> {
         let ret = f(self);
         let last_token = if self.token_cursor.stack.len() == prev {
             &mut self.token_cursor.frame.last_token
+        } else if self.token_cursor.stack.is_empty() {//&& !self.unclosed_delims.is_empty() {
+            // This can happen with mismatched delimiters (#62881)
+            return Ok((ret?, TokenStream::new(vec![])));
         } else {
             &mut self.token_cursor.stack[prev].last_token
         };
diff --git a/src/test/ui/issues/issue-62881.rs b/src/test/ui/issues/issue-62881.rs
new file mode 100644
index 0000000000000..1782c2e375df5
--- /dev/null
+++ b/src/test/ui/issues/issue-62881.rs
@@ -0,0 +1,6 @@
+fn main() {}
+
+fn f() -> isize { fn f() -> isize {} pub f<
+//~^ ERROR missing `fn` or `struct` for function or struct definition
+//~| ERROR mismatched types
+//~ ERROR this file contains an un-closed delimiter
diff --git a/src/test/ui/issues/issue-62881.stderr b/src/test/ui/issues/issue-62881.stderr
new file mode 100644
index 0000000000000..85c3575fd9288
--- /dev/null
+++ b/src/test/ui/issues/issue-62881.stderr
@@ -0,0 +1,29 @@
+error: this file contains an un-closed delimiter
+  --> $DIR/issue-62881.rs:6:53
+   |
+LL | fn f() -> isize { fn f() -> isize {} pub f<
+   |                 - un-closed delimiter
+...
+LL |
+   |                                                     ^
+
+error: missing `fn` or `struct` for function or struct definition
+  --> $DIR/issue-62881.rs:3:41
+   |
+LL | fn f() -> isize { fn f() -> isize {} pub f<
+   |                                         ^
+
+error[E0308]: mismatched types
+  --> $DIR/issue-62881.rs:3:29
+   |
+LL | fn f() -> isize { fn f() -> isize {} pub f<
+   |                      -      ^^^^^ expected isize, found ()
+   |                      |
+   |                      this function's body doesn't return
+   |
+   = note: expected type `isize`
+              found type `()`
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0308`.

From d8c07484531afb05f901f0f85c0d997d6f0bf7a7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Tue, 23 Jul 2019 11:19:13 -0700
Subject: [PATCH 05/20] Fix another case

---
 src/libsyntax/parse/parser.rs         | 15 ++++++--
 src/test/ui/issues/issue-62895.rs     | 11 ++++++
 src/test/ui/issues/issue-62895.stderr | 49 +++++++++++++++++++++++++++
 3 files changed, 72 insertions(+), 3 deletions(-)
 create mode 100644 src/test/ui/issues/issue-62895.rs
 create mode 100644 src/test/ui/issues/issue-62895.stderr

diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 143179fb46fea..27225dc1abfa1 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -7716,8 +7716,9 @@ impl<'a> Parser<'a> {
         let ret = f(self);
         let last_token = if self.token_cursor.stack.len() == prev {
             &mut self.token_cursor.frame.last_token
-        } else if self.token_cursor.stack.is_empty() {//&& !self.unclosed_delims.is_empty() {
-            // This can happen with mismatched delimiters (#62881)
+        } else if self.token_cursor.stack.get(prev).is_none() {
+            // This can happen due to a bad interaction of two unrelated recovery mechanisms with
+            // mismatched delimiters *and* recovery lookahead on `pub ident(` likely typo (#62881)
             return Ok((ret?, TokenStream::new(vec![])));
         } else {
             &mut self.token_cursor.stack[prev].last_token
@@ -7726,7 +7727,15 @@ impl<'a> Parser<'a> {
         // Pull out the tokens that we've collected from the call to `f` above.
         let mut collected_tokens = match *last_token {
             LastToken::Collecting(ref mut v) => mem::replace(v, Vec::new()),
-            LastToken::Was(_) => panic!("our vector went away?"),
+            LastToken::Was(ref was) => {
+                let msg = format!("our vector went away? - found Was({:?})", was);
+                debug!("collect_tokens: {}", msg);
+                self.sess.span_diagnostic.delay_span_bug(self.token.span, &msg);
+                // This can happen due to a bad interaction of two unrelated recovery mechanisms
+                // with mismatched delimiters *and* recovery lookahead on `pub ident(` likely typo
+                // (#62895, different but similar to the case above)
+                return Ok((ret?, TokenStream::new(vec![])));
+            }
         };
 
         // If we're not at EOF our current token wasn't actually consumed by
diff --git a/src/test/ui/issues/issue-62895.rs b/src/test/ui/issues/issue-62895.rs
new file mode 100644
index 0000000000000..53f17405d79f4
--- /dev/null
+++ b/src/test/ui/issues/issue-62895.rs
@@ -0,0 +1,11 @@
+fn main() {}
+
+fn v() -> isize { //~ ERROR mismatched types
+mod _ { //~ ERROR expected identifier
+pub fn g() -> isizee { //~ ERROR cannot find type `isizee` in this scope
+mod _ { //~ ERROR expected identifier
+pub    g() -> is //~ ERROR missing `fn` for function definition
+(), w20);
+}
+(), w20); //~ ERROR expected item, found `;`
+}
diff --git a/src/test/ui/issues/issue-62895.stderr b/src/test/ui/issues/issue-62895.stderr
new file mode 100644
index 0000000000000..7def7b562ca59
--- /dev/null
+++ b/src/test/ui/issues/issue-62895.stderr
@@ -0,0 +1,49 @@
+error: expected identifier, found reserved identifier `_`
+  --> $DIR/issue-62895.rs:4:5
+   |
+LL | mod _ {
+   |     ^ expected identifier, found reserved identifier
+
+error: expected identifier, found reserved identifier `_`
+  --> $DIR/issue-62895.rs:6:5
+   |
+LL | mod _ {
+   |     ^ expected identifier, found reserved identifier
+
+error: missing `fn` for function definition
+  --> $DIR/issue-62895.rs:7:4
+   |
+LL | pub    g() -> is
+   |    ^^^^
+help: add `fn` here to parse `g` as a public function
+   |
+LL | pub fn g() -> is
+   |     ^^
+
+error: expected item, found `;`
+  --> $DIR/issue-62895.rs:10:9
+   |
+LL | (), w20);
+   |         ^ help: remove this semicolon
+
+error[E0412]: cannot find type `isizee` in this scope
+  --> $DIR/issue-62895.rs:5:15
+   |
+LL | pub fn g() -> isizee {
+   |               ^^^^^^ help: a builtin type with a similar name exists: `isize`
+
+error[E0308]: mismatched types
+  --> $DIR/issue-62895.rs:3:11
+   |
+LL | fn v() -> isize {
+   |    -      ^^^^^ expected isize, found ()
+   |    |
+   |    this function's body doesn't return
+   |
+   = note: expected type `isize`
+              found type `()`
+
+error: aborting due to 6 previous errors
+
+Some errors have detailed explanations: E0308, E0412.
+For more information about an error, try `rustc --explain E0308`.

From 639cb881f0354cedda1168e3e599e679d0ccce15 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Tue, 23 Jul 2019 12:51:34 -0700
Subject: [PATCH 06/20] review comments

---
 src/libsyntax/parse/parser.rs                     | 7 ++++---
 src/test/ui/{issues => parser}/issue-62881.rs     | 0
 src/test/ui/{issues => parser}/issue-62881.stderr | 0
 src/test/ui/{issues => parser}/issue-62895.rs     | 0
 src/test/ui/{issues => parser}/issue-62895.stderr | 0
 5 files changed, 4 insertions(+), 3 deletions(-)
 rename src/test/ui/{issues => parser}/issue-62881.rs (100%)
 rename src/test/ui/{issues => parser}/issue-62881.stderr (100%)
 rename src/test/ui/{issues => parser}/issue-62895.rs (100%)
 rename src/test/ui/{issues => parser}/issue-62895.stderr (100%)

diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 27225dc1abfa1..b2e319a478e3a 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -7718,7 +7718,8 @@ impl<'a> Parser<'a> {
             &mut self.token_cursor.frame.last_token
         } else if self.token_cursor.stack.get(prev).is_none() {
             // This can happen due to a bad interaction of two unrelated recovery mechanisms with
-            // mismatched delimiters *and* recovery lookahead on `pub ident(` likely typo (#62881)
+            // mismatched delimiters *and* recovery lookahead on the likely typo `pub ident(`
+            // (#62881).
             return Ok((ret?, TokenStream::new(vec![])));
         } else {
             &mut self.token_cursor.stack[prev].last_token
@@ -7732,8 +7733,8 @@ impl<'a> Parser<'a> {
                 debug!("collect_tokens: {}", msg);
                 self.sess.span_diagnostic.delay_span_bug(self.token.span, &msg);
                 // This can happen due to a bad interaction of two unrelated recovery mechanisms
-                // with mismatched delimiters *and* recovery lookahead on `pub ident(` likely typo
-                // (#62895, different but similar to the case above)
+                // with mismatched delimiters *and* recovery lookahead on the likely typo
+                // `pub ident(` (#62895, different but similar to the case above).
                 return Ok((ret?, TokenStream::new(vec![])));
             }
         };
diff --git a/src/test/ui/issues/issue-62881.rs b/src/test/ui/parser/issue-62881.rs
similarity index 100%
rename from src/test/ui/issues/issue-62881.rs
rename to src/test/ui/parser/issue-62881.rs
diff --git a/src/test/ui/issues/issue-62881.stderr b/src/test/ui/parser/issue-62881.stderr
similarity index 100%
rename from src/test/ui/issues/issue-62881.stderr
rename to src/test/ui/parser/issue-62881.stderr
diff --git a/src/test/ui/issues/issue-62895.rs b/src/test/ui/parser/issue-62895.rs
similarity index 100%
rename from src/test/ui/issues/issue-62895.rs
rename to src/test/ui/parser/issue-62895.rs
diff --git a/src/test/ui/issues/issue-62895.stderr b/src/test/ui/parser/issue-62895.stderr
similarity index 100%
rename from src/test/ui/issues/issue-62895.stderr
rename to src/test/ui/parser/issue-62895.stderr

From 6db3310d3ba94f630501d64916d9d4c3e8ee9609 Mon Sep 17 00:00:00 2001
From: Pietro Albini <pietro@pietroalbini.org>
Date: Sat, 3 Aug 2019 22:29:28 +0200
Subject: [PATCH 07/20] ci: move .azure-pipelines to src/ci/azure-pipelines

---
 {.azure-pipelines => src/ci/azure-pipelines}/auto.yml             | 0
 {.azure-pipelines => src/ci/azure-pipelines}/master.yml           | 0
 {.azure-pipelines => src/ci/azure-pipelines}/pr.yml               | 0
 .../ci/azure-pipelines}/steps/install-clang.yml                   | 0
 .../ci/azure-pipelines}/steps/install-sccache.yml                 | 0
 .../ci/azure-pipelines}/steps/install-windows-build-deps.yml      | 0
 {.azure-pipelines => src/ci/azure-pipelines}/steps/run.yml        | 0
 {.azure-pipelines => src/ci/azure-pipelines}/try.yml              | 0
 8 files changed, 0 insertions(+), 0 deletions(-)
 rename {.azure-pipelines => src/ci/azure-pipelines}/auto.yml (100%)
 rename {.azure-pipelines => src/ci/azure-pipelines}/master.yml (100%)
 rename {.azure-pipelines => src/ci/azure-pipelines}/pr.yml (100%)
 rename {.azure-pipelines => src/ci/azure-pipelines}/steps/install-clang.yml (100%)
 rename {.azure-pipelines => src/ci/azure-pipelines}/steps/install-sccache.yml (100%)
 rename {.azure-pipelines => src/ci/azure-pipelines}/steps/install-windows-build-deps.yml (100%)
 rename {.azure-pipelines => src/ci/azure-pipelines}/steps/run.yml (100%)
 rename {.azure-pipelines => src/ci/azure-pipelines}/try.yml (100%)

diff --git a/.azure-pipelines/auto.yml b/src/ci/azure-pipelines/auto.yml
similarity index 100%
rename from .azure-pipelines/auto.yml
rename to src/ci/azure-pipelines/auto.yml
diff --git a/.azure-pipelines/master.yml b/src/ci/azure-pipelines/master.yml
similarity index 100%
rename from .azure-pipelines/master.yml
rename to src/ci/azure-pipelines/master.yml
diff --git a/.azure-pipelines/pr.yml b/src/ci/azure-pipelines/pr.yml
similarity index 100%
rename from .azure-pipelines/pr.yml
rename to src/ci/azure-pipelines/pr.yml
diff --git a/.azure-pipelines/steps/install-clang.yml b/src/ci/azure-pipelines/steps/install-clang.yml
similarity index 100%
rename from .azure-pipelines/steps/install-clang.yml
rename to src/ci/azure-pipelines/steps/install-clang.yml
diff --git a/.azure-pipelines/steps/install-sccache.yml b/src/ci/azure-pipelines/steps/install-sccache.yml
similarity index 100%
rename from .azure-pipelines/steps/install-sccache.yml
rename to src/ci/azure-pipelines/steps/install-sccache.yml
diff --git a/.azure-pipelines/steps/install-windows-build-deps.yml b/src/ci/azure-pipelines/steps/install-windows-build-deps.yml
similarity index 100%
rename from .azure-pipelines/steps/install-windows-build-deps.yml
rename to src/ci/azure-pipelines/steps/install-windows-build-deps.yml
diff --git a/.azure-pipelines/steps/run.yml b/src/ci/azure-pipelines/steps/run.yml
similarity index 100%
rename from .azure-pipelines/steps/run.yml
rename to src/ci/azure-pipelines/steps/run.yml
diff --git a/.azure-pipelines/try.yml b/src/ci/azure-pipelines/try.yml
similarity index 100%
rename from .azure-pipelines/try.yml
rename to src/ci/azure-pipelines/try.yml

From 7a75a663fb55233081e2599857ee61197d23a398 Mon Sep 17 00:00:00 2001
From: Taiki Endo <te316e89@gmail.com>
Date: Mon, 27 May 2019 01:43:12 +0900
Subject: [PATCH 08/20] Allow lifetime elision in `Pin<&(mut) Self>`

---
 src/librustc/middle/resolve_lifetime.rs       | 29 ++++++++-
 .../self/arbitrary_self_types_pin_lifetime.rs | 60 +++++++++++++++++++
 ...rary_self_types_pin_lifetime_impl_trait.rs | 13 ++++
 ..._self_types_pin_lifetime_impl_trait.stderr | 20 +++++++
 ...itrary_self_types_pin_lifetime_mismatch.rs | 13 ++++
 ...ry_self_types_pin_lifetime_mismatch.stderr | 18 ++++++
 src/test/ui/self/self_lifetime.rs             | 13 ++++
 7 files changed, 165 insertions(+), 1 deletion(-)
 create mode 100644 src/test/ui/self/arbitrary_self_types_pin_lifetime.rs
 create mode 100644 src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.rs
 create mode 100644 src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr
 create mode 100644 src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.rs
 create mode 100644 src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.stderr
 create mode 100644 src/test/ui/self/self_lifetime.rs

diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index 412346bab257e..3bd423207d511 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -2145,7 +2145,34 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
                 false
             };
 
-            if let hir::TyKind::Rptr(lifetime_ref, ref mt) = inputs[0].node {
+            let mut self_arg = &inputs[0].node;
+
+            // Apply `self: &(mut) Self` elision rules even if nested in `Pin`.
+            loop {
+                if let hir::TyKind::Path(hir::QPath::Resolved(None, ref path)) = *self_arg {
+                    if let Res::Def(DefKind::Struct, def_id) = path.res {
+                        if self.tcx.lang_items().pin_type() == Some(def_id) {
+                            if let Some(args) = path
+                                .segments
+                                .last()
+                                .and_then(|segment| segment.args.as_ref())
+                            {
+                                if args.args.len() == 1 {
+                                    if let GenericArg::Type(ty) = &args.args[0] {
+                                        self_arg = &ty.node;
+                                        // Keep dereferencing `self_arg` until we get to non-`Pin`
+                                        // types.
+                                        continue;
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+                break;
+            }
+
+            if let hir::TyKind::Rptr(lifetime_ref, ref mt) = *self_arg {
                 if let hir::TyKind::Path(hir::QPath::Resolved(None, ref path)) = mt.ty.node {
                     if is_self_ty(path.res) {
                         if let Some(&lifetime) = self.map.defs.get(&lifetime_ref.hir_id) {
diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime.rs b/src/test/ui/self/arbitrary_self_types_pin_lifetime.rs
new file mode 100644
index 0000000000000..668aaf7166a0f
--- /dev/null
+++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime.rs
@@ -0,0 +1,60 @@
+// compile-pass
+
+use std::pin::Pin;
+use std::task::{Context, Poll};
+
+struct Foo;
+
+impl Foo {
+    fn pin_ref(self: Pin<&Self>) -> Pin<&Self> { self }
+
+    fn pin_mut(self: Pin<&mut Self>) -> Pin<&mut Self> { self }
+
+    fn pin_pin_pin_ref(self: Pin<Pin<Pin<&Self>>>) -> Pin<Pin<Pin<&Self>>> { self }
+
+    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 {
+    fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg }
+}
+
+struct Bar<T: Unpin, U: Unpin> {
+    field1: T,
+    field2: U,
+}
+
+impl<T: Unpin, U: Unpin> Bar<T, U> {
+    fn fields(self: Pin<&mut Self>) -> (Pin<&mut T>, Pin<&mut U>) {
+        let this = self.get_mut();
+        (Pin::new(&mut this.field1), Pin::new(&mut this.field2))
+    }
+}
+
+trait AsyncBufRead {
+    fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>)
+        -> Poll<std::io::Result<&[u8]>>;
+}
+
+struct Baz(Vec<u8>);
+
+impl AsyncBufRead for Baz {
+    fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>)
+        -> Poll<std::io::Result<&[u8]>>
+    {
+        Poll::Ready(Ok(&self.get_mut().0))
+    }
+}
+
+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() };
+    let mut bar = Bar { field1: 0u8, field2: 1u8 };
+    { Pin::new(&mut bar).fields() };
+}
diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.rs b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.rs
new file mode 100644
index 0000000000000..ad8959727cbee
--- /dev/null
+++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.rs
@@ -0,0 +1,13 @@
+// compile-fail
+
+use std::pin::Pin;
+
+struct Foo;
+
+impl Foo {
+    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.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr
new file mode 100644
index 0000000000000..5118280e7ec0c
--- /dev/null
+++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr
@@ -0,0 +1,20 @@
+error: cannot infer an appropriate lifetime
+  --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait.rs:8:44
+   |
+LL |     fn f(self: Pin<&Self>) -> impl Clone { self }
+   |                               ----------   ^^^^ ...but this borrow...
+   |                               |
+   |                               this return type evaluates to the `'static` lifetime...
+   |
+note: ...can't outlive the anonymous lifetime #1 defined on the method body at 8:5
+  --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait.rs:8:5
+   |
+LL |     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 anonymous lifetime #1 defined on the method body at 8:5
+   |
+LL |     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.rs b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.rs
new file mode 100644
index 0000000000000..3ed5e6bdd7211
--- /dev/null
+++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.rs
@@ -0,0 +1,13 @@
+// compile-fail
+
+use std::pin::Pin;
+
+struct Foo;
+
+impl Foo {
+    fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f } //~ ERROR E0623
+
+    fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) } //~ ERROR E0623
+}
+
+fn main() {}
diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.stderr
new file mode 100644
index 0000000000000..6e345b03056e9
--- /dev/null
+++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.stderr
@@ -0,0 +1,18 @@
+error[E0623]: lifetime mismatch
+  --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:8:46
+   |
+LL |     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.rs:10:76
+   |
+LL |     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: aborting due to 2 previous errors
+
diff --git a/src/test/ui/self/self_lifetime.rs b/src/test/ui/self/self_lifetime.rs
new file mode 100644
index 0000000000000..a3163ade0404f
--- /dev/null
+++ b/src/test/ui/self/self_lifetime.rs
@@ -0,0 +1,13 @@
+// compile-pass
+
+struct Foo<'a>(&'a ());
+impl<'a> Foo<'a> {
+    fn foo<'b>(self: &'b Foo<'a>) -> &() { self.0 }
+}
+
+type Alias = Foo<'static>;
+impl Alias {
+    fn bar<'a>(self: &Alias, arg: &'a ()) -> &() { arg }
+}
+
+fn main() {}

From ee53d9a802ba34701904cb34537144f61f93c410 Mon Sep 17 00:00:00 2001
From: Taiki Endo <te316e89@gmail.com>
Date: Mon, 27 May 2019 22:06:08 +0900
Subject: [PATCH 09/20] Remove query for `.pin_type()`

---
 src/librustc/middle/resolve_lifetime.rs       | 66 +++++++++----------
 .../self/arbitrary_self_types_pin_lifetime.rs |  2 +-
 ...itrary_self_types_pin_lifetime_mismatch.rs |  5 ++
 ...ry_self_types_pin_lifetime_mismatch.stderr | 10 ++-
 4 files changed, 47 insertions(+), 36 deletions(-)

diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index 3bd423207d511..3fe11a46081ed 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -2145,46 +2145,44 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
                 false
             };
 
-            let mut self_arg = &inputs[0].node;
-
-            // Apply `self: &(mut) Self` elision rules even if nested in `Pin`.
-            loop {
-                if let hir::TyKind::Path(hir::QPath::Resolved(None, ref path)) = *self_arg {
-                    if let Res::Def(DefKind::Struct, def_id) = path.res {
-                        if self.tcx.lang_items().pin_type() == Some(def_id) {
-                            if let Some(args) = path
-                                .segments
-                                .last()
-                                .and_then(|segment| segment.args.as_ref())
-                            {
-                                if args.args.len() == 1 {
-                                    if let GenericArg::Type(ty) = &args.args[0] {
-                                        self_arg = &ty.node;
-                                        // Keep dereferencing `self_arg` until we get to non-`Pin`
-                                        // types.
-                                        continue;
-                                    }
-                                }
+            struct SelfVisitor<'a, F: FnMut(Res) -> bool> {
+                is_self_ty: F,
+                map: &'a NamedRegionMap,
+                lifetime: Option<Region>,
+            }
+
+            impl<'a, F: FnMut(Res) -> bool> Visitor<'a> for SelfVisitor<'a, F> {
+                fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'a> {
+                    NestedVisitorMap::None
+                }
+
+                fn visit_ty(&mut self, ty: &'a hir::Ty) {
+                    if let hir::TyKind::Rptr(lifetime_ref, ref mt) = ty.node {
+                        if let hir::TyKind::Path(hir::QPath::Resolved(None, ref path)) = mt.ty.node
+                        {
+                            if (self.is_self_ty)(path.res) {
+                                self.lifetime = self.map.defs.get(&lifetime_ref.hir_id).copied();
+                                return;
                             }
                         }
                     }
+                    intravisit::walk_ty(self, ty)
                 }
-                break;
             }
 
-            if let hir::TyKind::Rptr(lifetime_ref, ref mt) = *self_arg {
-                if let hir::TyKind::Path(hir::QPath::Resolved(None, ref path)) = mt.ty.node {
-                    if is_self_ty(path.res) {
-                        if let Some(&lifetime) = self.map.defs.get(&lifetime_ref.hir_id) {
-                            let scope = Scope::Elision {
-                                elide: Elide::Exact(lifetime),
-                                s: self.scope,
-                            };
-                            self.with(scope, |_, this| this.visit_ty(output));
-                            return;
-                        }
-                    }
-                }
+            let mut visitor = SelfVisitor {
+                is_self_ty,
+                map: self.map,
+                lifetime: None,
+            };
+            visitor.visit_ty(&inputs[0]);
+            if let Some(lifetime) = visitor.lifetime {
+                let scope = Scope::Elision {
+                    elide: Elide::Exact(lifetime),
+                    s: self.scope,
+                };
+                self.with(scope, |_, this| this.visit_ty(output));
+                return;
             }
         }
 
diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime.rs b/src/test/ui/self/arbitrary_self_types_pin_lifetime.rs
index 668aaf7166a0f..ba574eeb4609b 100644
--- a/src/test/ui/self/arbitrary_self_types_pin_lifetime.rs
+++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime.rs
@@ -19,7 +19,7 @@ impl Foo {
 
 type Alias<T> = Pin<T>;
 impl Foo {
-    fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg }
+    fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> Alias<&Self> { self }
 }
 
 struct Bar<T: Unpin, U: Unpin> {
diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.rs b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.rs
index 3ed5e6bdd7211..fc5f94201b81a 100644
--- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.rs
+++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.rs
@@ -10,4 +10,9 @@ impl Foo {
     fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) } //~ ERROR E0623
 }
 
+type Alias<T> = Pin<T>;
+impl Foo {
+    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.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.stderr
index 6e345b03056e9..3296e14f806e1 100644
--- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.stderr
+++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.stderr
@@ -14,5 +14,13 @@ LL |     fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self,
    |                               |
    |                               this parameter and the return type are declared with different lifetimes...
 
-error: aborting due to 2 previous errors
+error[E0623]: lifetime mismatch
+  --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:15:58
+   |
+LL |     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
 

From 07903fe53ecca681936c5b9da0e9511fb80281eb Mon Sep 17 00:00:00 2001
From: Taiki Endo <te316e89@gmail.com>
Date: Wed, 29 May 2019 17:37:28 +0900
Subject: [PATCH 10/20] Make is_self_ty a method on SelfVisitor

---
 src/librustc/middle/resolve_lifetime.rs | 67 +++++++++++++------------
 1 file changed, 35 insertions(+), 32 deletions(-)

diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index 3fe11a46081ed..5c5e73aa427a4 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -2117,41 +2117,44 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
         // First (determined here), if `self` is by-reference, then the
         // implied output region is the region of the self parameter.
         if has_self {
-            // Look for `self: &'a Self` - also desugared from `&'a self`,
-            // and if that matches, use it for elision and return early.
-            let is_self_ty = |res: Res| {
-                if let Res::SelfTy(..) = res {
-                    return true;
-                }
-
-                // Can't always rely on literal (or implied) `Self` due
-                // to the way elision rules were originally specified.
-                let impl_self = impl_self.map(|ty| &ty.node);
-                if let Some(&hir::TyKind::Path(hir::QPath::Resolved(None, ref path))) = impl_self {
-                    match path.res {
-                        // Whitelist the types that unambiguously always
-                        // result in the same type constructor being used
-                        // (it can't differ between `Self` and `self`).
-                        Res::Def(DefKind::Struct, _)
-                        | Res::Def(DefKind::Union, _)
-                        | Res::Def(DefKind::Enum, _)
-                        | Res::PrimTy(_) => {
-                            return res == path.res
-                        }
-                        _ => {}
+            struct SelfVisitor<'a> {
+                map: &'a NamedRegionMap,
+                impl_self: Option<&'a hir::TyKind>,
+                lifetime: Option<Region>,
+            }
+
+            impl SelfVisitor<'_> {
+                // Look for `self: &'a Self` - also desugared from `&'a self`,
+                // and if that matches, use it for elision and return early.
+                fn is_self_ty(&self, res: Res) -> bool {
+                    if let Res::SelfTy(..) = res {
+                        return true;
                     }
-                }
 
-                false
-            };
+                    // Can't always rely on literal (or implied) `Self` due
+                    // to the way elision rules were originally specified.
+                    if let Some(&hir::TyKind::Path(hir::QPath::Resolved(None, ref path))) =
+                        self.impl_self
+                    {
+                        match path.res {
+                            // Whitelist the types that unambiguously always
+                            // result in the same type constructor being used
+                            // (it can't differ between `Self` and `self`).
+                            Res::Def(DefKind::Struct, _)
+                            | Res::Def(DefKind::Union, _)
+                            | Res::Def(DefKind::Enum, _)
+                            | Res::PrimTy(_) => {
+                                return res == path.res
+                            }
+                            _ => {}
+                        }
+                    }
 
-            struct SelfVisitor<'a, F: FnMut(Res) -> bool> {
-                is_self_ty: F,
-                map: &'a NamedRegionMap,
-                lifetime: Option<Region>,
+                    false
+                }
             }
 
-            impl<'a, F: FnMut(Res) -> bool> Visitor<'a> for SelfVisitor<'a, F> {
+            impl<'a> Visitor<'a> for SelfVisitor<'a> {
                 fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'a> {
                     NestedVisitorMap::None
                 }
@@ -2160,7 +2163,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
                     if let hir::TyKind::Rptr(lifetime_ref, ref mt) = ty.node {
                         if let hir::TyKind::Path(hir::QPath::Resolved(None, ref path)) = mt.ty.node
                         {
-                            if (self.is_self_ty)(path.res) {
+                            if self.is_self_ty(path.res) {
                                 self.lifetime = self.map.defs.get(&lifetime_ref.hir_id).copied();
                                 return;
                             }
@@ -2171,8 +2174,8 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
             }
 
             let mut visitor = SelfVisitor {
-                is_self_ty,
                 map: self.map,
+                impl_self: impl_self.map(|ty| &ty.node),
                 lifetime: None,
             };
             visitor.visit_ty(&inputs[0]);

From a2b4ec2f656afeeb6fbc22cdf23124f02dbcaf07 Mon Sep 17 00:00:00 2001
From: Taiki Endo <te316e89@gmail.com>
Date: Wed, 29 May 2019 18:50:24 +0900
Subject: [PATCH 11/20] Use Set1<Region> instead of Option<Region>

---
 src/librustc/middle/resolve_lifetime.rs | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index 5c5e73aa427a4..3d80fb28c738d 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -2120,7 +2120,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
             struct SelfVisitor<'a> {
                 map: &'a NamedRegionMap,
                 impl_self: Option<&'a hir::TyKind>,
-                lifetime: Option<Region>,
+                lifetime: Set1<Region>,
             }
 
             impl SelfVisitor<'_> {
@@ -2164,8 +2164,9 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
                         if let hir::TyKind::Path(hir::QPath::Resolved(None, ref path)) = mt.ty.node
                         {
                             if self.is_self_ty(path.res) {
-                                self.lifetime = self.map.defs.get(&lifetime_ref.hir_id).copied();
-                                return;
+                                if let Some(lifetime) = self.map.defs.get(&lifetime_ref.hir_id) {
+                                    self.lifetime.insert(*lifetime);
+                                }
                             }
                         }
                     }
@@ -2176,10 +2177,10 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
             let mut visitor = SelfVisitor {
                 map: self.map,
                 impl_self: impl_self.map(|ty| &ty.node),
-                lifetime: None,
+                lifetime: Set1::Empty,
             };
             visitor.visit_ty(&inputs[0]);
-            if let Some(lifetime) = visitor.lifetime {
+            if let Set1::One(lifetime) = visitor.lifetime {
                 let scope = Scope::Elision {
                     elide: Elide::Exact(lifetime),
                     s: self.scope,

From bdc8b9381df53df0ac89ec12c61c2857347fa52a Mon Sep 17 00:00:00 2001
From: Niko Matsakis <niko@alum.mit.edu>
Date: Fri, 28 Jun 2019 14:46:45 -0400
Subject: [PATCH 12/20] add a bevy of new test cases

---
 src/test/ui/self/elision/README.md            | 45 ++++++++++++++
 src/test/ui/self/elision/alias.rs             | 32 ++++++++++
 src/test/ui/self/elision/alias.stderr         |  7 +++
 src/test/ui/self/elision/lt-alias.rs          | 38 ++++++++++++
 src/test/ui/self/elision/lt-ref-self.rs       | 38 ++++++++++++
 src/test/ui/self/elision/lt-ref-self.stderr   | 62 +++++++++++++++++++
 src/test/ui/self/elision/lt-self.rs           | 49 +++++++++++++++
 src/test/ui/self/elision/lt-struct.rs         | 36 +++++++++++
 src/test/ui/self/elision/ref-alias.rs         | 39 ++++++++++++
 src/test/ui/self/elision/ref-mut-alias.rs     | 32 ++++++++++
 src/test/ui/self/elision/ref-mut-alias.stderr |  7 +++
 src/test/ui/self/elision/ref-mut-self.rs      | 40 ++++++++++++
 src/test/ui/self/elision/ref-mut-self.stderr  | 62 +++++++++++++++++++
 src/test/ui/self/elision/ref-mut-struct.rs    | 34 ++++++++++
 .../ui/self/elision/ref-mut-struct.stderr     | 52 ++++++++++++++++
 src/test/ui/self/elision/ref-self.rs          | 40 ++++++++++++
 src/test/ui/self/elision/ref-self.stderr      | 62 +++++++++++++++++++
 src/test/ui/self/elision/ref-struct.rs        | 34 ++++++++++
 src/test/ui/self/elision/ref-struct.stderr    | 52 ++++++++++++++++
 src/test/ui/self/elision/self.rs              | 36 +++++++++++
 src/test/ui/self/elision/struct.rs            | 34 ++++++++++
 21 files changed, 831 insertions(+)
 create mode 100644 src/test/ui/self/elision/README.md
 create mode 100644 src/test/ui/self/elision/alias.rs
 create mode 100644 src/test/ui/self/elision/alias.stderr
 create mode 100644 src/test/ui/self/elision/lt-alias.rs
 create mode 100644 src/test/ui/self/elision/lt-ref-self.rs
 create mode 100644 src/test/ui/self/elision/lt-ref-self.stderr
 create mode 100644 src/test/ui/self/elision/lt-self.rs
 create mode 100644 src/test/ui/self/elision/lt-struct.rs
 create mode 100644 src/test/ui/self/elision/ref-alias.rs
 create mode 100644 src/test/ui/self/elision/ref-mut-alias.rs
 create mode 100644 src/test/ui/self/elision/ref-mut-alias.stderr
 create mode 100644 src/test/ui/self/elision/ref-mut-self.rs
 create mode 100644 src/test/ui/self/elision/ref-mut-self.stderr
 create mode 100644 src/test/ui/self/elision/ref-mut-struct.rs
 create mode 100644 src/test/ui/self/elision/ref-mut-struct.stderr
 create mode 100644 src/test/ui/self/elision/ref-self.rs
 create mode 100644 src/test/ui/self/elision/ref-self.stderr
 create mode 100644 src/test/ui/self/elision/ref-struct.rs
 create mode 100644 src/test/ui/self/elision/ref-struct.stderr
 create mode 100644 src/test/ui/self/elision/self.rs
 create mode 100644 src/test/ui/self/elision/struct.rs

diff --git a/src/test/ui/self/elision/README.md b/src/test/ui/self/elision/README.md
new file mode 100644
index 0000000000000..de29a9d5e53bc
--- /dev/null
+++ b/src/test/ui/self/elision/README.md
@@ -0,0 +1,45 @@
+Test cases intended to to document behavior and tryto exhaustively
+explore the combinations. 
+
+## Confidence
+
+These tests are not yet considered 100% normative, in that some
+aspects of the current behavior are not desirable. This is expressed
+in the "confidence" field in the following table. Values:
+
+| Confidence | Interpretation |
+| --- | --- |
+| 100% | this will remain recommended behavior |
+| 75% | unclear whether we will continue to accept this |
+| 50% | this will likely be deprecated but remain valid |
+| 25% | this could change in the future |
+| 0% | this is definitely bogus and will likely change in the future in *some* way |
+
+## Tests
+
+| Test file | `Self` type | Pattern | Current elision behavior | Confidence |
+| --- | --- | --- | --- | --- |
+| `self.rs` | `Struct` | `Self` | ignore `self` parameter | 100% |
+| `struct.rs` | `Struct` | `Struct` | ignore `self` parameter | 100% |
+| `alias.rs` | `Struct` | `Alias` | ignore `self` parameter | 100% |
+| `ref-self.rs` | `Struct` | `&Self` | take lifetime from `&Self` | 100% |
+| `ref-mut-self.rs` | `Struct` | `&mut Self` | take lifetime from `&Self` | 100% |
+| `ref-struct.rs` | `Struct` | `&Struct` | take lifetime from `&Self` | 50% |
+| `ref-mut-struct.rs` | `Struct` | `&Struct` | take lifetime from `&Self` | 50% |
+| `ref-alias.rs` | `Struct` | `&Alias` | ignore `Alias` | 0% |
+| `ref-mut-alias.rs` | `Struct` | `&Alias` | ignore `Alias` | 0% |
+| `lt-self.rs` | `Struct<'a>` | `Self` | ignore `Self` (and hence `'a`) | 25% |
+| `lt-struct.rs` | `Struct<'a>` | `Self` | ignore `Self` (and hence `'a`) | 0% |
+| `lt-alias.rs`   | `Alias<'a>` | `Self` | ignore `Self` (and hence `'a`) | 0% |
+| `lt-ref-self.rs` | `Struct<'a>` | `&Self` | take lifetime from `&Self` | 75% |
+
+In each case, we test the following patterns:
+
+- `self: XXX`
+- `self: Box<XXX>`
+- `self: Pin<XXX>`
+- `self: Box<Box<XXX>>`
+- `self: Box<Pin<XXX>>`
+
+In the non-reference cases, `Pin` causes errors so we substitute `Rc`.
+
diff --git a/src/test/ui/self/elision/alias.rs b/src/test/ui/self/elision/alias.rs
new file mode 100644
index 0000000000000..6f113ec1a4bc9
--- /dev/null
+++ b/src/test/ui/self/elision/alias.rs
@@ -0,0 +1,32 @@
+#![feature(arbitrary_self_types)]
+#![allow(non_snake_case)]
+
+use std::rc::Rc;
+
+struct Struct { }
+
+type Alias = Struct;
+
+impl Struct {
+    // Test using an alias for `Struct`:
+
+    fn alias(self: Alias, f: &u32) -> &u32 {
+        f
+    }
+
+    fn box_Alias(self: Box<Alias>, f: &u32) -> &u32 {
+        f
+    }
+
+    fn rc_Alias(self: Rc<Alias>, f: &u32) -> &u32 {
+        f
+    }
+
+    fn box_box_Alias(self: Box<Box<Alias>>, f: &u32) -> &u32 {
+        f
+    }
+
+    fn box_rc_Alias(self: Box<Rc<Alias>>, f: &u32) -> &u32 {
+        f
+    }
+}
diff --git a/src/test/ui/self/elision/alias.stderr b/src/test/ui/self/elision/alias.stderr
new file mode 100644
index 0000000000000..a8f2a125b5eb7
--- /dev/null
+++ b/src/test/ui/self/elision/alias.stderr
@@ -0,0 +1,7 @@
+error[E0601]: `main` function not found in crate `alias`
+   |
+   = note: consider adding a `main` function to `$DIR/alias.rs`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0601`.
diff --git a/src/test/ui/self/elision/lt-alias.rs b/src/test/ui/self/elision/lt-alias.rs
new file mode 100644
index 0000000000000..044682789007d
--- /dev/null
+++ b/src/test/ui/self/elision/lt-alias.rs
@@ -0,0 +1,38 @@
+// run-pass
+
+#![feature(arbitrary_self_types)]
+#![allow(non_snake_case)]
+
+use std::rc::Rc;
+
+struct Struct<'a> { x: &'a u32 }
+
+type Alias<'a> = Struct<'a>;
+
+impl<'a> Alias<'a> {
+    fn take_self(self, f: &u32) -> &u32 {
+        f
+    }
+
+    fn take_Alias(self: Alias<'a>, f: &u32) -> &u32 {
+        f
+    }
+
+    fn take_Box_Alias(self: Box<Alias<'a>>, f: &u32) -> &u32 {
+        f
+    }
+
+    fn take_Box_Box_Alias(self: Box<Box<Alias<'a>>>, f: &u32) -> &u32 {
+        f
+    }
+
+    fn take_Rc_Alias(self: Rc<Alias<'a>>, f: &u32) -> &u32 {
+        f
+    }
+
+    fn take_Box_Rc_Alias(self: Box<Rc<Alias<'a>>>, f: &u32) -> &u32 {
+        f
+    }
+}
+
+fn main() { }
diff --git a/src/test/ui/self/elision/lt-ref-self.rs b/src/test/ui/self/elision/lt-ref-self.rs
new file mode 100644
index 0000000000000..8abf2876a5c1b
--- /dev/null
+++ b/src/test/ui/self/elision/lt-ref-self.rs
@@ -0,0 +1,38 @@
+#![feature(arbitrary_self_types)]
+#![allow(non_snake_case)]
+
+use std::pin::Pin;
+
+struct Struct<'a> { data: &'a u32 }
+
+impl<'a> Struct<'a> {
+    // Test using `&self` sugar:
+
+    fn ref_self(&self, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+
+    // Test using `&Self` explicitly:
+
+    fn ref_Self(self: &Self, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+
+    fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+
+    fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+
+    fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+
+    fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+}
+
+fn main() { }
diff --git a/src/test/ui/self/elision/lt-ref-self.stderr b/src/test/ui/self/elision/lt-ref-self.stderr
new file mode 100644
index 0000000000000..f73b3eddd3821
--- /dev/null
+++ b/src/test/ui/self/elision/lt-ref-self.stderr
@@ -0,0 +1,62 @@
+error[E0623]: lifetime mismatch
+  --> $DIR/lt-ref-self.rs:12:9
+   |
+LL |     fn ref_self(&self, f: &u32) -> &u32 {
+   |                           ----     ----
+   |                           |
+   |                           this parameter and the return type are declared with different lifetimes...
+LL |         f
+   |         ^ ...but data from `f` is returned here
+
+error[E0623]: lifetime mismatch
+  --> $DIR/lt-ref-self.rs:18:9
+   |
+LL |     fn ref_Self(self: &Self, f: &u32) -> &u32 {
+   |                                 ----     ----
+   |                                 |
+   |                                 this parameter and the return type are declared with different lifetimes...
+LL |         f
+   |         ^ ...but data from `f` is returned here
+
+error[E0623]: lifetime mismatch
+  --> $DIR/lt-ref-self.rs:22:9
+   |
+LL |     fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
+   |                                          ----     ----
+   |                                          |
+   |                                          this parameter and the return type are declared with different lifetimes...
+LL |         f
+   |         ^ ...but data from `f` is returned here
+
+error[E0623]: lifetime mismatch
+  --> $DIR/lt-ref-self.rs:26:9
+   |
+LL |     fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
+   |                                          ----     ----
+   |                                          |
+   |                                          this parameter and the return type are declared with different lifetimes...
+LL |         f
+   |         ^ ...but data from `f` is returned here
+
+error[E0623]: lifetime mismatch
+  --> $DIR/lt-ref-self.rs:30:9
+   |
+LL |     fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
+   |                                                   ----     ----
+   |                                                   |
+   |                                                   this parameter and the return type are declared with different lifetimes...
+LL |         f
+   |         ^ ...but data from `f` is returned here
+
+error[E0623]: lifetime mismatch
+  --> $DIR/lt-ref-self.rs:34:9
+   |
+LL |     fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
+   |                                               ----     ----
+   |                                               |
+   |                                               this parameter and the return type are declared with different lifetimes...
+LL |         f
+   |         ^ ...but data from `f` is returned here
+
+error: aborting due to 6 previous errors
+
diff --git a/src/test/ui/self/elision/lt-self.rs b/src/test/ui/self/elision/lt-self.rs
new file mode 100644
index 0000000000000..c33df08e0ee48
--- /dev/null
+++ b/src/test/ui/self/elision/lt-self.rs
@@ -0,0 +1,49 @@
+// run-pass
+
+#![feature(arbitrary_self_types)]
+#![allow(non_snake_case)]
+
+use std::pin::Pin;
+use std::rc::Rc;
+
+struct Struct<'a> {
+    x: &'a u32
+}
+
+impl<'a> Struct<'a> {
+    fn take_self(self, f: &u32) -> &u32 {
+        f
+    }
+
+    fn take_Self(self: Self, f: &u32) -> &u32 {
+        f
+    }
+
+    fn take_Box_Self(self: Box<Self>, f: &u32) -> &u32 {
+        f
+    }
+
+    fn take_Box_Box_Self(self: Box<Box<Self>>, f: &u32) -> &u32 {
+        f
+    }
+
+    fn take_Rc_Self(self: Rc<Self>, f: &u32) -> &u32 {
+        f
+    }
+
+    fn take_Box_Rc_Self(self: Box<Rc<Self>>, f: &u32) -> &u32 {
+        f
+    }
+
+    // N/A
+    //fn take_Pin_Self(self: Pin<Self>, f: &u32) -> &u32 {
+    //    f
+    //}
+
+    // N/A
+    //fn take_Box_Pin_Self(self: Box<Pin<Self>>, f: &u32) -> &u32 {
+    //    f
+    //}
+}
+
+fn main() { }
diff --git a/src/test/ui/self/elision/lt-struct.rs b/src/test/ui/self/elision/lt-struct.rs
new file mode 100644
index 0000000000000..79ffc8fd6f4bd
--- /dev/null
+++ b/src/test/ui/self/elision/lt-struct.rs
@@ -0,0 +1,36 @@
+// run-pass
+
+#![feature(arbitrary_self_types)]
+#![allow(non_snake_case)]
+
+use std::rc::Rc;
+
+struct Struct<'a> { x: &'a u32 }
+
+impl<'a> Struct<'a> {
+    fn take_self(self, f: &u32) -> &u32 {
+        f
+    }
+
+    fn take_Struct(self: Struct<'a>, f: &u32) -> &u32 {
+        f
+    }
+
+    fn take_Box_Struct(self: Box<Struct<'a>>, f: &u32) -> &u32 {
+        f
+    }
+
+    fn take_Box_Box_Struct(self: Box<Box<Struct<'a>>>, f: &u32) -> &u32 {
+        f
+    }
+
+    fn take_Rc_Struct(self: Rc<Struct<'a>>, f: &u32) -> &u32 {
+        f
+    }
+
+    fn take_Box_Rc_Struct(self: Box<Rc<Struct<'a>>>, f: &u32) -> &u32 {
+        f
+    }
+}
+
+fn main() { }
diff --git a/src/test/ui/self/elision/ref-alias.rs b/src/test/ui/self/elision/ref-alias.rs
new file mode 100644
index 0000000000000..23bfe8fb029f6
--- /dev/null
+++ b/src/test/ui/self/elision/ref-alias.rs
@@ -0,0 +1,39 @@
+// run-pass
+
+#![feature(arbitrary_self_types)]
+#![allow(non_snake_case)]
+
+use std::pin::Pin;
+
+struct Struct { }
+
+type Alias = Struct;
+
+impl Struct {
+    // Test using an alias for `Struct`:
+    //
+    // FIXME. We currently fail to recognize this as the self type, which
+    // feels like a bug.
+
+    fn ref_Alias(self: &Alias, f: &u32) -> &u32 {
+        f
+    }
+
+    fn box_ref_Alias(self: Box<&Alias>, f: &u32) -> &u32 {
+        f
+    }
+
+    fn pin_ref_Alias(self: Pin<&Alias>, f: &u32) -> &u32 {
+        f
+    }
+
+    fn box_box_ref_Alias(self: Box<Box<&Alias>>, f: &u32) -> &u32 {
+        f
+    }
+
+    fn box_pin_ref_Alias(self: Box<Pin<&Alias>>, f: &u32) -> &u32 {
+        f
+    }
+}
+
+fn main() { }
diff --git a/src/test/ui/self/elision/ref-mut-alias.rs b/src/test/ui/self/elision/ref-mut-alias.rs
new file mode 100644
index 0000000000000..abb412965768d
--- /dev/null
+++ b/src/test/ui/self/elision/ref-mut-alias.rs
@@ -0,0 +1,32 @@
+#![feature(arbitrary_self_types)]
+#![allow(non_snake_case)]
+
+use std::pin::Pin;
+
+struct Struct { }
+
+type Alias = Struct;
+
+impl Struct {
+    // Test using an alias for `Struct`:
+
+    fn ref_Alias(self: &mut Alias, f: &u32) -> &u32 {
+        f
+    }
+
+    fn box_ref_Alias(self: Box<&mut Alias>, f: &u32) -> &u32 {
+        f
+    }
+
+    fn pin_ref_Alias(self: Pin<&mut Alias>, f: &u32) -> &u32 {
+        f
+    }
+
+    fn box_box_ref_Alias(self: Box<Box<&mut Alias>>, f: &u32) -> &u32 {
+        f
+    }
+
+    fn box_pin_ref_Alias(self: Box<Pin<&mut Alias>>, f: &u32) -> &u32 {
+        f
+    }
+}
diff --git a/src/test/ui/self/elision/ref-mut-alias.stderr b/src/test/ui/self/elision/ref-mut-alias.stderr
new file mode 100644
index 0000000000000..cf202ccaa5d88
--- /dev/null
+++ b/src/test/ui/self/elision/ref-mut-alias.stderr
@@ -0,0 +1,7 @@
+error[E0601]: `main` function not found in crate `ref_mut_alias`
+   |
+   = note: consider adding a `main` function to `$DIR/ref-mut-alias.rs`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0601`.
diff --git a/src/test/ui/self/elision/ref-mut-self.rs b/src/test/ui/self/elision/ref-mut-self.rs
new file mode 100644
index 0000000000000..6705ca9e30598
--- /dev/null
+++ b/src/test/ui/self/elision/ref-mut-self.rs
@@ -0,0 +1,40 @@
+#![feature(arbitrary_self_types)]
+#![allow(non_snake_case)]
+
+use std::pin::Pin;
+
+struct Struct { }
+
+type Alias = Struct;
+
+impl Struct {
+    // Test using `&mut self` sugar:
+
+    fn ref_self(&mut self, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+
+    // Test using `&mut Self` explicitly:
+
+    fn ref_Self(self: &mut Self, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+
+    fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+
+    fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+
+    fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+
+    fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+}
+
+fn main() { }
diff --git a/src/test/ui/self/elision/ref-mut-self.stderr b/src/test/ui/self/elision/ref-mut-self.stderr
new file mode 100644
index 0000000000000..05dc5b774c832
--- /dev/null
+++ b/src/test/ui/self/elision/ref-mut-self.stderr
@@ -0,0 +1,62 @@
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-mut-self.rs:14:9
+   |
+LL |     fn ref_self(&mut self, f: &u32) -> &u32 {
+   |                               ----     ----
+   |                               |
+   |                               this parameter and the return type are declared with different lifetimes...
+LL |         f
+   |         ^ ...but data from `f` is returned here
+
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-mut-self.rs:20:9
+   |
+LL |     fn ref_Self(self: &mut Self, f: &u32) -> &u32 {
+   |                                     ----     ----
+   |                                     |
+   |                                     this parameter and the return type are declared with different lifetimes...
+LL |         f
+   |         ^ ...but data from `f` is returned here
+
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-mut-self.rs:24:9
+   |
+LL |     fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 {
+   |                                              ----     ----
+   |                                              |
+   |                                              this parameter and the return type are declared with different lifetimes...
+LL |         f
+   |         ^ ...but data from `f` is returned here
+
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-mut-self.rs:28:9
+   |
+LL |     fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 {
+   |                                              ----     ----
+   |                                              |
+   |                                              this parameter and the return type are declared with different lifetimes...
+LL |         f
+   |         ^ ...but data from `f` is returned here
+
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-mut-self.rs:32:9
+   |
+LL |     fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 {
+   |                                                       ----     ----
+   |                                                       |
+   |                                                       this parameter and the return type are declared with different lifetimes...
+LL |         f
+   |         ^ ...but data from `f` is returned here
+
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-mut-self.rs:36:9
+   |
+LL |     fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 {
+   |                                                       ----     ----
+   |                                                       |
+   |                                                       this parameter and the return type are declared with different lifetimes...
+LL |         f
+   |         ^ ...but data from `f` is returned here
+
+error: aborting due to 6 previous errors
+
diff --git a/src/test/ui/self/elision/ref-mut-struct.rs b/src/test/ui/self/elision/ref-mut-struct.rs
new file mode 100644
index 0000000000000..f063728e24751
--- /dev/null
+++ b/src/test/ui/self/elision/ref-mut-struct.rs
@@ -0,0 +1,34 @@
+#![feature(arbitrary_self_types)]
+#![allow(non_snake_case)]
+
+use std::pin::Pin;
+
+struct Struct { }
+
+type Alias = Struct;
+
+impl Struct {
+    // Test using `&mut Struct` explicitly:
+
+    fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+
+    fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+
+    fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+
+    fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+
+    fn box_pin_ref_Struct(self: Box<Pin<&mut Struct>>, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+}
+
+fn main() { }
diff --git a/src/test/ui/self/elision/ref-mut-struct.stderr b/src/test/ui/self/elision/ref-mut-struct.stderr
new file mode 100644
index 0000000000000..88dfb17892a2f
--- /dev/null
+++ b/src/test/ui/self/elision/ref-mut-struct.stderr
@@ -0,0 +1,52 @@
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-mut-struct.rs:14:9
+   |
+LL |     fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 {
+   |                                         ----     ----
+   |                                         |
+   |                                         this parameter and the return type are declared with different lifetimes...
+LL |         f
+   |         ^ ...but data from `f` is returned here
+
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-mut-struct.rs:18:9
+   |
+LL |     fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 {
+   |                                                  ----     ----
+   |                                                  |
+   |                                                  this parameter and the return type are declared with different lifetimes...
+LL |         f
+   |         ^ ...but data from `f` is returned here
+
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-mut-struct.rs:22:9
+   |
+LL |     fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 {
+   |                                                  ----     ----
+   |                                                  |
+   |                                                  this parameter and the return type are declared with different lifetimes...
+LL |         f
+   |         ^ ...but data from `f` is returned here
+
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-mut-struct.rs:26:9
+   |
+LL |     fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u32 {
+   |                                                           ----     ----
+   |                                                           |
+   |                                                           this parameter and the return type are declared with different lifetimes...
+LL |         f
+   |         ^ ...but data from `f` is returned here
+
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-mut-struct.rs:30:9
+   |
+LL |     fn box_pin_ref_Struct(self: Box<Pin<&mut Struct>>, f: &u32) -> &u32 {
+   |                                                           ----     ----
+   |                                                           |
+   |                                                           this parameter and the return type are declared with different lifetimes...
+LL |         f
+   |         ^ ...but data from `f` is returned here
+
+error: aborting due to 5 previous errors
+
diff --git a/src/test/ui/self/elision/ref-self.rs b/src/test/ui/self/elision/ref-self.rs
new file mode 100644
index 0000000000000..af10e10d3111c
--- /dev/null
+++ b/src/test/ui/self/elision/ref-self.rs
@@ -0,0 +1,40 @@
+#![feature(arbitrary_self_types)]
+#![allow(non_snake_case)]
+
+use std::pin::Pin;
+
+struct Struct { }
+
+type Alias = Struct;
+
+impl Struct {
+    // Test using `&self` sugar:
+
+    fn ref_self(&self, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+
+    // Test using `&Self` explicitly:
+
+    fn ref_Self(self: &Self, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+
+    fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+
+    fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+
+    fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+
+    fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+}
+
+fn main() { }
diff --git a/src/test/ui/self/elision/ref-self.stderr b/src/test/ui/self/elision/ref-self.stderr
new file mode 100644
index 0000000000000..10131cc5935a5
--- /dev/null
+++ b/src/test/ui/self/elision/ref-self.stderr
@@ -0,0 +1,62 @@
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-self.rs:14:9
+   |
+LL |     fn ref_self(&self, f: &u32) -> &u32 {
+   |                           ----     ----
+   |                           |
+   |                           this parameter and the return type are declared with different lifetimes...
+LL |         f
+   |         ^ ...but data from `f` is returned here
+
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-self.rs:20:9
+   |
+LL |     fn ref_Self(self: &Self, f: &u32) -> &u32 {
+   |                                 ----     ----
+   |                                 |
+   |                                 this parameter and the return type are declared with different lifetimes...
+LL |         f
+   |         ^ ...but data from `f` is returned here
+
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-self.rs:24:9
+   |
+LL |     fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
+   |                                          ----     ----
+   |                                          |
+   |                                          this parameter and the return type are declared with different lifetimes...
+LL |         f
+   |         ^ ...but data from `f` is returned here
+
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-self.rs:28:9
+   |
+LL |     fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
+   |                                          ----     ----
+   |                                          |
+   |                                          this parameter and the return type are declared with different lifetimes...
+LL |         f
+   |         ^ ...but data from `f` is returned here
+
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-self.rs:32:9
+   |
+LL |     fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
+   |                                                   ----     ----
+   |                                                   |
+   |                                                   this parameter and the return type are declared with different lifetimes...
+LL |         f
+   |         ^ ...but data from `f` is returned here
+
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-self.rs:36:9
+   |
+LL |     fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
+   |                                                   ----     ----
+   |                                                   |
+   |                                                   this parameter and the return type are declared with different lifetimes...
+LL |         f
+   |         ^ ...but data from `f` is returned here
+
+error: aborting due to 6 previous errors
+
diff --git a/src/test/ui/self/elision/ref-struct.rs b/src/test/ui/self/elision/ref-struct.rs
new file mode 100644
index 0000000000000..28afe17c23467
--- /dev/null
+++ b/src/test/ui/self/elision/ref-struct.rs
@@ -0,0 +1,34 @@
+#![feature(arbitrary_self_types)]
+#![allow(non_snake_case)]
+
+use std::pin::Pin;
+
+struct Struct { }
+
+type Alias = Struct;
+
+impl Struct {
+    // Test using `&Struct` explicitly:
+
+    fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+
+    fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+
+    fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+
+    fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+
+    fn box_pin_Struct(self: Box<Pin<&Struct>>, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+}
+
+fn main() { }
diff --git a/src/test/ui/self/elision/ref-struct.stderr b/src/test/ui/self/elision/ref-struct.stderr
new file mode 100644
index 0000000000000..8a17ab13d5759
--- /dev/null
+++ b/src/test/ui/self/elision/ref-struct.stderr
@@ -0,0 +1,52 @@
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-struct.rs:14:9
+   |
+LL |     fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
+   |                                     ----     ----
+   |                                     |
+   |                                     this parameter and the return type are declared with different lifetimes...
+LL |         f
+   |         ^ ...but data from `f` is returned here
+
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-struct.rs:18:9
+   |
+LL |     fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 {
+   |                                              ----     ----
+   |                                              |
+   |                                              this parameter and the return type are declared with different lifetimes...
+LL |         f
+   |         ^ ...but data from `f` is returned here
+
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-struct.rs:22:9
+   |
+LL |     fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 {
+   |                                              ----     ----
+   |                                              |
+   |                                              this parameter and the return type are declared with different lifetimes...
+LL |         f
+   |         ^ ...but data from `f` is returned here
+
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-struct.rs:26:9
+   |
+LL |     fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 {
+   |                                                       ----     ----
+   |                                                       |
+   |                                                       this parameter and the return type are declared with different lifetimes...
+LL |         f
+   |         ^ ...but data from `f` is returned here
+
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-struct.rs:30:9
+   |
+LL |     fn box_pin_Struct(self: Box<Pin<&Struct>>, f: &u32) -> &u32 {
+   |                                                   ----     ----
+   |                                                   |
+   |                                                   this parameter and the return type are declared with different lifetimes...
+LL |         f
+   |         ^ ...but data from `f` is returned here
+
+error: aborting due to 5 previous errors
+
diff --git a/src/test/ui/self/elision/self.rs b/src/test/ui/self/elision/self.rs
new file mode 100644
index 0000000000000..cfd1e79e975c3
--- /dev/null
+++ b/src/test/ui/self/elision/self.rs
@@ -0,0 +1,36 @@
+// run-pass
+
+#![feature(arbitrary_self_types)]
+#![allow(non_snake_case)]
+
+use std::rc::Rc;
+
+struct Struct { }
+
+impl Struct {
+    fn take_self(self, f: &u32) -> &u32 {
+        f
+    }
+
+    fn take_Self(self: Self, f: &u32) -> &u32 {
+        f
+    }
+
+    fn take_Box_Self(self: Box<Self>, f: &u32) -> &u32 {
+        f
+    }
+
+    fn take_Box_Box_Self(self: Box<Box<Self>>, f: &u32) -> &u32 {
+        f
+    }
+
+    fn take_Rc_Self(self: Rc<Self>, f: &u32) -> &u32 {
+        f
+    }
+
+    fn take_Box_Rc_Self(self: Box<Rc<Self>>, f: &u32) -> &u32 {
+        f
+    }
+}
+
+fn main() { }
diff --git a/src/test/ui/self/elision/struct.rs b/src/test/ui/self/elision/struct.rs
new file mode 100644
index 0000000000000..efdeb121fed8a
--- /dev/null
+++ b/src/test/ui/self/elision/struct.rs
@@ -0,0 +1,34 @@
+// run-pass
+
+#![feature(arbitrary_self_types)]
+#![allow(non_snake_case)]
+
+use std::rc::Rc;
+
+struct Struct { }
+
+impl Struct {
+    // Test using `&mut Struct` explicitly:
+
+    fn ref_Struct(self: Struct, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+
+    fn box_Struct(self: Box<Struct>, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+
+    fn rc_Struct(self: Rc<Struct>, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+
+    fn box_box_Struct(self: Box<Box<Struct>>, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+
+    fn box_rc_Struct(self: Box<Rc<Struct>>, f: &u32) -> &u32 {
+        f //~ ERROR lifetime mismatch
+    }
+}
+
+fn main() { }

From 3f55d29221b2f41ad004faeabfcacb23aed83857 Mon Sep 17 00:00:00 2001
From: Taiki Endo <te316e89@gmail.com>
Date: Mon, 15 Jul 2019 17:59:22 +0900
Subject: [PATCH 13/20] Update src/test/ui/self/elision/README.md

Co-Authored-By: Mazdak Farrokhzad <twingoow@gmail.com>
---
 src/test/ui/self/elision/README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/test/ui/self/elision/README.md b/src/test/ui/self/elision/README.md
index de29a9d5e53bc..9e874e2753e93 100644
--- a/src/test/ui/self/elision/README.md
+++ b/src/test/ui/self/elision/README.md
@@ -1,4 +1,4 @@
-Test cases intended to to document behavior and tryto exhaustively
+Test cases intended to to document behavior and try to exhaustively
 explore the combinations. 
 
 ## Confidence

From 857a8dd952ab1391d1a06282606f227734448a81 Mon Sep 17 00:00:00 2001
From: Taiki Endo <te316e89@gmail.com>
Date: Mon, 15 Jul 2019 18:25:09 +0900
Subject: [PATCH 14/20] Add main functions and check-pass annotations

---
 src/test/ui/self/arbitrary_self_types_pin_lifetime.rs | 2 +-
 src/test/ui/self/elision/alias.rs                     | 4 ++++
 src/test/ui/self/elision/alias.stderr                 | 7 -------
 src/test/ui/self/elision/lt-alias.rs                  | 2 +-
 src/test/ui/self/elision/lt-self.rs                   | 2 +-
 src/test/ui/self/elision/lt-struct.rs                 | 2 +-
 src/test/ui/self/elision/ref-alias.rs                 | 2 +-
 src/test/ui/self/elision/ref-mut-alias.rs             | 4 ++++
 src/test/ui/self/elision/ref-mut-alias.stderr         | 7 -------
 src/test/ui/self/elision/self.rs                      | 2 +-
 src/test/ui/self/elision/struct.rs                    | 2 +-
 src/test/ui/self/self_lifetime.rs                     | 2 +-
 12 files changed, 16 insertions(+), 22 deletions(-)
 delete mode 100644 src/test/ui/self/elision/alias.stderr
 delete mode 100644 src/test/ui/self/elision/ref-mut-alias.stderr

diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime.rs b/src/test/ui/self/arbitrary_self_types_pin_lifetime.rs
index ba574eeb4609b..3002013881249 100644
--- a/src/test/ui/self/arbitrary_self_types_pin_lifetime.rs
+++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime.rs
@@ -1,4 +1,4 @@
-// compile-pass
+// check-pass
 
 use std::pin::Pin;
 use std::task::{Context, Poll};
diff --git a/src/test/ui/self/elision/alias.rs b/src/test/ui/self/elision/alias.rs
index 6f113ec1a4bc9..b5aacfaeec427 100644
--- a/src/test/ui/self/elision/alias.rs
+++ b/src/test/ui/self/elision/alias.rs
@@ -1,3 +1,5 @@
+// check-pass
+
 #![feature(arbitrary_self_types)]
 #![allow(non_snake_case)]
 
@@ -30,3 +32,5 @@ impl Struct {
         f
     }
 }
+
+fn main() { }
diff --git a/src/test/ui/self/elision/alias.stderr b/src/test/ui/self/elision/alias.stderr
deleted file mode 100644
index a8f2a125b5eb7..0000000000000
--- a/src/test/ui/self/elision/alias.stderr
+++ /dev/null
@@ -1,7 +0,0 @@
-error[E0601]: `main` function not found in crate `alias`
-   |
-   = note: consider adding a `main` function to `$DIR/alias.rs`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0601`.
diff --git a/src/test/ui/self/elision/lt-alias.rs b/src/test/ui/self/elision/lt-alias.rs
index 044682789007d..df2300deda25f 100644
--- a/src/test/ui/self/elision/lt-alias.rs
+++ b/src/test/ui/self/elision/lt-alias.rs
@@ -1,4 +1,4 @@
-// run-pass
+// check-pass
 
 #![feature(arbitrary_self_types)]
 #![allow(non_snake_case)]
diff --git a/src/test/ui/self/elision/lt-self.rs b/src/test/ui/self/elision/lt-self.rs
index c33df08e0ee48..9b0ee5e42a51a 100644
--- a/src/test/ui/self/elision/lt-self.rs
+++ b/src/test/ui/self/elision/lt-self.rs
@@ -1,4 +1,4 @@
-// run-pass
+// check-pass
 
 #![feature(arbitrary_self_types)]
 #![allow(non_snake_case)]
diff --git a/src/test/ui/self/elision/lt-struct.rs b/src/test/ui/self/elision/lt-struct.rs
index 79ffc8fd6f4bd..e41dfbbe0bf0d 100644
--- a/src/test/ui/self/elision/lt-struct.rs
+++ b/src/test/ui/self/elision/lt-struct.rs
@@ -1,4 +1,4 @@
-// run-pass
+// check-pass
 
 #![feature(arbitrary_self_types)]
 #![allow(non_snake_case)]
diff --git a/src/test/ui/self/elision/ref-alias.rs b/src/test/ui/self/elision/ref-alias.rs
index 23bfe8fb029f6..d83ac612235e3 100644
--- a/src/test/ui/self/elision/ref-alias.rs
+++ b/src/test/ui/self/elision/ref-alias.rs
@@ -1,4 +1,4 @@
-// run-pass
+// check-pass
 
 #![feature(arbitrary_self_types)]
 #![allow(non_snake_case)]
diff --git a/src/test/ui/self/elision/ref-mut-alias.rs b/src/test/ui/self/elision/ref-mut-alias.rs
index abb412965768d..395816f8f5d80 100644
--- a/src/test/ui/self/elision/ref-mut-alias.rs
+++ b/src/test/ui/self/elision/ref-mut-alias.rs
@@ -1,3 +1,5 @@
+// check-pass
+
 #![feature(arbitrary_self_types)]
 #![allow(non_snake_case)]
 
@@ -30,3 +32,5 @@ impl Struct {
         f
     }
 }
+
+fn main() { }
diff --git a/src/test/ui/self/elision/ref-mut-alias.stderr b/src/test/ui/self/elision/ref-mut-alias.stderr
deleted file mode 100644
index cf202ccaa5d88..0000000000000
--- a/src/test/ui/self/elision/ref-mut-alias.stderr
+++ /dev/null
@@ -1,7 +0,0 @@
-error[E0601]: `main` function not found in crate `ref_mut_alias`
-   |
-   = note: consider adding a `main` function to `$DIR/ref-mut-alias.rs`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0601`.
diff --git a/src/test/ui/self/elision/self.rs b/src/test/ui/self/elision/self.rs
index cfd1e79e975c3..dbcef71ba14fc 100644
--- a/src/test/ui/self/elision/self.rs
+++ b/src/test/ui/self/elision/self.rs
@@ -1,4 +1,4 @@
-// run-pass
+// check-pass
 
 #![feature(arbitrary_self_types)]
 #![allow(non_snake_case)]
diff --git a/src/test/ui/self/elision/struct.rs b/src/test/ui/self/elision/struct.rs
index efdeb121fed8a..f6e7c0fb129d5 100644
--- a/src/test/ui/self/elision/struct.rs
+++ b/src/test/ui/self/elision/struct.rs
@@ -1,4 +1,4 @@
-// run-pass
+// check-pass
 
 #![feature(arbitrary_self_types)]
 #![allow(non_snake_case)]
diff --git a/src/test/ui/self/self_lifetime.rs b/src/test/ui/self/self_lifetime.rs
index a3163ade0404f..edb47fd4d327c 100644
--- a/src/test/ui/self/self_lifetime.rs
+++ b/src/test/ui/self/self_lifetime.rs
@@ -1,4 +1,4 @@
-// compile-pass
+// check-pass
 
 struct Foo<'a>(&'a ());
 impl<'a> Foo<'a> {

From dc04a4e4d2bbda6ad47ed17434744196137a8f85 Mon Sep 17 00:00:00 2001
From: Taiki Endo <te316e89@gmail.com>
Date: Tue, 16 Jul 2019 00:48:28 +0900
Subject: [PATCH 15/20] Minor clean up

---
 src/test/ui/self/elision/README.md             |  9 ++++-----
 src/test/ui/self/elision/ref-mut-self.rs       |  2 --
 src/test/ui/self/elision/ref-mut-self.stderr   | 12 ++++++------
 src/test/ui/self/elision/ref-mut-struct.rs     |  2 --
 src/test/ui/self/elision/ref-mut-struct.stderr | 10 +++++-----
 src/test/ui/self/elision/ref-self.rs           |  2 --
 src/test/ui/self/elision/ref-struct.rs         |  2 --
 src/test/ui/self/elision/ref-struct.stderr     | 10 +++++-----
 src/test/ui/self/elision/struct.rs             | 12 +++++-------
 src/test/ui/self/self_lifetime.rs              |  2 ++
 10 files changed, 27 insertions(+), 36 deletions(-)

diff --git a/src/test/ui/self/elision/README.md b/src/test/ui/self/elision/README.md
index 9e874e2753e93..793eb16b0377c 100644
--- a/src/test/ui/self/elision/README.md
+++ b/src/test/ui/self/elision/README.md
@@ -1,5 +1,5 @@
 Test cases intended to to document behavior and try to exhaustively
-explore the combinations. 
+explore the combinations.
 
 ## Confidence
 
@@ -23,11 +23,11 @@ in the "confidence" field in the following table. Values:
 | `struct.rs` | `Struct` | `Struct` | ignore `self` parameter | 100% |
 | `alias.rs` | `Struct` | `Alias` | ignore `self` parameter | 100% |
 | `ref-self.rs` | `Struct` | `&Self` | take lifetime from `&Self` | 100% |
-| `ref-mut-self.rs` | `Struct` | `&mut Self` | take lifetime from `&Self` | 100% |
+| `ref-mut-self.rs` | `Struct` | `&mut Self` | take lifetime from `&mut Self` | 100% |
 | `ref-struct.rs` | `Struct` | `&Struct` | take lifetime from `&Self` | 50% |
-| `ref-mut-struct.rs` | `Struct` | `&Struct` | take lifetime from `&Self` | 50% |
+| `ref-mut-struct.rs` | `Struct` | `&mut Struct` | take lifetime from `&mut Self` | 50% |
 | `ref-alias.rs` | `Struct` | `&Alias` | ignore `Alias` | 0% |
-| `ref-mut-alias.rs` | `Struct` | `&Alias` | ignore `Alias` | 0% |
+| `ref-mut-alias.rs` | `Struct` | `&mut Alias` | ignore `Alias` | 0% |
 | `lt-self.rs` | `Struct<'a>` | `Self` | ignore `Self` (and hence `'a`) | 25% |
 | `lt-struct.rs` | `Struct<'a>` | `Self` | ignore `Self` (and hence `'a`) | 0% |
 | `lt-alias.rs`   | `Alias<'a>` | `Self` | ignore `Self` (and hence `'a`) | 0% |
@@ -42,4 +42,3 @@ In each case, we test the following patterns:
 - `self: Box<Pin<XXX>>`
 
 In the non-reference cases, `Pin` causes errors so we substitute `Rc`.
-
diff --git a/src/test/ui/self/elision/ref-mut-self.rs b/src/test/ui/self/elision/ref-mut-self.rs
index 6705ca9e30598..a7ea47bb7f6de 100644
--- a/src/test/ui/self/elision/ref-mut-self.rs
+++ b/src/test/ui/self/elision/ref-mut-self.rs
@@ -5,8 +5,6 @@ use std::pin::Pin;
 
 struct Struct { }
 
-type Alias = Struct;
-
 impl Struct {
     // Test using `&mut self` sugar:
 
diff --git a/src/test/ui/self/elision/ref-mut-self.stderr b/src/test/ui/self/elision/ref-mut-self.stderr
index 05dc5b774c832..37984cd72fbac 100644
--- a/src/test/ui/self/elision/ref-mut-self.stderr
+++ b/src/test/ui/self/elision/ref-mut-self.stderr
@@ -1,5 +1,5 @@
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-mut-self.rs:14:9
+  --> $DIR/ref-mut-self.rs:12:9
    |
 LL |     fn ref_self(&mut self, f: &u32) -> &u32 {
    |                               ----     ----
@@ -9,7 +9,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-mut-self.rs:20:9
+  --> $DIR/ref-mut-self.rs:18:9
    |
 LL |     fn ref_Self(self: &mut Self, f: &u32) -> &u32 {
    |                                     ----     ----
@@ -19,7 +19,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-mut-self.rs:24:9
+  --> $DIR/ref-mut-self.rs:22:9
    |
 LL |     fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 {
    |                                              ----     ----
@@ -29,7 +29,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-mut-self.rs:28:9
+  --> $DIR/ref-mut-self.rs:26:9
    |
 LL |     fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 {
    |                                              ----     ----
@@ -39,7 +39,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-mut-self.rs:32:9
+  --> $DIR/ref-mut-self.rs:30:9
    |
 LL |     fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 {
    |                                                       ----     ----
@@ -49,7 +49,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-mut-self.rs:36:9
+  --> $DIR/ref-mut-self.rs:34:9
    |
 LL |     fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 {
    |                                                       ----     ----
diff --git a/src/test/ui/self/elision/ref-mut-struct.rs b/src/test/ui/self/elision/ref-mut-struct.rs
index f063728e24751..795ddf8ac1354 100644
--- a/src/test/ui/self/elision/ref-mut-struct.rs
+++ b/src/test/ui/self/elision/ref-mut-struct.rs
@@ -5,8 +5,6 @@ use std::pin::Pin;
 
 struct Struct { }
 
-type Alias = Struct;
-
 impl Struct {
     // Test using `&mut Struct` explicitly:
 
diff --git a/src/test/ui/self/elision/ref-mut-struct.stderr b/src/test/ui/self/elision/ref-mut-struct.stderr
index 88dfb17892a2f..2a4826905b94a 100644
--- a/src/test/ui/self/elision/ref-mut-struct.stderr
+++ b/src/test/ui/self/elision/ref-mut-struct.stderr
@@ -1,5 +1,5 @@
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-mut-struct.rs:14:9
+  --> $DIR/ref-mut-struct.rs:12:9
    |
 LL |     fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 {
    |                                         ----     ----
@@ -9,7 +9,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-mut-struct.rs:18:9
+  --> $DIR/ref-mut-struct.rs:16:9
    |
 LL |     fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 {
    |                                                  ----     ----
@@ -19,7 +19,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-mut-struct.rs:22:9
+  --> $DIR/ref-mut-struct.rs:20:9
    |
 LL |     fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 {
    |                                                  ----     ----
@@ -29,7 +29,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-mut-struct.rs:26:9
+  --> $DIR/ref-mut-struct.rs:24:9
    |
 LL |     fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u32 {
    |                                                           ----     ----
@@ -39,7 +39,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-mut-struct.rs:30:9
+  --> $DIR/ref-mut-struct.rs:28:9
    |
 LL |     fn box_pin_ref_Struct(self: Box<Pin<&mut Struct>>, f: &u32) -> &u32 {
    |                                                           ----     ----
diff --git a/src/test/ui/self/elision/ref-self.rs b/src/test/ui/self/elision/ref-self.rs
index af10e10d3111c..9655c11f45e2c 100644
--- a/src/test/ui/self/elision/ref-self.rs
+++ b/src/test/ui/self/elision/ref-self.rs
@@ -5,8 +5,6 @@ use std::pin::Pin;
 
 struct Struct { }
 
-type Alias = Struct;
-
 impl Struct {
     // Test using `&self` sugar:
 
diff --git a/src/test/ui/self/elision/ref-struct.rs b/src/test/ui/self/elision/ref-struct.rs
index 28afe17c23467..342d6d2b36357 100644
--- a/src/test/ui/self/elision/ref-struct.rs
+++ b/src/test/ui/self/elision/ref-struct.rs
@@ -5,8 +5,6 @@ use std::pin::Pin;
 
 struct Struct { }
 
-type Alias = Struct;
-
 impl Struct {
     // Test using `&Struct` explicitly:
 
diff --git a/src/test/ui/self/elision/ref-struct.stderr b/src/test/ui/self/elision/ref-struct.stderr
index 8a17ab13d5759..186e651c143bf 100644
--- a/src/test/ui/self/elision/ref-struct.stderr
+++ b/src/test/ui/self/elision/ref-struct.stderr
@@ -1,5 +1,5 @@
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-struct.rs:14:9
+  --> $DIR/ref-struct.rs:12:9
    |
 LL |     fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
    |                                     ----     ----
@@ -9,7 +9,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-struct.rs:18:9
+  --> $DIR/ref-struct.rs:16:9
    |
 LL |     fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 {
    |                                              ----     ----
@@ -19,7 +19,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-struct.rs:22:9
+  --> $DIR/ref-struct.rs:20:9
    |
 LL |     fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 {
    |                                              ----     ----
@@ -29,7 +29,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-struct.rs:26:9
+  --> $DIR/ref-struct.rs:24:9
    |
 LL |     fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 {
    |                                                       ----     ----
@@ -39,7 +39,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-struct.rs:30:9
+  --> $DIR/ref-struct.rs:28:9
    |
 LL |     fn box_pin_Struct(self: Box<Pin<&Struct>>, f: &u32) -> &u32 {
    |                                                   ----     ----
diff --git a/src/test/ui/self/elision/struct.rs b/src/test/ui/self/elision/struct.rs
index f6e7c0fb129d5..227e993bd3c61 100644
--- a/src/test/ui/self/elision/struct.rs
+++ b/src/test/ui/self/elision/struct.rs
@@ -8,26 +8,24 @@ use std::rc::Rc;
 struct Struct { }
 
 impl Struct {
-    // Test using `&mut Struct` explicitly:
-
     fn ref_Struct(self: Struct, f: &u32) -> &u32 {
-        f //~ ERROR lifetime mismatch
+        f
     }
 
     fn box_Struct(self: Box<Struct>, f: &u32) -> &u32 {
-        f //~ ERROR lifetime mismatch
+        f
     }
 
     fn rc_Struct(self: Rc<Struct>, f: &u32) -> &u32 {
-        f //~ ERROR lifetime mismatch
+        f
     }
 
     fn box_box_Struct(self: Box<Box<Struct>>, f: &u32) -> &u32 {
-        f //~ ERROR lifetime mismatch
+        f
     }
 
     fn box_rc_Struct(self: Box<Rc<Struct>>, f: &u32) -> &u32 {
-        f //~ ERROR lifetime mismatch
+        f
     }
 }
 
diff --git a/src/test/ui/self/self_lifetime.rs b/src/test/ui/self/self_lifetime.rs
index edb47fd4d327c..f04bd83ab6e4c 100644
--- a/src/test/ui/self/self_lifetime.rs
+++ b/src/test/ui/self/self_lifetime.rs
@@ -1,5 +1,7 @@
 // check-pass
 
+// https://github.com/rust-lang/rust/pull/60944#issuecomment-495346120
+
 struct Foo<'a>(&'a ());
 impl<'a> Foo<'a> {
     fn foo<'b>(self: &'b Foo<'a>) -> &() { self.0 }

From f916aa995a40e4b23712f5f176eef287b2fa09cd Mon Sep 17 00:00:00 2001
From: Taiki Endo <te316e89@gmail.com>
Date: Tue, 16 Jul 2019 01:09:25 +0900
Subject: [PATCH 16/20] Add test for multiple ref-self

---
 src/test/ui/self/elision/multiple-ref-self.rs | 43 +++++++++++++++++++
 src/test/ui/self/elision/ref-self.rs          | 13 ++++++
 src/test/ui/self/elision/ref-self.stderr      | 24 ++++++++---
 3 files changed, 73 insertions(+), 7 deletions(-)
 create mode 100644 src/test/ui/self/elision/multiple-ref-self.rs

diff --git a/src/test/ui/self/elision/multiple-ref-self.rs b/src/test/ui/self/elision/multiple-ref-self.rs
new file mode 100644
index 0000000000000..f39613d0c9007
--- /dev/null
+++ b/src/test/ui/self/elision/multiple-ref-self.rs
@@ -0,0 +1,43 @@
+// check-pass
+
+#![feature(arbitrary_self_types)]
+#![allow(non_snake_case)]
+
+use std::marker::PhantomData;
+use std::ops::Deref;
+use std::pin::Pin;
+
+struct Struct { }
+
+struct Wrap<T, P>(T, PhantomData<P>);
+
+impl<T, P> Deref for Wrap<T, P> {
+    type Target = T;
+    fn deref(&self) -> &T { &self.0 }
+}
+
+impl Struct {
+    // Test using multiple `&Self`:
+
+    fn wrap_ref_Self_ref_Self(self: Wrap<&Self, &Self>, f: &u8) -> &u8 {
+        f
+    }
+
+    fn box_wrap_ref_Self_ref_Self(self: Box<Wrap<&Self, &Self>>, f: &u32) -> &u32 {
+        f
+    }
+
+    fn pin_wrap_ref_Self_ref_Self(self: Pin<Wrap<&Self, &Self>>, f: &u32) -> &u32 {
+        f
+    }
+
+    fn box_box_wrap_ref_Self_ref_Self(self: Box<Box<Wrap<&Self, &Self>>>, f: &u32) -> &u32 {
+        f
+    }
+
+    fn box_pin_wrap_ref_Self_ref_Self(self: Box<Pin<Wrap<&Self, &Self>>>, f: &u32) -> &u32 {
+        f
+    }
+}
+
+fn main() { }
diff --git a/src/test/ui/self/elision/ref-self.rs b/src/test/ui/self/elision/ref-self.rs
index 9655c11f45e2c..e389d8518ada4 100644
--- a/src/test/ui/self/elision/ref-self.rs
+++ b/src/test/ui/self/elision/ref-self.rs
@@ -1,10 +1,19 @@
 #![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:
 
@@ -33,6 +42,10 @@ impl Struct {
     fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
         f //~ ERROR lifetime mismatch
     }
+
+    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.stderr b/src/test/ui/self/elision/ref-self.stderr
index 10131cc5935a5..611498f18da42 100644
--- a/src/test/ui/self/elision/ref-self.stderr
+++ b/src/test/ui/self/elision/ref-self.stderr
@@ -1,5 +1,5 @@
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-self.rs:14:9
+  --> $DIR/ref-self.rs:21:9
    |
 LL |     fn ref_self(&self, f: &u32) -> &u32 {
    |                           ----     ----
@@ -9,7 +9,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-self.rs:20:9
+  --> $DIR/ref-self.rs:27:9
    |
 LL |     fn ref_Self(self: &Self, f: &u32) -> &u32 {
    |                                 ----     ----
@@ -19,7 +19,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-self.rs:24:9
+  --> $DIR/ref-self.rs:31:9
    |
 LL |     fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
    |                                          ----     ----
@@ -29,7 +29,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-self.rs:28:9
+  --> $DIR/ref-self.rs:35:9
    |
 LL |     fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
    |                                          ----     ----
@@ -39,7 +39,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-self.rs:32:9
+  --> $DIR/ref-self.rs:39:9
    |
 LL |     fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
    |                                                   ----     ----
@@ -49,7 +49,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-self.rs:36:9
+  --> $DIR/ref-self.rs:43:9
    |
 LL |     fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
    |                                                   ----     ----
@@ -58,5 +58,15 @@ LL |     fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
 LL |         f
    |         ^ ...but data from `f` is returned here
 
-error: aborting due to 6 previous errors
+error[E0623]: lifetime mismatch
+  --> $DIR/ref-self.rs:47:9
+   |
+LL |     fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 {
+   |                                                       ---     ---
+   |                                                       |
+   |                                                       this parameter and the return type are declared with different lifetimes...
+LL |         f
+   |         ^ ...but data from `f` is returned here
+
+error: aborting due to 7 previous errors
 

From fdf1cc41616cc5bbbf12aa98a34c79efb999632d Mon Sep 17 00:00:00 2001
From: Taiki Endo <te316e89@gmail.com>
Date: Fri, 26 Jul 2019 15:20:04 +0900
Subject: [PATCH 17/20] Add tests for `self: (&)AssocType`

---
 src/test/ui/self/elision/assoc.rs     | 40 ++++++++++++++++++++++++
 src/test/ui/self/elision/lt-assoc.rs  | 44 +++++++++++++++++++++++++++
 src/test/ui/self/elision/ref-assoc.rs | 40 ++++++++++++++++++++++++
 3 files changed, 124 insertions(+)
 create mode 100644 src/test/ui/self/elision/assoc.rs
 create mode 100644 src/test/ui/self/elision/lt-assoc.rs
 create mode 100644 src/test/ui/self/elision/ref-assoc.rs

diff --git a/src/test/ui/self/elision/assoc.rs b/src/test/ui/self/elision/assoc.rs
new file mode 100644
index 0000000000000..163eb49383a87
--- /dev/null
+++ b/src/test/ui/self/elision/assoc.rs
@@ -0,0 +1,40 @@
+// check-pass
+
+#![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 {
+    fn assoc(self: <Struct as Trait>::AssocType, f: &u32) -> &u32 {
+        f
+    }
+
+    fn box_AssocType(self: Box<<Struct as Trait>::AssocType>, f: &u32) -> &u32 {
+        f
+    }
+
+    fn rc_AssocType(self: Rc<<Struct as Trait>::AssocType>, f: &u32) -> &u32 {
+        f
+    }
+
+    fn box_box_AssocType(self: Box<Box<<Struct as Trait>::AssocType>>, f: &u32) -> &u32 {
+        f
+    }
+
+    fn box_rc_AssocType(self: Box<Rc<<Struct as Trait>::AssocType>>, f: &u32) -> &u32 {
+        f
+    }
+}
+
+fn main() { }
diff --git a/src/test/ui/self/elision/lt-assoc.rs b/src/test/ui/self/elision/lt-assoc.rs
new file mode 100644
index 0000000000000..70573598fcb16
--- /dev/null
+++ b/src/test/ui/self/elision/lt-assoc.rs
@@ -0,0 +1,44 @@
+// check-pass
+
+#![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> {
+    fn take_self(self, f: &u32) -> &u32 {
+        f
+    }
+
+    fn take_AssocType(self: <Struct<'a> as Trait>::AssocType, f: &u32) -> &u32 {
+        f
+    }
+
+    fn take_Box_AssocType(self: Box<<Struct<'a> as Trait>::AssocType>, f: &u32) -> &u32 {
+        f
+    }
+
+    fn take_Box_Box_AssocType(self: Box<Box<<Struct<'a> as Trait>::AssocType>>, f: &u32) -> &u32 {
+        f
+    }
+
+    fn take_Rc_AssocType(self: Rc<<Struct<'a> as Trait>::AssocType>, f: &u32) -> &u32 {
+        f
+    }
+
+    fn take_Box_Rc_AssocType(self: Box<Rc<<Struct<'a> as Trait>::AssocType>>, f: &u32) -> &u32 {
+        f
+    }
+}
+
+fn main() { }
diff --git a/src/test/ui/self/elision/ref-assoc.rs b/src/test/ui/self/elision/ref-assoc.rs
new file mode 100644
index 0000000000000..f9354bc884710
--- /dev/null
+++ b/src/test/ui/self/elision/ref-assoc.rs
@@ -0,0 +1,40 @@
+// check-pass
+
+#![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 {
+    fn ref_AssocType(self: &<Struct as Trait>::AssocType, f: &u32) -> &u32 {
+        f
+    }
+
+    fn box_ref_AssocType(self: Box<&<Struct as Trait>::AssocType>, f: &u32) -> &u32 {
+        f
+    }
+
+    fn pin_ref_AssocType(self: Pin<&<Struct as Trait>::AssocType>, f: &u32) -> &u32 {
+        f
+    }
+
+    fn box_box_ref_AssocType(self: Box<Box<&<Struct as Trait>::AssocType>>, f: &u32) -> &u32 {
+        f
+    }
+
+    fn box_pin_ref_AssocType(self: Box<Pin<&<Struct as Trait>::AssocType>>, f: &u32) -> &u32 {
+        f
+    }
+}
+
+fn main() { }

From 62a1c115045ad887c73053c7e3b9ba9d13e86aa2 Mon Sep 17 00:00:00 2001
From: Taiki Endo <te316e89@gmail.com>
Date: Fri, 26 Jul 2019 15:41:00 +0900
Subject: [PATCH 18/20] Fix typo

---
 src/test/ui/self/elision/README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/test/ui/self/elision/README.md b/src/test/ui/self/elision/README.md
index 793eb16b0377c..7ace2e0c89039 100644
--- a/src/test/ui/self/elision/README.md
+++ b/src/test/ui/self/elision/README.md
@@ -1,4 +1,4 @@
-Test cases intended to to document behavior and try to exhaustively
+Test cases intended to document behavior and try to exhaustively
 explore the combinations.
 
 ## Confidence

From d27529f79c999b779f02a06e23a754e3c242a774 Mon Sep 17 00:00:00 2001
From: Taiki Endo <te316e89@gmail.com>
Date: Sat, 27 Jul 2019 12:35:05 +0900
Subject: [PATCH 19/20] arbitrary_self_types lifetime elision: --bless
 --compare-mode=nll

---
 ...f_types_pin_lifetime_impl_trait.nll.stderr | 14 ++++
 ...elf_types_pin_lifetime_mismatch.nll.stderr | 28 ++++++++
 .../ui/self/elision/lt-ref-self.nll.stderr    | 62 ++++++++++++++++
 .../ui/self/elision/ref-mut-self.nll.stderr   | 62 ++++++++++++++++
 .../ui/self/elision/ref-mut-struct.nll.stderr | 52 ++++++++++++++
 src/test/ui/self/elision/ref-self.nll.stderr  | 72 +++++++++++++++++++
 .../ui/self/elision/ref-struct.nll.stderr     | 52 ++++++++++++++
 7 files changed, 342 insertions(+)
 create mode 100644 src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.nll.stderr
 create mode 100644 src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.nll.stderr
 create mode 100644 src/test/ui/self/elision/lt-ref-self.nll.stderr
 create mode 100644 src/test/ui/self/elision/ref-mut-self.nll.stderr
 create mode 100644 src/test/ui/self/elision/ref-mut-struct.nll.stderr
 create mode 100644 src/test/ui/self/elision/ref-self.nll.stderr
 create mode 100644 src/test/ui/self/elision/ref-struct.nll.stderr

diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.nll.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.nll.stderr
new file mode 100644
index 0000000000000..dcfc9ba511d74
--- /dev/null
+++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.nll.stderr
@@ -0,0 +1,14 @@
+error: lifetime may not live long enough
+  --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait.rs:8:31
+   |
+LL |     fn f(self: Pin<&Self>) -> impl Clone { self }
+   |                    -          ^^^^^^^^^^ opaque type requires that `'1` must outlive `'static`
+   |                    |
+   |                    let's call the lifetime of this reference `'1`
+help: to allow this `impl Trait` to capture borrowed data with lifetime `'1`, add `'_` as a constraint
+   |
+LL |     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.nll.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.nll.stderr
new file mode 100644
index 0000000000000..8a0f1a804ad82
--- /dev/null
+++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.nll.stderr
@@ -0,0 +1,28 @@
+error: lifetime may not live long enough
+  --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:8:46
+   |
+LL |     fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f }
+   |                    -         -               ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |                    |         |
+   |                    |         let's call the lifetime of this reference `'1`
+   |                    let's call the lifetime of this reference `'2`
+
+error: lifetime may not live long enough
+  --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:10:69
+   |
+LL |     fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) }
+   |                    -          -                                     ^^^^^^^^^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |                    |          |
+   |                    |          let's call the lifetime of this reference `'1`
+   |                    let's call the lifetime of this reference `'2`
+
+error: lifetime may not live long enough
+  --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:15:58
+   |
+LL |     fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg }
+   |            --  ---- has type `std::pin::Pin<&'1 Foo>`    ^^^ function was supposed to return data with lifetime `'1` but it is returning data with lifetime `'a`
+   |            |
+   |            lifetime `'a` defined here
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/self/elision/lt-ref-self.nll.stderr b/src/test/ui/self/elision/lt-ref-self.nll.stderr
new file mode 100644
index 0000000000000..e97a01e746d4b
--- /dev/null
+++ b/src/test/ui/self/elision/lt-ref-self.nll.stderr
@@ -0,0 +1,62 @@
+error: lifetime may not live long enough
+  --> $DIR/lt-ref-self.rs:12:9
+   |
+LL |     fn ref_self(&self, f: &u32) -> &u32 {
+   |                 -         - let's call the lifetime of this reference `'1`
+   |                 |
+   |                 let's call the lifetime of this reference `'2`
+LL |         f
+   |         ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+
+error: lifetime may not live long enough
+  --> $DIR/lt-ref-self.rs:18:9
+   |
+LL |     fn ref_Self(self: &Self, f: &u32) -> &u32 {
+   |                       -         - let's call the lifetime of this reference `'1`
+   |                       |
+   |                       let's call the lifetime of this reference `'2`
+LL |         f
+   |         ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+
+error: lifetime may not live long enough
+  --> $DIR/lt-ref-self.rs:22:9
+   |
+LL |     fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
+   |                               -          - let's call the lifetime of this reference `'1`
+   |                               |
+   |                               let's call the lifetime of this reference `'2`
+LL |         f
+   |         ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+
+error: lifetime may not live long enough
+  --> $DIR/lt-ref-self.rs:26:9
+   |
+LL |     fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
+   |                               -          - let's call the lifetime of this reference `'1`
+   |                               |
+   |                               let's call the lifetime of this reference `'2`
+LL |         f
+   |         ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+
+error: lifetime may not live long enough
+  --> $DIR/lt-ref-self.rs:30:9
+   |
+LL |     fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
+   |                                       -           - let's call the lifetime of this reference `'1`
+   |                                       |
+   |                                       let's call the lifetime of this reference `'2`
+LL |         f
+   |         ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+
+error: lifetime may not live long enough
+  --> $DIR/lt-ref-self.rs:34:9
+   |
+LL |     fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
+   |                                   -           - let's call the lifetime of this reference `'1`
+   |                                   |
+   |                                   let's call the lifetime of this reference `'2`
+LL |         f
+   |         ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+
+error: aborting due to 6 previous errors
+
diff --git a/src/test/ui/self/elision/ref-mut-self.nll.stderr b/src/test/ui/self/elision/ref-mut-self.nll.stderr
new file mode 100644
index 0000000000000..3a8ae3fdcba8c
--- /dev/null
+++ b/src/test/ui/self/elision/ref-mut-self.nll.stderr
@@ -0,0 +1,62 @@
+error: lifetime may not live long enough
+  --> $DIR/ref-mut-self.rs:12:9
+   |
+LL |     fn ref_self(&mut self, f: &u32) -> &u32 {
+   |                 -             - let's call the lifetime of this reference `'1`
+   |                 |
+   |                 let's call the lifetime of this reference `'2`
+LL |         f
+   |         ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+
+error: lifetime may not live long enough
+  --> $DIR/ref-mut-self.rs:18:9
+   |
+LL |     fn ref_Self(self: &mut Self, f: &u32) -> &u32 {
+   |                       -             - let's call the lifetime of this reference `'1`
+   |                       |
+   |                       let's call the lifetime of this reference `'2`
+LL |         f
+   |         ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+
+error: lifetime may not live long enough
+  --> $DIR/ref-mut-self.rs:22:9
+   |
+LL |     fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 {
+   |                               -              - let's call the lifetime of this reference `'1`
+   |                               |
+   |                               let's call the lifetime of this reference `'2`
+LL |         f
+   |         ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+
+error: lifetime may not live long enough
+  --> $DIR/ref-mut-self.rs:26:9
+   |
+LL |     fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 {
+   |                               -              - let's call the lifetime of this reference `'1`
+   |                               |
+   |                               let's call the lifetime of this reference `'2`
+LL |         f
+   |         ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+
+error: lifetime may not live long enough
+  --> $DIR/ref-mut-self.rs:30:9
+   |
+LL |     fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 {
+   |                                       -               - let's call the lifetime of this reference `'1`
+   |                                       |
+   |                                       let's call the lifetime of this reference `'2`
+LL |         f
+   |         ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+
+error: lifetime may not live long enough
+  --> $DIR/ref-mut-self.rs:34:9
+   |
+LL |     fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 {
+   |                                       -               - let's call the lifetime of this reference `'1`
+   |                                       |
+   |                                       let's call the lifetime of this reference `'2`
+LL |         f
+   |         ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+
+error: aborting due to 6 previous errors
+
diff --git a/src/test/ui/self/elision/ref-mut-struct.nll.stderr b/src/test/ui/self/elision/ref-mut-struct.nll.stderr
new file mode 100644
index 0000000000000..66152ba40a5f5
--- /dev/null
+++ b/src/test/ui/self/elision/ref-mut-struct.nll.stderr
@@ -0,0 +1,52 @@
+error: lifetime may not live long enough
+  --> $DIR/ref-mut-struct.rs:12:9
+   |
+LL |     fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 {
+   |                         -               - let's call the lifetime of this reference `'1`
+   |                         |
+   |                         let's call the lifetime of this reference `'2`
+LL |         f
+   |         ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+
+error: lifetime may not live long enough
+  --> $DIR/ref-mut-struct.rs:16:9
+   |
+LL |     fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 {
+   |                                 -                - let's call the lifetime of this reference `'1`
+   |                                 |
+   |                                 let's call the lifetime of this reference `'2`
+LL |         f
+   |         ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+
+error: lifetime may not live long enough
+  --> $DIR/ref-mut-struct.rs:20:9
+   |
+LL |     fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 {
+   |                                 -                - let's call the lifetime of this reference `'1`
+   |                                 |
+   |                                 let's call the lifetime of this reference `'2`
+LL |         f
+   |         ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+
+error: lifetime may not live long enough
+  --> $DIR/ref-mut-struct.rs:24:9
+   |
+LL |     fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u32 {
+   |                                         -                 - let's call the lifetime of this reference `'1`
+   |                                         |
+   |                                         let's call the lifetime of this reference `'2`
+LL |         f
+   |         ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+
+error: lifetime may not live long enough
+  --> $DIR/ref-mut-struct.rs:28:9
+   |
+LL |     fn box_pin_ref_Struct(self: Box<Pin<&mut Struct>>, f: &u32) -> &u32 {
+   |                                         -                 - let's call the lifetime of this reference `'1`
+   |                                         |
+   |                                         let's call the lifetime of this reference `'2`
+LL |         f
+   |         ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+
+error: aborting due to 5 previous errors
+
diff --git a/src/test/ui/self/elision/ref-self.nll.stderr b/src/test/ui/self/elision/ref-self.nll.stderr
new file mode 100644
index 0000000000000..20045be0527a4
--- /dev/null
+++ b/src/test/ui/self/elision/ref-self.nll.stderr
@@ -0,0 +1,72 @@
+error: lifetime may not live long enough
+  --> $DIR/ref-self.rs:21:9
+   |
+LL |     fn ref_self(&self, f: &u32) -> &u32 {
+   |                 -         - let's call the lifetime of this reference `'1`
+   |                 |
+   |                 let's call the lifetime of this reference `'2`
+LL |         f
+   |         ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+
+error: lifetime may not live long enough
+  --> $DIR/ref-self.rs:27:9
+   |
+LL |     fn ref_Self(self: &Self, f: &u32) -> &u32 {
+   |                       -         - let's call the lifetime of this reference `'1`
+   |                       |
+   |                       let's call the lifetime of this reference `'2`
+LL |         f
+   |         ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+
+error: lifetime may not live long enough
+  --> $DIR/ref-self.rs:31:9
+   |
+LL |     fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
+   |                               -          - let's call the lifetime of this reference `'1`
+   |                               |
+   |                               let's call the lifetime of this reference `'2`
+LL |         f
+   |         ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+
+error: lifetime may not live long enough
+  --> $DIR/ref-self.rs:35:9
+   |
+LL |     fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
+   |                               -          - let's call the lifetime of this reference `'1`
+   |                               |
+   |                               let's call the lifetime of this reference `'2`
+LL |         f
+   |         ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+
+error: lifetime may not live long enough
+  --> $DIR/ref-self.rs:39:9
+   |
+LL |     fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
+   |                                       -           - let's call the lifetime of this reference `'1`
+   |                                       |
+   |                                       let's call the lifetime of this reference `'2`
+LL |         f
+   |         ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+
+error: lifetime may not live long enough
+  --> $DIR/ref-self.rs:43:9
+   |
+LL |     fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
+   |                                       -           - let's call the lifetime of this reference `'1`
+   |                                       |
+   |                                       let's call the lifetime of this reference `'2`
+LL |         f
+   |         ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+
+error: lifetime may not live long enough
+  --> $DIR/ref-self.rs:47:9
+   |
+LL |     fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 {
+   |                                      -                - let's call the lifetime of this reference `'1`
+   |                                      |
+   |                                      let's call the lifetime of this reference `'2`
+LL |         f
+   |         ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+
+error: aborting due to 7 previous errors
+
diff --git a/src/test/ui/self/elision/ref-struct.nll.stderr b/src/test/ui/self/elision/ref-struct.nll.stderr
new file mode 100644
index 0000000000000..a258bc9f74390
--- /dev/null
+++ b/src/test/ui/self/elision/ref-struct.nll.stderr
@@ -0,0 +1,52 @@
+error: lifetime may not live long enough
+  --> $DIR/ref-struct.rs:12:9
+   |
+LL |     fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
+   |                         -           - let's call the lifetime of this reference `'1`
+   |                         |
+   |                         let's call the lifetime of this reference `'2`
+LL |         f
+   |         ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+
+error: lifetime may not live long enough
+  --> $DIR/ref-struct.rs:16:9
+   |
+LL |     fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 {
+   |                                 -            - let's call the lifetime of this reference `'1`
+   |                                 |
+   |                                 let's call the lifetime of this reference `'2`
+LL |         f
+   |         ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+
+error: lifetime may not live long enough
+  --> $DIR/ref-struct.rs:20:9
+   |
+LL |     fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 {
+   |                                 -            - let's call the lifetime of this reference `'1`
+   |                                 |
+   |                                 let's call the lifetime of this reference `'2`
+LL |         f
+   |         ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+
+error: lifetime may not live long enough
+  --> $DIR/ref-struct.rs:24:9
+   |
+LL |     fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 {
+   |                                         -             - let's call the lifetime of this reference `'1`
+   |                                         |
+   |                                         let's call the lifetime of this reference `'2`
+LL |         f
+   |         ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+
+error: lifetime may not live long enough
+  --> $DIR/ref-struct.rs:28:9
+   |
+LL |     fn box_pin_Struct(self: Box<Pin<&Struct>>, f: &u32) -> &u32 {
+   |                                     -             - let's call the lifetime of this reference `'1`
+   |                                     |
+   |                                     let's call the lifetime of this reference `'2`
+LL |         f
+   |         ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+
+error: aborting due to 5 previous errors
+

From 775ffd9df1b90e83c3145e3fefff30072c0683f8 Mon Sep 17 00:00:00 2001
From: Pietro Albini <pietro@pietroalbini.org>
Date: Mon, 5 Aug 2019 11:29:11 +0200
Subject: [PATCH 20/20] bless ui tests

---
 src/test/ui/parser/issue-62895.stderr | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/test/ui/parser/issue-62895.stderr b/src/test/ui/parser/issue-62895.stderr
index 7def7b562ca59..882764cb94678 100644
--- a/src/test/ui/parser/issue-62895.stderr
+++ b/src/test/ui/parser/issue-62895.stderr
@@ -30,7 +30,7 @@ error[E0412]: cannot find type `isizee` in this scope
   --> $DIR/issue-62895.rs:5:15
    |
 LL | pub fn g() -> isizee {
-   |               ^^^^^^ help: a builtin type with a similar name exists: `isize`
+   |               ^^^^^^ help: a primitive type with a similar name exists: `isize`
 
 error[E0308]: mismatched types
   --> $DIR/issue-62895.rs:3:11