From 2ce14b8a19865ed359e9df7eb5e8e6186cae1e58 Mon Sep 17 00:00:00 2001
From: Marincia Catalin <35623921+cata0309@users.noreply.github.com>
Date: Sat, 1 Feb 2020 19:05:50 +0200
Subject: [PATCH 1/5] Update option.rs

I updated the example of the `expect` examples so they won't contain depressing sentences any more !
---
 src/libcore/option.rs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/libcore/option.rs b/src/libcore/option.rs
index cb4247d98745e..ad0491f888cc7 100644
--- a/src/libcore/option.rs
+++ b/src/libcore/option.rs
@@ -331,12 +331,12 @@ impl<T> Option<T> {
     ///
     /// ```
     /// let x = Some("value");
-    /// assert_eq!(x.expect("the world is ending"), "value");
+    /// assert_eq!(x.expect("fruits are healthy"), "value");
     /// ```
     ///
     /// ```{.should_panic}
     /// let x: Option<&str> = None;
-    /// x.expect("the world is ending"); // panics with `the world is ending`
+    /// x.expect("fruits are healthy"); // panics with `fruits are healthy`
     /// ```
     #[inline]
     #[track_caller]

From f6c389472448257a91c2f6713061cd69025c766f Mon Sep 17 00:00:00 2001
From: Tyler Lanphear <animemachine13@gmail.com>
Date: Sun, 2 Feb 2020 01:05:53 -0500
Subject: [PATCH 2/5] compiletest: error if `compile-fail` header in ui test.

---
 .../bad-bounds-on-assoc-in-trait.rs           |   1 -
 .../bad-bounds-on-assoc-in-trait.stderr       |  10 +-
 .../ui/associated-type-bounds/duplicate.rs    |   1 -
 .../associated-type-bounds/duplicate.stderr   | 194 +++++++++---------
 .../implied-region-constraints.nll.stderr     |   4 +-
 .../implied-region-constraints.rs             |   2 -
 .../implied-region-constraints.stderr         |   4 +-
 .../ui/associated-type-bounds/inside-adt.rs   |   1 -
 .../associated-type-bounds/inside-adt.stderr  |  36 ++--
 src/test/ui/async-await/async-fn-nonsend.rs   |   1 -
 .../ui/async-await/async-fn-nonsend.stderr    |  12 +-
 src/test/ui/async-await/no-async-const.rs     |   1 -
 src/test/ui/async-await/no-async-const.stderr |   2 +-
 src/test/ui/async-await/no-const-async.rs     |   1 -
 src/test/ui/async-await/no-const-async.stderr |   4 +-
 .../no-move-across-await-struct.rs            |   1 -
 .../no-move-across-await-struct.stderr        |   2 +-
 .../async-await/no-move-across-await-tuple.rs |   1 -
 .../no-move-across-await-tuple.stderr         |   2 +-
 .../no-non-guaranteed-initialization.rs       |   1 -
 .../no-non-guaranteed-initialization.stderr   |   2 +-
 .../two-phase-nonrecv-autoref.nll.stderr      |  14 +-
 .../ui/borrowck/two-phase-nonrecv-autoref.rs  |   7 -
 .../ui/impl-trait/bound-normalization-fail.rs |   1 -
 .../bound-normalization-fail.stderr           |   8 +-
 ...f_types_pin_lifetime_impl_trait.nll.stderr |   2 +-
 ...rary_self_types_pin_lifetime_impl_trait.rs |   2 -
 ..._self_types_pin_lifetime_impl_trait.stderr |   8 +-
 ...elf_types_pin_lifetime_mismatch.nll.stderr |   6 +-
 ...itrary_self_types_pin_lifetime_mismatch.rs |   2 -
 ...ry_self_types_pin_lifetime_mismatch.stderr |   6 +-
 .../reservation-impl-coherence-conflict.rs    |   2 -
 ...reservation-impl-coherence-conflict.stderr |   2 +-
 .../reservation-impl-no-use.rs                |   2 -
 .../reservation-impl-no-use.stderr            |   2 +-
 .../ui/traits/wf-trait-object-maybe-bound.rs  |   2 -
 .../traits/wf-trait-object-maybe-bound.stderr |  10 +-
 src/tools/compiletest/src/header.rs           |   3 +
 38 files changed, 168 insertions(+), 194 deletions(-)

diff --git a/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.rs b/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.rs
index 78704a9b51239..3db5e468b35bf 100644
--- a/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.rs
+++ b/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.rs
@@ -1,4 +1,3 @@
-// compile-fail
 // ignore-tidy-linelength
 
 // NOTE: rustc cannot currently handle bounds of the form `for<'a> <Foo as Bar<'a>>::Assoc: Baz`.
diff --git a/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr b/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr
index 9f6a73cfe3910..5303a09644d50 100644
--- a/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr
+++ b/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr
@@ -1,5 +1,5 @@
 error[E0277]: `<L1 as Lam<&'a u8>>::App` doesn't implement `std::fmt::Debug`
-  --> $DIR/bad-bounds-on-assoc-in-trait.rs:32:6
+  --> $DIR/bad-bounds-on-assoc-in-trait.rs:31:6
    |
 LL | impl Case1 for S1 {
    |      ^^^^^ `<L1 as Lam<&'a u8>>::App` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug`
@@ -7,7 +7,7 @@ LL | impl Case1 for S1 {
    = help: the trait `for<'a> std::fmt::Debug` is not implemented for `<L1 as Lam<&'a u8>>::App`
 
 error[E0277]: `<<T as Case1>::C as std::iter::Iterator>::Item` is not an iterator
-  --> $DIR/bad-bounds-on-assoc-in-trait.rs:37:1
+  --> $DIR/bad-bounds-on-assoc-in-trait.rs:36:1
    |
 LL |   fn assume_case1<T: Case1>() {
    |   ^                          - help: consider further restricting the associated type: `where <<T as Case1>::C as std::iter::Iterator>::Item: std::iter::Iterator`
@@ -24,7 +24,7 @@ LL | | }
    = help: the trait `std::iter::Iterator` is not implemented for `<<T as Case1>::C as std::iter::Iterator>::Item`
 
 error[E0277]: `<<T as Case1>::C as std::iter::Iterator>::Item` cannot be sent between threads safely
-  --> $DIR/bad-bounds-on-assoc-in-trait.rs:37:1
+  --> $DIR/bad-bounds-on-assoc-in-trait.rs:36:1
    |
 LL |   trait Case1 {
    |   ----------- required by `Case1`
@@ -44,7 +44,7 @@ LL | | }
    = help: the trait `std::marker::Send` is not implemented for `<<T as Case1>::C as std::iter::Iterator>::Item`
 
 error[E0277]: `<<T as Case1>::C as std::iter::Iterator>::Item` cannot be shared between threads safely
-  --> $DIR/bad-bounds-on-assoc-in-trait.rs:37:1
+  --> $DIR/bad-bounds-on-assoc-in-trait.rs:36:1
    |
 LL |   trait Case1 {
    |   ----------- required by `Case1`
@@ -64,7 +64,7 @@ LL | | }
    = help: the trait `std::marker::Sync` is not implemented for `<<T as Case1>::C as std::iter::Iterator>::Item`
 
 error[E0277]: `<_ as Lam<&'a u8>>::App` doesn't implement `std::fmt::Debug`
-  --> $DIR/bad-bounds-on-assoc-in-trait.rs:37:1
+  --> $DIR/bad-bounds-on-assoc-in-trait.rs:36:1
    |
 LL |   trait Case1 {
    |   ----------- required by `Case1`
diff --git a/src/test/ui/associated-type-bounds/duplicate.rs b/src/test/ui/associated-type-bounds/duplicate.rs
index 65ca017e2f269..f8d230da36523 100644
--- a/src/test/ui/associated-type-bounds/duplicate.rs
+++ b/src/test/ui/associated-type-bounds/duplicate.rs
@@ -1,4 +1,3 @@
-// compile-fail
 // ignore-tidy-linelength
 
 #![feature(associated_type_bounds)]
diff --git a/src/test/ui/associated-type-bounds/duplicate.stderr b/src/test/ui/associated-type-bounds/duplicate.stderr
index defa62994e9e1..df1151d876c04 100644
--- a/src/test/ui/associated-type-bounds/duplicate.stderr
+++ b/src/test/ui/associated-type-bounds/duplicate.stderr
@@ -1,5 +1,5 @@
 warning: the feature `impl_trait_in_bindings` is incomplete and may cause the compiler to crash
-  --> $DIR/duplicate.rs:6:12
+  --> $DIR/duplicate.rs:5:12
    |
 LL | #![feature(impl_trait_in_bindings)]
    |            ^^^^^^^^^^^^^^^^^^^^^^
@@ -7,7 +7,7 @@ LL | #![feature(impl_trait_in_bindings)]
    = note: `#[warn(incomplete_features)]` on by default
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:11:36
+  --> $DIR/duplicate.rs:10:36
    |
 LL | struct SI1<T: Iterator<Item: Copy, Item: Send>> { f: T }
    |                        ----------  ^^^^^^^^^^ re-bound here
@@ -15,7 +15,7 @@ LL | struct SI1<T: Iterator<Item: Copy, Item: Send>> { f: T }
    |                        `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:13:36
+  --> $DIR/duplicate.rs:12:36
    |
 LL | struct SI2<T: Iterator<Item: Copy, Item: Copy>> { f: T }
    |                        ----------  ^^^^^^^^^^ re-bound here
@@ -23,7 +23,7 @@ LL | struct SI2<T: Iterator<Item: Copy, Item: Copy>> { f: T }
    |                        `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:15:39
+  --> $DIR/duplicate.rs:14:39
    |
 LL | struct SI3<T: Iterator<Item: 'static, Item: 'static>> { f: T }
    |                        -------------  ^^^^^^^^^^^^^ re-bound here
@@ -31,7 +31,7 @@ LL | struct SI3<T: Iterator<Item: 'static, Item: 'static>> { f: T }
    |                        `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:17:45
+  --> $DIR/duplicate.rs:16:45
    |
 LL | struct SW1<T> where T: Iterator<Item: Copy, Item: Send> { f: T }
    |                                 ----------  ^^^^^^^^^^ re-bound here
@@ -39,7 +39,7 @@ LL | struct SW1<T> where T: Iterator<Item: Copy, Item: Send> { f: T }
    |                                 `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:19:45
+  --> $DIR/duplicate.rs:18:45
    |
 LL | struct SW2<T> where T: Iterator<Item: Copy, Item: Copy> { f: T }
    |                                 ----------  ^^^^^^^^^^ re-bound here
@@ -47,7 +47,7 @@ LL | struct SW2<T> where T: Iterator<Item: Copy, Item: Copy> { f: T }
    |                                 `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:21:48
+  --> $DIR/duplicate.rs:20:48
    |
 LL | struct SW3<T> where T: Iterator<Item: 'static, Item: 'static> { f: T }
    |                                 -------------  ^^^^^^^^^^^^^ re-bound here
@@ -55,7 +55,7 @@ LL | struct SW3<T> where T: Iterator<Item: 'static, Item: 'static> { f: T }
    |                                 `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:24:34
+  --> $DIR/duplicate.rs:23:34
    |
 LL | enum EI1<T: Iterator<Item: Copy, Item: Send>> { V(T) }
    |                      ----------  ^^^^^^^^^^ re-bound here
@@ -63,7 +63,7 @@ LL | enum EI1<T: Iterator<Item: Copy, Item: Send>> { V(T) }
    |                      `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:26:34
+  --> $DIR/duplicate.rs:25:34
    |
 LL | enum EI2<T: Iterator<Item: Copy, Item: Copy>> { V(T) }
    |                      ----------  ^^^^^^^^^^ re-bound here
@@ -71,7 +71,7 @@ LL | enum EI2<T: Iterator<Item: Copy, Item: Copy>> { V(T) }
    |                      `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:28:37
+  --> $DIR/duplicate.rs:27:37
    |
 LL | enum EI3<T: Iterator<Item: 'static, Item: 'static>> { V(T) }
    |                      -------------  ^^^^^^^^^^^^^ re-bound here
@@ -79,7 +79,7 @@ LL | enum EI3<T: Iterator<Item: 'static, Item: 'static>> { V(T) }
    |                      `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:30:43
+  --> $DIR/duplicate.rs:29:43
    |
 LL | enum EW1<T> where T: Iterator<Item: Copy, Item: Send> { V(T) }
    |                               ----------  ^^^^^^^^^^ re-bound here
@@ -87,7 +87,7 @@ LL | enum EW1<T> where T: Iterator<Item: Copy, Item: Send> { V(T) }
    |                               `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:32:43
+  --> $DIR/duplicate.rs:31:43
    |
 LL | enum EW2<T> where T: Iterator<Item: Copy, Item: Copy> { V(T) }
    |                               ----------  ^^^^^^^^^^ re-bound here
@@ -95,7 +95,7 @@ LL | enum EW2<T> where T: Iterator<Item: Copy, Item: Copy> { V(T) }
    |                               `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:34:46
+  --> $DIR/duplicate.rs:33:46
    |
 LL | enum EW3<T> where T: Iterator<Item: 'static, Item: 'static> { V(T) }
    |                               -------------  ^^^^^^^^^^^^^ re-bound here
@@ -103,7 +103,7 @@ LL | enum EW3<T> where T: Iterator<Item: 'static, Item: 'static> { V(T) }
    |                               `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:37:35
+  --> $DIR/duplicate.rs:36:35
    |
 LL | union UI1<T: Iterator<Item: Copy, Item: Send>> { f: T }
    |                       ----------  ^^^^^^^^^^ re-bound here
@@ -111,7 +111,7 @@ LL | union UI1<T: Iterator<Item: Copy, Item: Send>> { f: T }
    |                       `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:39:35
+  --> $DIR/duplicate.rs:38:35
    |
 LL | union UI2<T: Iterator<Item: Copy, Item: Copy>> { f: T }
    |                       ----------  ^^^^^^^^^^ re-bound here
@@ -119,7 +119,7 @@ LL | union UI2<T: Iterator<Item: Copy, Item: Copy>> { f: T }
    |                       `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:41:38
+  --> $DIR/duplicate.rs:40:38
    |
 LL | union UI3<T: Iterator<Item: 'static, Item: 'static>> { f: T }
    |                       -------------  ^^^^^^^^^^^^^ re-bound here
@@ -127,7 +127,7 @@ LL | union UI3<T: Iterator<Item: 'static, Item: 'static>> { f: T }
    |                       `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:43:44
+  --> $DIR/duplicate.rs:42:44
    |
 LL | union UW1<T> where T: Iterator<Item: Copy, Item: Send> { f: T }
    |                                ----------  ^^^^^^^^^^ re-bound here
@@ -135,7 +135,7 @@ LL | union UW1<T> where T: Iterator<Item: Copy, Item: Send> { f: T }
    |                                `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:45:44
+  --> $DIR/duplicate.rs:44:44
    |
 LL | union UW2<T> where T: Iterator<Item: Copy, Item: Copy> { f: T }
    |                                ----------  ^^^^^^^^^^ re-bound here
@@ -143,7 +143,7 @@ LL | union UW2<T> where T: Iterator<Item: Copy, Item: Copy> { f: T }
    |                                `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:47:47
+  --> $DIR/duplicate.rs:46:47
    |
 LL | union UW3<T> where T: Iterator<Item: 'static, Item: 'static> { f: T }
    |                                -------------  ^^^^^^^^^^^^^ re-bound here
@@ -151,7 +151,7 @@ LL | union UW3<T> where T: Iterator<Item: 'static, Item: 'static> { f: T }
    |                                `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:50:32
+  --> $DIR/duplicate.rs:49:32
    |
 LL | fn FI1<T: Iterator<Item: Copy, Item: Send>>() {}
    |                    ----------  ^^^^^^^^^^ re-bound here
@@ -159,7 +159,7 @@ LL | fn FI1<T: Iterator<Item: Copy, Item: Send>>() {}
    |                    `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:52:32
+  --> $DIR/duplicate.rs:51:32
    |
 LL | fn FI2<T: Iterator<Item: Copy, Item: Copy>>() {}
    |                    ----------  ^^^^^^^^^^ re-bound here
@@ -167,7 +167,7 @@ LL | fn FI2<T: Iterator<Item: Copy, Item: Copy>>() {}
    |                    `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:54:35
+  --> $DIR/duplicate.rs:53:35
    |
 LL | fn FI3<T: Iterator<Item: 'static, Item: 'static>>() {}
    |                    -------------  ^^^^^^^^^^^^^ re-bound here
@@ -175,7 +175,7 @@ LL | fn FI3<T: Iterator<Item: 'static, Item: 'static>>() {}
    |                    `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:56:43
+  --> $DIR/duplicate.rs:55:43
    |
 LL | fn FW1<T>() where T: Iterator<Item: Copy, Item: Send> {}
    |                               ----------  ^^^^^^^^^^ re-bound here
@@ -183,7 +183,7 @@ LL | fn FW1<T>() where T: Iterator<Item: Copy, Item: Send> {}
    |                               `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:58:43
+  --> $DIR/duplicate.rs:57:43
    |
 LL | fn FW2<T>() where T: Iterator<Item: Copy, Item: Copy> {}
    |                               ----------  ^^^^^^^^^^ re-bound here
@@ -191,7 +191,7 @@ LL | fn FW2<T>() where T: Iterator<Item: Copy, Item: Copy> {}
    |                               `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:60:46
+  --> $DIR/duplicate.rs:59:46
    |
 LL | fn FW3<T>() where T: Iterator<Item: 'static, Item: 'static> {}
    |                               -------------  ^^^^^^^^^^^^^ re-bound here
@@ -199,7 +199,7 @@ LL | fn FW3<T>() where T: Iterator<Item: 'static, Item: 'static> {}
    |                               `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:69:40
+  --> $DIR/duplicate.rs:68:40
    |
 LL | fn FAPIT1(_: impl Iterator<Item: Copy, Item: Send>) {}
    |                            ----------  ^^^^^^^^^^ re-bound here
@@ -207,7 +207,7 @@ LL | fn FAPIT1(_: impl Iterator<Item: Copy, Item: Send>) {}
    |                            `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:71:40
+  --> $DIR/duplicate.rs:70:40
    |
 LL | fn FAPIT2(_: impl Iterator<Item: Copy, Item: Copy>) {}
    |                            ----------  ^^^^^^^^^^ re-bound here
@@ -215,7 +215,7 @@ LL | fn FAPIT2(_: impl Iterator<Item: Copy, Item: Copy>) {}
    |                            `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:73:43
+  --> $DIR/duplicate.rs:72:43
    |
 LL | fn FAPIT3(_: impl Iterator<Item: 'static, Item: 'static>) {}
    |                            -------------  ^^^^^^^^^^^^^ re-bound here
@@ -223,7 +223,7 @@ LL | fn FAPIT3(_: impl Iterator<Item: 'static, Item: 'static>) {}
    |                            `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:63:42
+  --> $DIR/duplicate.rs:62:42
    |
 LL | fn FRPIT1() -> impl Iterator<Item: Copy, Item: Send> { iter::empty() }
    |                              ----------  ^^^^^^^^^^ re-bound here
@@ -231,7 +231,7 @@ LL | fn FRPIT1() -> impl Iterator<Item: Copy, Item: Send> { iter::empty() }
    |                              `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:65:42
+  --> $DIR/duplicate.rs:64:42
    |
 LL | fn FRPIT2() -> impl Iterator<Item: Copy, Item: Copy> { iter::empty() }
    |                              ----------  ^^^^^^^^^^ re-bound here
@@ -239,7 +239,7 @@ LL | fn FRPIT2() -> impl Iterator<Item: Copy, Item: Copy> { iter::empty() }
    |                              `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:67:45
+  --> $DIR/duplicate.rs:66:45
    |
 LL | fn FRPIT3() -> impl Iterator<Item: 'static, Item: 'static> { iter::empty() }
    |                              -------------  ^^^^^^^^^^^^^ re-bound here
@@ -247,7 +247,7 @@ LL | fn FRPIT3() -> impl Iterator<Item: 'static, Item: 'static> { iter::empty()
    |                              `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:76:39
+  --> $DIR/duplicate.rs:75:39
    |
 LL | const CIT1: impl Iterator<Item: Copy, Item: Send> = iter::empty();
    |                           ----------  ^^^^^^^^^^ re-bound here
@@ -255,7 +255,7 @@ LL | const CIT1: impl Iterator<Item: Copy, Item: Send> = iter::empty();
    |                           `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:78:39
+  --> $DIR/duplicate.rs:77:39
    |
 LL | const CIT2: impl Iterator<Item: Copy, Item: Copy> = iter::empty();
    |                           ----------  ^^^^^^^^^^ re-bound here
@@ -263,7 +263,7 @@ LL | const CIT2: impl Iterator<Item: Copy, Item: Copy> = iter::empty();
    |                           `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:80:42
+  --> $DIR/duplicate.rs:79:42
    |
 LL | const CIT3: impl Iterator<Item: 'static, Item: 'static> = iter::empty();
    |                           -------------  ^^^^^^^^^^^^^ re-bound here
@@ -271,7 +271,7 @@ LL | const CIT3: impl Iterator<Item: 'static, Item: 'static> = iter::empty();
    |                           `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:82:40
+  --> $DIR/duplicate.rs:81:40
    |
 LL | static SIT1: impl Iterator<Item: Copy, Item: Send> = iter::empty();
    |                            ----------  ^^^^^^^^^^ re-bound here
@@ -279,7 +279,7 @@ LL | static SIT1: impl Iterator<Item: Copy, Item: Send> = iter::empty();
    |                            `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:84:40
+  --> $DIR/duplicate.rs:83:40
    |
 LL | static SIT2: impl Iterator<Item: Copy, Item: Copy> = iter::empty();
    |                            ----------  ^^^^^^^^^^ re-bound here
@@ -287,7 +287,7 @@ LL | static SIT2: impl Iterator<Item: Copy, Item: Copy> = iter::empty();
    |                            `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:86:43
+  --> $DIR/duplicate.rs:85:43
    |
 LL | static SIT3: impl Iterator<Item: 'static, Item: 'static> = iter::empty();
    |                            -------------  ^^^^^^^^^^^^^ re-bound here
@@ -295,7 +295,7 @@ LL | static SIT3: impl Iterator<Item: 'static, Item: 'static> = iter::empty();
    |                            `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:89:46
+  --> $DIR/duplicate.rs:88:46
    |
 LL | fn lit1() { let _: impl Iterator<Item: Copy, Item: Send> = iter::empty(); }
    |                                  ----------  ^^^^^^^^^^ re-bound here
@@ -303,7 +303,7 @@ LL | fn lit1() { let _: impl Iterator<Item: Copy, Item: Send> = iter::empty(); }
    |                                  `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:91:46
+  --> $DIR/duplicate.rs:90:46
    |
 LL | fn lit2() { let _: impl Iterator<Item: Copy, Item: Copy> = iter::empty(); }
    |                                  ----------  ^^^^^^^^^^ re-bound here
@@ -311,7 +311,7 @@ LL | fn lit2() { let _: impl Iterator<Item: Copy, Item: Copy> = iter::empty(); }
    |                                  `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:93:49
+  --> $DIR/duplicate.rs:92:49
    |
 LL | fn lit3() { let _: impl Iterator<Item: 'static, Item: 'static> = iter::empty(); }
    |                                  -------------  ^^^^^^^^^^^^^ re-bound here
@@ -319,7 +319,7 @@ LL | fn lit3() { let _: impl Iterator<Item: 'static, Item: 'static> = iter::empt
    |                                  `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:96:35
+  --> $DIR/duplicate.rs:95:35
    |
 LL | type TAI1<T: Iterator<Item: Copy, Item: Send>> = T;
    |                       ----------  ^^^^^^^^^^ re-bound here
@@ -327,7 +327,7 @@ LL | type TAI1<T: Iterator<Item: Copy, Item: Send>> = T;
    |                       `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:98:35
+  --> $DIR/duplicate.rs:97:35
    |
 LL | type TAI2<T: Iterator<Item: Copy, Item: Copy>> = T;
    |                       ----------  ^^^^^^^^^^ re-bound here
@@ -335,7 +335,7 @@ LL | type TAI2<T: Iterator<Item: Copy, Item: Copy>> = T;
    |                       `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:100:38
+  --> $DIR/duplicate.rs:99:38
    |
 LL | type TAI3<T: Iterator<Item: 'static, Item: 'static>> = T;
    |                       -------------  ^^^^^^^^^^^^^ re-bound here
@@ -343,7 +343,7 @@ LL | type TAI3<T: Iterator<Item: 'static, Item: 'static>> = T;
    |                       `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:102:44
+  --> $DIR/duplicate.rs:101:44
    |
 LL | type TAW1<T> where T: Iterator<Item: Copy, Item: Send> = T;
    |                                ----------  ^^^^^^^^^^ re-bound here
@@ -351,7 +351,7 @@ LL | type TAW1<T> where T: Iterator<Item: Copy, Item: Send> = T;
    |                                `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:104:44
+  --> $DIR/duplicate.rs:103:44
    |
 LL | type TAW2<T> where T: Iterator<Item: Copy, Item: Copy> = T;
    |                                ----------  ^^^^^^^^^^ re-bound here
@@ -359,7 +359,7 @@ LL | type TAW2<T> where T: Iterator<Item: Copy, Item: Copy> = T;
    |                                `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:106:47
+  --> $DIR/duplicate.rs:105:47
    |
 LL | type TAW3<T> where T: Iterator<Item: 'static, Item: 'static> = T;
    |                                -------------  ^^^^^^^^^^^^^ re-bound here
@@ -367,13 +367,13 @@ LL | type TAW3<T> where T: Iterator<Item: 'static, Item: 'static> = T;
    |                                `Item` bound here first
 
 error: could not find defining uses
-  --> $DIR/duplicate.rs:109:1
+  --> $DIR/duplicate.rs:108:1
    |
 LL | type ETAI1<T: Iterator<Item: Copy, Item: Send>> = impl Copy;
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:109:36
+  --> $DIR/duplicate.rs:108:36
    |
 LL | type ETAI1<T: Iterator<Item: Copy, Item: Send>> = impl Copy;
    |                        ----------  ^^^^^^^^^^ re-bound here
@@ -381,13 +381,13 @@ LL | type ETAI1<T: Iterator<Item: Copy, Item: Send>> = impl Copy;
    |                        `Item` bound here first
 
 error: could not find defining uses
-  --> $DIR/duplicate.rs:114:1
+  --> $DIR/duplicate.rs:113:1
    |
 LL | type ETAI2<T: Iterator<Item: Copy, Item: Copy>> = impl Copy;
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:114:36
+  --> $DIR/duplicate.rs:113:36
    |
 LL | type ETAI2<T: Iterator<Item: Copy, Item: Copy>> = impl Copy;
    |                        ----------  ^^^^^^^^^^ re-bound here
@@ -395,13 +395,13 @@ LL | type ETAI2<T: Iterator<Item: Copy, Item: Copy>> = impl Copy;
    |                        `Item` bound here first
 
 error: could not find defining uses
-  --> $DIR/duplicate.rs:119:1
+  --> $DIR/duplicate.rs:118:1
    |
 LL | type ETAI3<T: Iterator<Item: 'static, Item: 'static>> = impl Copy;
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:119:39
+  --> $DIR/duplicate.rs:118:39
    |
 LL | type ETAI3<T: Iterator<Item: 'static, Item: 'static>> = impl Copy;
    |                        -------------  ^^^^^^^^^^^^^ re-bound here
@@ -409,13 +409,13 @@ LL | type ETAI3<T: Iterator<Item: 'static, Item: 'static>> = impl Copy;
    |                        `Item` bound here first
 
 error: could not find defining uses
-  --> $DIR/duplicate.rs:124:1
+  --> $DIR/duplicate.rs:123:1
    |
 LL | type ETAI4 = impl Iterator<Item: Copy, Item: Send>;
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:124:40
+  --> $DIR/duplicate.rs:123:40
    |
 LL | type ETAI4 = impl Iterator<Item: Copy, Item: Send>;
    |                            ----------  ^^^^^^^^^^ re-bound here
@@ -423,13 +423,13 @@ LL | type ETAI4 = impl Iterator<Item: Copy, Item: Send>;
    |                            `Item` bound here first
 
 error: could not find defining uses
-  --> $DIR/duplicate.rs:129:1
+  --> $DIR/duplicate.rs:128:1
    |
 LL | type ETAI5 = impl Iterator<Item: Copy, Item: Copy>;
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:129:40
+  --> $DIR/duplicate.rs:128:40
    |
 LL | type ETAI5 = impl Iterator<Item: Copy, Item: Copy>;
    |                            ----------  ^^^^^^^^^^ re-bound here
@@ -437,13 +437,13 @@ LL | type ETAI5 = impl Iterator<Item: Copy, Item: Copy>;
    |                            `Item` bound here first
 
 error: could not find defining uses
-  --> $DIR/duplicate.rs:134:1
+  --> $DIR/duplicate.rs:133:1
    |
 LL | type ETAI6 = impl Iterator<Item: 'static, Item: 'static>;
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:134:43
+  --> $DIR/duplicate.rs:133:43
    |
 LL | type ETAI6 = impl Iterator<Item: 'static, Item: 'static>;
    |                            -------------  ^^^^^^^^^^^^^ re-bound here
@@ -451,7 +451,7 @@ LL | type ETAI6 = impl Iterator<Item: 'static, Item: 'static>;
    |                            `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:140:36
+  --> $DIR/duplicate.rs:139:36
    |
 LL | trait TRI1<T: Iterator<Item: Copy, Item: Send>> {}
    |                        ----------  ^^^^^^^^^^ re-bound here
@@ -459,7 +459,7 @@ LL | trait TRI1<T: Iterator<Item: Copy, Item: Send>> {}
    |                        `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:142:36
+  --> $DIR/duplicate.rs:141:36
    |
 LL | trait TRI2<T: Iterator<Item: Copy, Item: Copy>> {}
    |                        ----------  ^^^^^^^^^^ re-bound here
@@ -467,7 +467,7 @@ LL | trait TRI2<T: Iterator<Item: Copy, Item: Copy>> {}
    |                        `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:144:39
+  --> $DIR/duplicate.rs:143:39
    |
 LL | trait TRI3<T: Iterator<Item: 'static, Item: 'static>> {}
    |                        -------------  ^^^^^^^^^^^^^ re-bound here
@@ -475,7 +475,7 @@ LL | trait TRI3<T: Iterator<Item: 'static, Item: 'static>> {}
    |                        `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:146:34
+  --> $DIR/duplicate.rs:145:34
    |
 LL | trait TRS1: Iterator<Item: Copy, Item: Send> {}
    |                      ----------  ^^^^^^^^^^ re-bound here
@@ -483,7 +483,7 @@ LL | trait TRS1: Iterator<Item: Copy, Item: Send> {}
    |                      `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:148:34
+  --> $DIR/duplicate.rs:147:34
    |
 LL | trait TRS2: Iterator<Item: Copy, Item: Copy> {}
    |                      ----------  ^^^^^^^^^^ re-bound here
@@ -491,7 +491,7 @@ LL | trait TRS2: Iterator<Item: Copy, Item: Copy> {}
    |                      `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:150:37
+  --> $DIR/duplicate.rs:149:37
    |
 LL | trait TRS3: Iterator<Item: 'static, Item: 'static> {}
    |                      -------------  ^^^^^^^^^^^^^ re-bound here
@@ -499,7 +499,7 @@ LL | trait TRS3: Iterator<Item: 'static, Item: 'static> {}
    |                      `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:152:45
+  --> $DIR/duplicate.rs:151:45
    |
 LL | trait TRW1<T> where T: Iterator<Item: Copy, Item: Send> {}
    |                                 ----------  ^^^^^^^^^^ re-bound here
@@ -507,7 +507,7 @@ LL | trait TRW1<T> where T: Iterator<Item: Copy, Item: Send> {}
    |                                 `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:154:45
+  --> $DIR/duplicate.rs:153:45
    |
 LL | trait TRW2<T> where T: Iterator<Item: Copy, Item: Copy> {}
    |                                 ----------  ^^^^^^^^^^ re-bound here
@@ -515,7 +515,7 @@ LL | trait TRW2<T> where T: Iterator<Item: Copy, Item: Copy> {}
    |                                 `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:156:48
+  --> $DIR/duplicate.rs:155:48
    |
 LL | trait TRW3<T> where T: Iterator<Item: 'static, Item: 'static> {}
    |                                 -------------  ^^^^^^^^^^^^^ re-bound here
@@ -523,7 +523,7 @@ LL | trait TRW3<T> where T: Iterator<Item: 'static, Item: 'static> {}
    |                                 `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:158:46
+  --> $DIR/duplicate.rs:157:46
    |
 LL | trait TRSW1 where Self: Iterator<Item: Copy, Item: Send> {}
    |                                  ----------  ^^^^^^^^^^ re-bound here
@@ -531,7 +531,7 @@ LL | trait TRSW1 where Self: Iterator<Item: Copy, Item: Send> {}
    |                                  `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:158:46
+  --> $DIR/duplicate.rs:157:46
    |
 LL | trait TRSW1 where Self: Iterator<Item: Copy, Item: Send> {}
    |                                  ----------  ^^^^^^^^^^ re-bound here
@@ -539,7 +539,7 @@ LL | trait TRSW1 where Self: Iterator<Item: Copy, Item: Send> {}
    |                                  `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:161:46
+  --> $DIR/duplicate.rs:160:46
    |
 LL | trait TRSW2 where Self: Iterator<Item: Copy, Item: Copy> {}
    |                                  ----------  ^^^^^^^^^^ re-bound here
@@ -547,7 +547,7 @@ LL | trait TRSW2 where Self: Iterator<Item: Copy, Item: Copy> {}
    |                                  `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:161:46
+  --> $DIR/duplicate.rs:160:46
    |
 LL | trait TRSW2 where Self: Iterator<Item: Copy, Item: Copy> {}
    |                                  ----------  ^^^^^^^^^^ re-bound here
@@ -555,7 +555,7 @@ LL | trait TRSW2 where Self: Iterator<Item: Copy, Item: Copy> {}
    |                                  `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:164:49
+  --> $DIR/duplicate.rs:163:49
    |
 LL | trait TRSW3 where Self: Iterator<Item: 'static, Item: 'static> {}
    |                                  -------------  ^^^^^^^^^^^^^ re-bound here
@@ -563,7 +563,7 @@ LL | trait TRSW3 where Self: Iterator<Item: 'static, Item: 'static> {}
    |                                  `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:164:49
+  --> $DIR/duplicate.rs:163:49
    |
 LL | trait TRSW3 where Self: Iterator<Item: 'static, Item: 'static> {}
    |                                  -------------  ^^^^^^^^^^^^^ re-bound here
@@ -571,7 +571,7 @@ LL | trait TRSW3 where Self: Iterator<Item: 'static, Item: 'static> {}
    |                                  `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:167:43
+  --> $DIR/duplicate.rs:166:43
    |
 LL | trait TRA1 { type A: Iterator<Item: Copy, Item: Send>; }
    |                               ----------  ^^^^^^^^^^ re-bound here
@@ -579,7 +579,7 @@ LL | trait TRA1 { type A: Iterator<Item: Copy, Item: Send>; }
    |                               `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:169:43
+  --> $DIR/duplicate.rs:168:43
    |
 LL | trait TRA2 { type A: Iterator<Item: Copy, Item: Copy>; }
    |                               ----------  ^^^^^^^^^^ re-bound here
@@ -587,7 +587,7 @@ LL | trait TRA2 { type A: Iterator<Item: Copy, Item: Copy>; }
    |                               `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:171:46
+  --> $DIR/duplicate.rs:170:46
    |
 LL | trait TRA3 { type A: Iterator<Item: 'static, Item: 'static>; }
    |                               -------------  ^^^^^^^^^^^^^ re-bound here
@@ -595,7 +595,7 @@ LL | trait TRA3 { type A: Iterator<Item: 'static, Item: 'static>; }
    |                               `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:174:40
+  --> $DIR/duplicate.rs:173:40
    |
 LL | type TADyn1 = dyn Iterator<Item: Copy, Item: Send>;
    |                            ----------  ^^^^^^^^^^ re-bound here
@@ -603,7 +603,7 @@ LL | type TADyn1 = dyn Iterator<Item: Copy, Item: Send>;
    |                            `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:178:44
+  --> $DIR/duplicate.rs:177:44
    |
 LL | type TADyn2 = Box<dyn Iterator<Item: Copy, Item: Copy>>;
    |                                ----------  ^^^^^^^^^^ re-bound here
@@ -611,7 +611,7 @@ LL | type TADyn2 = Box<dyn Iterator<Item: Copy, Item: Copy>>;
    |                                `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified
-  --> $DIR/duplicate.rs:182:43
+  --> $DIR/duplicate.rs:181:43
    |
 LL | type TADyn3 = dyn Iterator<Item: 'static, Item: 'static>;
    |                            -------------  ^^^^^^^^^^^^^ re-bound here
@@ -619,109 +619,109 @@ LL | type TADyn3 = dyn Iterator<Item: 'static, Item: 'static>;
    |                            `Item` bound here first
 
 error: could not find defining uses
-  --> $DIR/duplicate.rs:109:24
+  --> $DIR/duplicate.rs:108:24
    |
 LL | type ETAI1<T: Iterator<Item: Copy, Item: Send>> = impl Copy;
    |                        ^^^^^^^^^^
 
 error: could not find defining uses
-  --> $DIR/duplicate.rs:109:36
+  --> $DIR/duplicate.rs:108:36
    |
 LL | type ETAI1<T: Iterator<Item: Copy, Item: Send>> = impl Copy;
    |                                    ^^^^^^^^^^
 
 error: could not find defining uses
-  --> $DIR/duplicate.rs:114:24
+  --> $DIR/duplicate.rs:113:24
    |
 LL | type ETAI2<T: Iterator<Item: Copy, Item: Copy>> = impl Copy;
    |                        ^^^^^^^^^^
 
 error: could not find defining uses
-  --> $DIR/duplicate.rs:114:36
+  --> $DIR/duplicate.rs:113:36
    |
 LL | type ETAI2<T: Iterator<Item: Copy, Item: Copy>> = impl Copy;
    |                                    ^^^^^^^^^^
 
 error: could not find defining uses
-  --> $DIR/duplicate.rs:119:24
+  --> $DIR/duplicate.rs:118:24
    |
 LL | type ETAI3<T: Iterator<Item: 'static, Item: 'static>> = impl Copy;
    |                        ^^^^^^^^^^^^^
 
 error: could not find defining uses
-  --> $DIR/duplicate.rs:119:39
+  --> $DIR/duplicate.rs:118:39
    |
 LL | type ETAI3<T: Iterator<Item: 'static, Item: 'static>> = impl Copy;
    |                                       ^^^^^^^^^^^^^
 
 error: could not find defining uses
-  --> $DIR/duplicate.rs:124:28
+  --> $DIR/duplicate.rs:123:28
    |
 LL | type ETAI4 = impl Iterator<Item: Copy, Item: Send>;
    |                            ^^^^^^^^^^
 
 error: could not find defining uses
-  --> $DIR/duplicate.rs:124:40
+  --> $DIR/duplicate.rs:123:40
    |
 LL | type ETAI4 = impl Iterator<Item: Copy, Item: Send>;
    |                                        ^^^^^^^^^^
 
 error: could not find defining uses
-  --> $DIR/duplicate.rs:129:28
+  --> $DIR/duplicate.rs:128:28
    |
 LL | type ETAI5 = impl Iterator<Item: Copy, Item: Copy>;
    |                            ^^^^^^^^^^
 
 error: could not find defining uses
-  --> $DIR/duplicate.rs:129:40
+  --> $DIR/duplicate.rs:128:40
    |
 LL | type ETAI5 = impl Iterator<Item: Copy, Item: Copy>;
    |                                        ^^^^^^^^^^
 
 error: could not find defining uses
-  --> $DIR/duplicate.rs:134:28
+  --> $DIR/duplicate.rs:133:28
    |
 LL | type ETAI6 = impl Iterator<Item: 'static, Item: 'static>;
    |                            ^^^^^^^^^^^^^
 
 error: could not find defining uses
-  --> $DIR/duplicate.rs:134:43
+  --> $DIR/duplicate.rs:133:43
    |
 LL | type ETAI6 = impl Iterator<Item: 'static, Item: 'static>;
    |                                           ^^^^^^^^^^^^^
 
 error: could not find defining uses
-  --> $DIR/duplicate.rs:174:28
+  --> $DIR/duplicate.rs:173:28
    |
 LL | type TADyn1 = dyn Iterator<Item: Copy, Item: Send>;
    |                            ^^^^^^^^^^
 
 error: could not find defining uses
-  --> $DIR/duplicate.rs:174:40
+  --> $DIR/duplicate.rs:173:40
    |
 LL | type TADyn1 = dyn Iterator<Item: Copy, Item: Send>;
    |                                        ^^^^^^^^^^
 
 error: could not find defining uses
-  --> $DIR/duplicate.rs:178:32
+  --> $DIR/duplicate.rs:177:32
    |
 LL | type TADyn2 = Box<dyn Iterator<Item: Copy, Item: Copy>>;
    |                                ^^^^^^^^^^
 
 error: could not find defining uses
-  --> $DIR/duplicate.rs:178:44
+  --> $DIR/duplicate.rs:177:44
    |
 LL | type TADyn2 = Box<dyn Iterator<Item: Copy, Item: Copy>>;
    |                                            ^^^^^^^^^^
 
 error: could not find defining uses
-  --> $DIR/duplicate.rs:182:28
+  --> $DIR/duplicate.rs:181:28
    |
 LL | type TADyn3 = dyn Iterator<Item: 'static, Item: 'static>;
    |                            ^^^^^^^^^^^^^
 
 error: could not find defining uses
-  --> $DIR/duplicate.rs:182:43
+  --> $DIR/duplicate.rs:181:43
    |
 LL | type TADyn3 = dyn Iterator<Item: 'static, Item: 'static>;
    |                                           ^^^^^^^^^^^^^
diff --git a/src/test/ui/associated-type-bounds/implied-region-constraints.nll.stderr b/src/test/ui/associated-type-bounds/implied-region-constraints.nll.stderr
index b8c54b13d8b4d..cddce8777eab7 100644
--- a/src/test/ui/associated-type-bounds/implied-region-constraints.nll.stderr
+++ b/src/test/ui/associated-type-bounds/implied-region-constraints.nll.stderr
@@ -1,5 +1,5 @@
 error: lifetime may not live long enough
-  --> $DIR/implied-region-constraints.rs:19:56
+  --> $DIR/implied-region-constraints.rs:17:56
    |
 LL | fn _bad_st<'a, 'b, T>(x: St<'a, 'b, T>)
    |            --  -- lifetime `'b` defined here
@@ -12,7 +12,7 @@ LL |     let _failure_proves_not_implied_outlives_region_b: &'b T = &x.f0;
    = help: consider adding the following bound: `'a: 'b`
 
 error: lifetime may not live long enough
-  --> $DIR/implied-region-constraints.rs:40:64
+  --> $DIR/implied-region-constraints.rs:38:64
    |
 LL | fn _bad_en7<'a, 'b, T>(x: En7<'a, 'b, T>)
    |             --  -- lifetime `'b` defined here
diff --git a/src/test/ui/associated-type-bounds/implied-region-constraints.rs b/src/test/ui/associated-type-bounds/implied-region-constraints.rs
index 4dbaab50a61db..ccad947f7f074 100644
--- a/src/test/ui/associated-type-bounds/implied-region-constraints.rs
+++ b/src/test/ui/associated-type-bounds/implied-region-constraints.rs
@@ -1,5 +1,3 @@
-// compile-fail
-
 #![feature(associated_type_bounds)]
 
 trait Tr1 { type As1; }
diff --git a/src/test/ui/associated-type-bounds/implied-region-constraints.stderr b/src/test/ui/associated-type-bounds/implied-region-constraints.stderr
index 60c6e8a80fb6a..c338e38d28f71 100644
--- a/src/test/ui/associated-type-bounds/implied-region-constraints.stderr
+++ b/src/test/ui/associated-type-bounds/implied-region-constraints.stderr
@@ -1,5 +1,5 @@
 error[E0623]: lifetime mismatch
-  --> $DIR/implied-region-constraints.rs:19:64
+  --> $DIR/implied-region-constraints.rs:17:64
    |
 LL | fn _bad_st<'a, 'b, T>(x: St<'a, 'b, T>)
    |                          ------------- this type is declared with multiple lifetimes...
@@ -8,7 +8,7 @@ LL |     let _failure_proves_not_implied_outlives_region_b: &'b T = &x.f0;
    |                                                                ^^^^^ ...but data with one lifetime flows into the other here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/implied-region-constraints.rs:40:72
+  --> $DIR/implied-region-constraints.rs:38:72
    |
 LL | fn _bad_en7<'a, 'b, T>(x: En7<'a, 'b, T>)
    |                           -------------- this type is declared with multiple lifetimes...
diff --git a/src/test/ui/associated-type-bounds/inside-adt.rs b/src/test/ui/associated-type-bounds/inside-adt.rs
index 59ce9496d28f0..b74c03829b48b 100644
--- a/src/test/ui/associated-type-bounds/inside-adt.rs
+++ b/src/test/ui/associated-type-bounds/inside-adt.rs
@@ -1,4 +1,3 @@
-// compile-fail
 #![feature(associated_type_bounds)]
 #![feature(untagged_unions)]
 
diff --git a/src/test/ui/associated-type-bounds/inside-adt.stderr b/src/test/ui/associated-type-bounds/inside-adt.stderr
index 9c4d03e900940..a532bb0c76697 100644
--- a/src/test/ui/associated-type-bounds/inside-adt.stderr
+++ b/src/test/ui/associated-type-bounds/inside-adt.stderr
@@ -1,107 +1,107 @@
 error: associated type bounds are not allowed within structs, enums, or unions
-  --> $DIR/inside-adt.rs:5:29
+  --> $DIR/inside-adt.rs:4:29
    |
 LL | struct S1 { f: dyn Iterator<Item: Copy> }
    |                             ^^^^^^^^^^
 
 error: associated type bounds are not allowed within structs, enums, or unions
-  --> $DIR/inside-adt.rs:8:33
+  --> $DIR/inside-adt.rs:7:33
    |
 LL | struct S2 { f: Box<dyn Iterator<Item: Copy>> }
    |                                 ^^^^^^^^^^
 
 error: associated type bounds are not allowed within structs, enums, or unions
-  --> $DIR/inside-adt.rs:11:29
+  --> $DIR/inside-adt.rs:10:29
    |
 LL | struct S3 { f: dyn Iterator<Item: 'static> }
    |                             ^^^^^^^^^^^^^
 
 error: associated type bounds are not allowed within structs, enums, or unions
-  --> $DIR/inside-adt.rs:15:26
+  --> $DIR/inside-adt.rs:14:26
    |
 LL | enum E1 { V(dyn Iterator<Item: Copy>) }
    |                          ^^^^^^^^^^
 
 error: associated type bounds are not allowed within structs, enums, or unions
-  --> $DIR/inside-adt.rs:18:30
+  --> $DIR/inside-adt.rs:17:30
    |
 LL | enum E2 { V(Box<dyn Iterator<Item: Copy>>) }
    |                              ^^^^^^^^^^
 
 error: associated type bounds are not allowed within structs, enums, or unions
-  --> $DIR/inside-adt.rs:21:26
+  --> $DIR/inside-adt.rs:20:26
    |
 LL | enum E3 { V(dyn Iterator<Item: 'static>) }
    |                          ^^^^^^^^^^^^^
 
 error: associated type bounds are not allowed within structs, enums, or unions
-  --> $DIR/inside-adt.rs:25:28
+  --> $DIR/inside-adt.rs:24:28
    |
 LL | union U1 { f: dyn Iterator<Item: Copy> }
    |                            ^^^^^^^^^^
 
 error: associated type bounds are not allowed within structs, enums, or unions
-  --> $DIR/inside-adt.rs:28:32
+  --> $DIR/inside-adt.rs:27:32
    |
 LL | union U2 { f: Box<dyn Iterator<Item: Copy>> }
    |                                ^^^^^^^^^^
 
 error: associated type bounds are not allowed within structs, enums, or unions
-  --> $DIR/inside-adt.rs:31:28
+  --> $DIR/inside-adt.rs:30:28
    |
 LL | union U3 { f: dyn Iterator<Item: 'static> }
    |                            ^^^^^^^^^^^^^
 
 error: could not find defining uses
-  --> $DIR/inside-adt.rs:5:29
+  --> $DIR/inside-adt.rs:4:29
    |
 LL | struct S1 { f: dyn Iterator<Item: Copy> }
    |                             ^^^^^^^^^^
 
 error: could not find defining uses
-  --> $DIR/inside-adt.rs:8:33
+  --> $DIR/inside-adt.rs:7:33
    |
 LL | struct S2 { f: Box<dyn Iterator<Item: Copy>> }
    |                                 ^^^^^^^^^^
 
 error: could not find defining uses
-  --> $DIR/inside-adt.rs:11:29
+  --> $DIR/inside-adt.rs:10:29
    |
 LL | struct S3 { f: dyn Iterator<Item: 'static> }
    |                             ^^^^^^^^^^^^^
 
 error: could not find defining uses
-  --> $DIR/inside-adt.rs:15:26
+  --> $DIR/inside-adt.rs:14:26
    |
 LL | enum E1 { V(dyn Iterator<Item: Copy>) }
    |                          ^^^^^^^^^^
 
 error: could not find defining uses
-  --> $DIR/inside-adt.rs:18:30
+  --> $DIR/inside-adt.rs:17:30
    |
 LL | enum E2 { V(Box<dyn Iterator<Item: Copy>>) }
    |                              ^^^^^^^^^^
 
 error: could not find defining uses
-  --> $DIR/inside-adt.rs:21:26
+  --> $DIR/inside-adt.rs:20:26
    |
 LL | enum E3 { V(dyn Iterator<Item: 'static>) }
    |                          ^^^^^^^^^^^^^
 
 error: could not find defining uses
-  --> $DIR/inside-adt.rs:25:28
+  --> $DIR/inside-adt.rs:24:28
    |
 LL | union U1 { f: dyn Iterator<Item: Copy> }
    |                            ^^^^^^^^^^
 
 error: could not find defining uses
-  --> $DIR/inside-adt.rs:28:32
+  --> $DIR/inside-adt.rs:27:32
    |
 LL | union U2 { f: Box<dyn Iterator<Item: Copy>> }
    |                                ^^^^^^^^^^
 
 error: could not find defining uses
-  --> $DIR/inside-adt.rs:31:28
+  --> $DIR/inside-adt.rs:30:28
    |
 LL | union U3 { f: dyn Iterator<Item: 'static> }
    |                            ^^^^^^^^^^^^^
diff --git a/src/test/ui/async-await/async-fn-nonsend.rs b/src/test/ui/async-await/async-fn-nonsend.rs
index ceeebbca5195a..845941200fc95 100644
--- a/src/test/ui/async-await/async-fn-nonsend.rs
+++ b/src/test/ui/async-await/async-fn-nonsend.rs
@@ -1,4 +1,3 @@
-// compile-fail
 // edition:2018
 // compile-flags: --crate-type lib
 
diff --git a/src/test/ui/async-await/async-fn-nonsend.stderr b/src/test/ui/async-await/async-fn-nonsend.stderr
index 105fd23ecfb66..3a2c42b383700 100644
--- a/src/test/ui/async-await/async-fn-nonsend.stderr
+++ b/src/test/ui/async-await/async-fn-nonsend.stderr
@@ -1,5 +1,5 @@
 error: future cannot be sent between threads safely
-  --> $DIR/async-fn-nonsend.rs:50:5
+  --> $DIR/async-fn-nonsend.rs:49:5
    |
 LL | fn assert_send(_: impl Send) {}
    |    -----------         ---- required by this bound in `assert_send`
@@ -9,7 +9,7 @@ LL |     assert_send(local_dropped_before_await());
    |
    = help: within `impl std::future::Future`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<()>`
 note: future is not `Send` as this value is used across an await
-  --> $DIR/async-fn-nonsend.rs:25:5
+  --> $DIR/async-fn-nonsend.rs:24:5
    |
 LL |     let x = non_send();
    |         - has type `impl std::fmt::Debug`
@@ -20,7 +20,7 @@ LL | }
    | - `x` is later dropped here
 
 error: future cannot be sent between threads safely
-  --> $DIR/async-fn-nonsend.rs:52:5
+  --> $DIR/async-fn-nonsend.rs:51:5
    |
 LL | fn assert_send(_: impl Send) {}
    |    -----------         ---- required by this bound in `assert_send`
@@ -30,7 +30,7 @@ LL |     assert_send(non_send_temporary_in_match());
    |
    = help: within `impl std::future::Future`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<()>`
 note: future is not `Send` as this value is used across an await
-  --> $DIR/async-fn-nonsend.rs:34:20
+  --> $DIR/async-fn-nonsend.rs:33:20
    |
 LL |     match Some(non_send()) {
    |                ---------- has type `impl std::fmt::Debug`
@@ -41,7 +41,7 @@ LL | }
    | - `non_send()` is later dropped here
 
 error: future cannot be sent between threads safely
-  --> $DIR/async-fn-nonsend.rs:54:5
+  --> $DIR/async-fn-nonsend.rs:53:5
    |
 LL | fn assert_send(_: impl Send) {}
    |    -----------         ---- required by this bound in `assert_send`
@@ -51,7 +51,7 @@ LL |     assert_send(non_sync_with_method_call());
    |
    = help: the trait `std::marker::Send` is not implemented for `dyn std::fmt::Write`
 note: future is not `Send` as this value is used across an await
-  --> $DIR/async-fn-nonsend.rs:43:9
+  --> $DIR/async-fn-nonsend.rs:42:9
    |
 LL |     let f: &mut std::fmt::Formatter = panic!();
    |         - has type `&mut std::fmt::Formatter<'_>`
diff --git a/src/test/ui/async-await/no-async-const.rs b/src/test/ui/async-await/no-async-const.rs
index 44f02d1a7b19b..64322990d0a93 100644
--- a/src/test/ui/async-await/no-async-const.rs
+++ b/src/test/ui/async-await/no-async-const.rs
@@ -1,4 +1,3 @@
-// compile-fail
 // edition:2018
 // compile-flags: --crate-type lib
 
diff --git a/src/test/ui/async-await/no-async-const.stderr b/src/test/ui/async-await/no-async-const.stderr
index 05cdbff0bf042..d5b8b344abe62 100644
--- a/src/test/ui/async-await/no-async-const.stderr
+++ b/src/test/ui/async-await/no-async-const.stderr
@@ -1,5 +1,5 @@
 error: expected one of `fn` or `unsafe`, found keyword `const`
-  --> $DIR/no-async-const.rs:5:11
+  --> $DIR/no-async-const.rs:4:11
    |
 LL | pub async const fn x() {}
    |           ^^^^^ expected one of `fn` or `unsafe`
diff --git a/src/test/ui/async-await/no-const-async.rs b/src/test/ui/async-await/no-const-async.rs
index ef7edf8504952..55b27bd3fa1ac 100644
--- a/src/test/ui/async-await/no-const-async.rs
+++ b/src/test/ui/async-await/no-const-async.rs
@@ -1,4 +1,3 @@
-// compile-fail
 // edition:2018
 // compile-flags: --crate-type lib
 
diff --git a/src/test/ui/async-await/no-const-async.stderr b/src/test/ui/async-await/no-const-async.stderr
index 7ed822a5cd5a1..62cd5c45d1950 100644
--- a/src/test/ui/async-await/no-const-async.stderr
+++ b/src/test/ui/async-await/no-const-async.stderr
@@ -1,11 +1,11 @@
 error: expected identifier, found keyword `async`
-  --> $DIR/no-const-async.rs:5:11
+  --> $DIR/no-const-async.rs:4:11
    |
 LL | pub const async fn x() {}
    |           ^^^^^ expected identifier, found keyword
 
 error: expected `:`, found keyword `fn`
-  --> $DIR/no-const-async.rs:5:17
+  --> $DIR/no-const-async.rs:4:17
    |
 LL | pub const async fn x() {}
    |                 ^^ expected `:`
diff --git a/src/test/ui/async-await/no-move-across-await-struct.rs b/src/test/ui/async-await/no-move-across-await-struct.rs
index bef477bd256ec..51c9a42b3f4e3 100644
--- a/src/test/ui/async-await/no-move-across-await-struct.rs
+++ b/src/test/ui/async-await/no-move-across-await-struct.rs
@@ -1,4 +1,3 @@
-// compile-fail
 // edition:2018
 // compile-flags: --crate-type lib
 
diff --git a/src/test/ui/async-await/no-move-across-await-struct.stderr b/src/test/ui/async-await/no-move-across-await-struct.stderr
index 88f147b8d9ddd..adfae09925fef 100644
--- a/src/test/ui/async-await/no-move-across-await-struct.stderr
+++ b/src/test/ui/async-await/no-move-across-await-struct.stderr
@@ -1,5 +1,5 @@
 error[E0382]: use of moved value: `s.x`
-  --> $DIR/no-move-across-await-struct.rs:8:5
+  --> $DIR/no-move-across-await-struct.rs:7:5
    |
 LL |     needs_vec(s.x).await;
    |               --- value moved here
diff --git a/src/test/ui/async-await/no-move-across-await-tuple.rs b/src/test/ui/async-await/no-move-across-await-tuple.rs
index 565cbd7d5f4ae..a656332698c43 100644
--- a/src/test/ui/async-await/no-move-across-await-tuple.rs
+++ b/src/test/ui/async-await/no-move-across-await-tuple.rs
@@ -1,4 +1,3 @@
-// compile-fail
 // edition:2018
 // compile-flags: --crate-type lib
 
diff --git a/src/test/ui/async-await/no-move-across-await-tuple.stderr b/src/test/ui/async-await/no-move-across-await-tuple.stderr
index fe98ecd599a23..a60fd9361a779 100644
--- a/src/test/ui/async-await/no-move-across-await-tuple.stderr
+++ b/src/test/ui/async-await/no-move-across-await-tuple.stderr
@@ -1,5 +1,5 @@
 error[E0382]: use of moved value: `x.1`
-  --> $DIR/no-move-across-await-tuple.rs:9:5
+  --> $DIR/no-move-across-await-tuple.rs:8:5
    |
 LL |     drop(x.1);
    |          --- value moved here
diff --git a/src/test/ui/async-await/no-non-guaranteed-initialization.rs b/src/test/ui/async-await/no-non-guaranteed-initialization.rs
index 6a34209d55289..24070fe33083c 100644
--- a/src/test/ui/async-await/no-non-guaranteed-initialization.rs
+++ b/src/test/ui/async-await/no-non-guaranteed-initialization.rs
@@ -1,4 +1,3 @@
-// compile-fail
 // edition:2018
 // compile-flags: --crate-type lib
 
diff --git a/src/test/ui/async-await/no-non-guaranteed-initialization.stderr b/src/test/ui/async-await/no-non-guaranteed-initialization.stderr
index b9aa9924bb815..f5991f4bccac9 100644
--- a/src/test/ui/async-await/no-non-guaranteed-initialization.stderr
+++ b/src/test/ui/async-await/no-non-guaranteed-initialization.stderr
@@ -1,5 +1,5 @@
 error[E0381]: use of possibly-uninitialized variable: `y`
-  --> $DIR/no-non-guaranteed-initialization.rs:10:5
+  --> $DIR/no-non-guaranteed-initialization.rs:9:5
    |
 LL |     y
    |     ^ use of possibly-uninitialized `y`
diff --git a/src/test/ui/borrowck/two-phase-nonrecv-autoref.nll.stderr b/src/test/ui/borrowck/two-phase-nonrecv-autoref.nll.stderr
index baf122df5e268..21ae25c16bb78 100644
--- a/src/test/ui/borrowck/two-phase-nonrecv-autoref.nll.stderr
+++ b/src/test/ui/borrowck/two-phase-nonrecv-autoref.nll.stderr
@@ -1,5 +1,5 @@
 error[E0499]: cannot borrow `*f` as mutable more than once at a time
-  --> $DIR/two-phase-nonrecv-autoref.rs:58:11
+  --> $DIR/two-phase-nonrecv-autoref.rs:51:11
    |
 LL |         f(f(10));
    |         - ^ second mutable borrow occurs here
@@ -8,7 +8,7 @@ LL |         f(f(10));
    |         first borrow later used by call
 
 error[E0382]: use of moved value: `f`
-  --> $DIR/two-phase-nonrecv-autoref.rs:66:11
+  --> $DIR/two-phase-nonrecv-autoref.rs:59:11
    |
 LL |     fn twice_ten_so<F: FnOnce(i32) -> i32>(f: Box<F>) {
    |                                            - move occurs because `f` has type `std::boxed::Box<F>`, which does not implement the `Copy` trait
@@ -18,7 +18,7 @@ LL |         f(f(10));
    |         value moved here
 
 error[E0499]: cannot borrow `*f` as mutable more than once at a time
-  --> $DIR/two-phase-nonrecv-autoref.rs:72:11
+  --> $DIR/two-phase-nonrecv-autoref.rs:65:11
    |
 LL |         f(f(10));
    |         - ^ second mutable borrow occurs here
@@ -27,7 +27,7 @@ LL |         f(f(10));
    |         first borrow later used by call
 
 error[E0382]: use of moved value: `f`
-  --> $DIR/two-phase-nonrecv-autoref.rs:80:11
+  --> $DIR/two-phase-nonrecv-autoref.rs:73:11
    |
 LL |     fn twice_ten_oo(f: Box<dyn FnOnce(i32) -> i32>) {
    |                     - move occurs because `f` has type `std::boxed::Box<dyn std::ops::FnOnce(i32) -> i32>`, which does not implement the `Copy` trait
@@ -37,7 +37,7 @@ LL |         f(f(10));
    |         value moved here
 
 error[E0502]: cannot borrow `a` as immutable because it is also borrowed as mutable
-  --> $DIR/two-phase-nonrecv-autoref.rs:119:27
+  --> $DIR/two-phase-nonrecv-autoref.rs:112:27
    |
 LL |     double_access(&mut a, &a);
    |     ------------- ------  ^^ immutable borrow occurs here
@@ -46,7 +46,7 @@ LL |     double_access(&mut a, &a);
    |     mutable borrow later used by call
 
 error[E0502]: cannot borrow `i` as immutable because it is also borrowed as mutable
-  --> $DIR/two-phase-nonrecv-autoref.rs:145:7
+  --> $DIR/two-phase-nonrecv-autoref.rs:138:7
    |
 LL |     i[i[3]] = 4;
    |     --^----
@@ -56,7 +56,7 @@ LL |     i[i[3]] = 4;
    |     mutable borrow later used here
 
 error[E0502]: cannot borrow `i` as immutable because it is also borrowed as mutable
-  --> $DIR/two-phase-nonrecv-autoref.rs:150:7
+  --> $DIR/two-phase-nonrecv-autoref.rs:143:7
    |
 LL |     i[i[3]] = i[4];
    |     --^----
diff --git a/src/test/ui/borrowck/two-phase-nonrecv-autoref.rs b/src/test/ui/borrowck/two-phase-nonrecv-autoref.rs
index b29664e3d8cbd..918c7a1be197a 100644
--- a/src/test/ui/borrowck/two-phase-nonrecv-autoref.rs
+++ b/src/test/ui/borrowck/two-phase-nonrecv-autoref.rs
@@ -13,13 +13,6 @@
 // receivers (namely, in many cases demonstrated below, the error
 // would not arise).
 
-// (If we revise the compiler or this test so that the g2p revision
-// passes, turn the `rustc_attrs` feature back on and tag the `fn
-// main` with `#[rustc_error]` so that this remains a valid
-// compile-fail test.)
-//
-// #![feature(rustc_attrs)]
-
 use std::ops::{Index, IndexMut};
 
 fn foo(x: &mut u32, y: u32) {
diff --git a/src/test/ui/impl-trait/bound-normalization-fail.rs b/src/test/ui/impl-trait/bound-normalization-fail.rs
index 235c1f80ef637..5bf3ec733f5d7 100644
--- a/src/test/ui/impl-trait/bound-normalization-fail.rs
+++ b/src/test/ui/impl-trait/bound-normalization-fail.rs
@@ -1,4 +1,3 @@
-// compile-fail
 // ignore-tidy-linelength
 // edition:2018
 
diff --git a/src/test/ui/impl-trait/bound-normalization-fail.stderr b/src/test/ui/impl-trait/bound-normalization-fail.stderr
index fc4cddd02168e..22ba8342ff41f 100644
--- a/src/test/ui/impl-trait/bound-normalization-fail.stderr
+++ b/src/test/ui/impl-trait/bound-normalization-fail.stderr
@@ -1,5 +1,5 @@
 warning: the feature `impl_trait_in_bindings` is incomplete and may cause the compiler to crash
-  --> $DIR/bound-normalization-fail.rs:5:12
+  --> $DIR/bound-normalization-fail.rs:4:12
    |
 LL | #![feature(impl_trait_in_bindings)]
    |            ^^^^^^^^^^^^^^^^^^^^^^
@@ -7,7 +7,7 @@ LL | #![feature(impl_trait_in_bindings)]
    = note: `#[warn(incomplete_features)]` on by default
 
 error[E0271]: type mismatch resolving `<Foo<()> as FooLike>::Output == <T as impl_trait::Trait>::Assoc`
-  --> $DIR/bound-normalization-fail.rs:28:32
+  --> $DIR/bound-normalization-fail.rs:27:32
    |
 LL |     fn foo_fail<T: Trait>() -> impl FooLike<Output=T::Assoc> {
    |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type
@@ -19,13 +19,13 @@ LL |     fn foo_fail<T: Trait>() -> impl FooLike<Output=T::Assoc> {
    = note: the return type of a function must have a statically known size
 
 error: `impl Trait` return type cannot contain a projection or `Self` that references lifetimes from a parent scope
-  --> $DIR/bound-normalization-fail.rs:44:41
+  --> $DIR/bound-normalization-fail.rs:43:41
    |
 LL |     fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike<Output=T::Assoc> {
    |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0271]: type mismatch resolving `<Foo<()> as FooLike>::Output == <T as lifetimes::Trait<'static>>::Assoc`
-  --> $DIR/bound-normalization-fail.rs:44:41
+  --> $DIR/bound-normalization-fail.rs:43:41
    |
 LL |     fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike<Output=T::Assoc> {
    |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type
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
index b76966e8693f2..73766c31b93b6 100644
--- 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
@@ -1,5 +1,5 @@
 error: lifetime may not live long enough
-  --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait.rs:8:31
+  --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait.rs:6:31
    |
 LL |     fn f(self: Pin<&Self>) -> impl Clone { self }
    |                    -          ^^^^^^^^^^ opaque type requires that `'1` must outlive `'static`
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
index ad8959727cbee..5054568b18970 100644
--- 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
@@ -1,5 +1,3 @@
-// compile-fail
-
 use std::pin::Pin;
 
 struct Foo;
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
index 9f5414995151b..47ab6fff83878 100644
--- 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
@@ -1,17 +1,17 @@
 error: cannot infer an appropriate lifetime
-  --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait.rs:8:44
+  --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait.rs:6: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
+note: ...can't outlive the anonymous lifetime #1 defined on the method body at 6:5
+  --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait.rs:6:5
    |
 LL |     fn f(self: Pin<&Self>) -> impl Clone { self }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-help: you can add a bound 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
+help: you can add a bound to the return type to make it last less than `'static` and match the anonymous lifetime #1 defined on the method body at 6:5
    |
 LL |     fn f(self: Pin<&Self>) -> impl Clone + '_ { self }
    |                               ^^^^^^^^^^^^^^^
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
index 8a0f1a804ad82..1a0904fcbba6e 100644
--- 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
@@ -1,5 +1,5 @@
 error: lifetime may not live long enough
-  --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:8:46
+  --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:6: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`
@@ -8,7 +8,7 @@ LL |     fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f }
    |                    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
+  --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:8: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`
@@ -17,7 +17,7 @@ LL |     fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self,
    |                    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
+  --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:13: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`
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 fc5f94201b81a..8291e44080b37 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
@@ -1,5 +1,3 @@
-// compile-fail
-
 use std::pin::Pin;
 
 struct Foo;
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 f3a7d14720171..6bb7ad7cdc7c2 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
@@ -1,5 +1,5 @@
 error[E0623]: lifetime mismatch
-  --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:8:46
+  --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:6:46
    |
 LL |     fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f }
    |                              ----     ----   ^ ...but data from `f` is returned here
@@ -7,7 +7,7 @@ LL |     fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f }
    |                              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
+  --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:8:76
    |
 LL |     fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) }
    |                               ----              -----------------          ^ ...but data from `f` is returned here
@@ -15,7 +15,7 @@ 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[E0623]: lifetime mismatch
-  --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:15:58
+  --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:13:58
    |
 LL |     fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg }
    |                                         ------     ---   ^^^ ...but data from `arg` is returned here
diff --git a/src/test/ui/traits/reservation-impls/reservation-impl-coherence-conflict.rs b/src/test/ui/traits/reservation-impls/reservation-impl-coherence-conflict.rs
index 775278c30cd4c..fa4a309315b47 100644
--- a/src/test/ui/traits/reservation-impls/reservation-impl-coherence-conflict.rs
+++ b/src/test/ui/traits/reservation-impls/reservation-impl-coherence-conflict.rs
@@ -1,5 +1,3 @@
-// compile-fail
-
 // check that reservation impls are accounted for in negative reasoning.
 
 #![feature(rustc_attrs)]
diff --git a/src/test/ui/traits/reservation-impls/reservation-impl-coherence-conflict.stderr b/src/test/ui/traits/reservation-impls/reservation-impl-coherence-conflict.stderr
index 47e141bd048eb..d76d3a91c8d3f 100644
--- a/src/test/ui/traits/reservation-impls/reservation-impl-coherence-conflict.stderr
+++ b/src/test/ui/traits/reservation-impls/reservation-impl-coherence-conflict.stderr
@@ -1,5 +1,5 @@
 error[E0119]: conflicting implementations of trait `OtherTrait` for type `()`:
-  --> $DIR/reservation-impl-coherence-conflict.rs:13:1
+  --> $DIR/reservation-impl-coherence-conflict.rs:11:1
    |
 LL | impl OtherTrait for () {}
    | ---------------------- first implementation here
diff --git a/src/test/ui/traits/reservation-impls/reservation-impl-no-use.rs b/src/test/ui/traits/reservation-impls/reservation-impl-no-use.rs
index 3391daaabe975..65a55d9e20936 100644
--- a/src/test/ui/traits/reservation-impls/reservation-impl-no-use.rs
+++ b/src/test/ui/traits/reservation-impls/reservation-impl-no-use.rs
@@ -1,5 +1,3 @@
-// compile-fail
-
 // check that reservation impls can't be used as normal impls in positive reasoning.
 
 #![feature(rustc_attrs)]
diff --git a/src/test/ui/traits/reservation-impls/reservation-impl-no-use.stderr b/src/test/ui/traits/reservation-impls/reservation-impl-no-use.stderr
index 0cd56b978f10c..794faff8848fe 100644
--- a/src/test/ui/traits/reservation-impls/reservation-impl-no-use.stderr
+++ b/src/test/ui/traits/reservation-impls/reservation-impl-no-use.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `(): MyTrait` is not satisfied
-  --> $DIR/reservation-impl-no-use.rs:12:26
+  --> $DIR/reservation-impl-no-use.rs:10:26
    |
 LL | trait MyTrait { fn foo(&self); }
    |                 -------------- required by `MyTrait::foo`
diff --git a/src/test/ui/traits/wf-trait-object-maybe-bound.rs b/src/test/ui/traits/wf-trait-object-maybe-bound.rs
index f24c1301c53ab..17771e976ef3b 100644
--- a/src/test/ui/traits/wf-trait-object-maybe-bound.rs
+++ b/src/test/ui/traits/wf-trait-object-maybe-bound.rs
@@ -1,5 +1,3 @@
-// compile-fail
-
 // Test that `dyn ... + ?Sized + ...` is okay (though `?Sized` has no effect in trait objects).
 
 trait Foo {}
diff --git a/src/test/ui/traits/wf-trait-object-maybe-bound.stderr b/src/test/ui/traits/wf-trait-object-maybe-bound.stderr
index 11187342d59f2..4a570efcb5dbc 100644
--- a/src/test/ui/traits/wf-trait-object-maybe-bound.stderr
+++ b/src/test/ui/traits/wf-trait-object-maybe-bound.stderr
@@ -1,29 +1,29 @@
 error: `?Trait` is not permitted in trait object types
-  --> $DIR/wf-trait-object-maybe-bound.rs:7:15
+  --> $DIR/wf-trait-object-maybe-bound.rs:5:15
    |
 LL | type _0 = dyn ?Sized + Foo;
    |               ^^^^^^
 
 error: `?Trait` is not permitted in trait object types
-  --> $DIR/wf-trait-object-maybe-bound.rs:10:21
+  --> $DIR/wf-trait-object-maybe-bound.rs:8:21
    |
 LL | type _1 = dyn Foo + ?Sized;
    |                     ^^^^^^
 
 error: `?Trait` is not permitted in trait object types
-  --> $DIR/wf-trait-object-maybe-bound.rs:13:21
+  --> $DIR/wf-trait-object-maybe-bound.rs:11:21
    |
 LL | type _2 = dyn Foo + ?Sized + ?Sized;
    |                     ^^^^^^
 
 error: `?Trait` is not permitted in trait object types
-  --> $DIR/wf-trait-object-maybe-bound.rs:13:30
+  --> $DIR/wf-trait-object-maybe-bound.rs:11:30
    |
 LL | type _2 = dyn Foo + ?Sized + ?Sized;
    |                              ^^^^^^
 
 error: `?Trait` is not permitted in trait object types
-  --> $DIR/wf-trait-object-maybe-bound.rs:17:15
+  --> $DIR/wf-trait-object-maybe-bound.rs:15:15
    |
 LL | type _3 = dyn ?Sized + Foo;
    |               ^^^^^^
diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index 817705c0bd6bf..555e79d3e065c 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -554,6 +554,9 @@ impl TestProps {
                 panic!("`{}-fail` header is only supported in UI tests", mode);
             }
         };
+        if config.mode == Mode::Ui && config.parse_name_directive(ln, "compile-fail") {
+            panic!("`compile-fail` header is useless in UI tests");
+        }
         let fail_mode = if config.parse_name_directive(ln, "check-fail") {
             check_ui("check");
             Some(FailMode::Check)

From 8674efdb7c9d263caef8d282086a4243eae8df20 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Wed, 29 Jan 2020 01:30:01 +0100
Subject: [PATCH 3/5] parser: move restrictions re. `self` to `ast_validation`.

---
 src/librustc_ast_passes/ast_validation.rs     |  44 +++-
 src/librustc_parse/parser/diagnostics.rs      |  12 +-
 src/librustc_parse/parser/item.rs             |  60 +++--
 src/librustc_parse/parser/ty.rs               |   4 +-
 .../ui/invalid-self-argument/bare-fn-start.rs |   6 +-
 .../bare-fn-start.stderr                      |   6 +-
 .../ui/parser/self-param-semantic-fail.rs     |  64 +++++
 .../ui/parser/self-param-semantic-fail.stderr | 220 ++++++++++++++++++
 .../ui/parser/self-param-syntactic-pass.rs    |  66 ++++++
 9 files changed, 426 insertions(+), 56 deletions(-)
 create mode 100644 src/test/ui/parser/self-param-semantic-fail.rs
 create mode 100644 src/test/ui/parser/self-param-semantic-fail.stderr
 create mode 100644 src/test/ui/parser/self-param-syntactic-pass.rs

diff --git a/src/librustc_ast_passes/ast_validation.rs b/src/librustc_ast_passes/ast_validation.rs
index 152086bfce0ea..f37f93c0254bd 100644
--- a/src/librustc_ast_passes/ast_validation.rs
+++ b/src/librustc_ast_passes/ast_validation.rs
@@ -23,6 +23,12 @@ use syntax::print::pprust;
 use syntax::visit::{self, Visitor};
 use syntax::walk_list;
 
+/// Is `self` allowed semantically as the first parameter in an `FnDecl`?
+enum SelfSemantic {
+    Yes,
+    No,
+}
+
 /// A syntactic context that disallows certain kinds of bounds (e.g., `?Trait` or `?const Trait`).
 #[derive(Clone, Copy)]
 enum BoundContext {
@@ -302,7 +308,13 @@ impl<'a> AstValidator<'a> {
         }
     }
 
-    fn check_fn_decl(&self, fn_decl: &FnDecl) {
+    fn check_fn_decl(&self, fn_decl: &FnDecl, self_semantic: SelfSemantic) {
+        self.check_decl_cvaradic_pos(fn_decl);
+        self.check_decl_attrs(fn_decl);
+        self.check_decl_self_param(fn_decl, self_semantic);
+    }
+
+    fn check_decl_cvaradic_pos(&self, fn_decl: &FnDecl) {
         match &*fn_decl.inputs {
             [Param { ty, span, .. }] => {
                 if let TyKind::CVarArgs = ty.kind {
@@ -324,7 +336,9 @@ impl<'a> AstValidator<'a> {
             }
             _ => {}
         }
+    }
 
+    fn check_decl_attrs(&self, fn_decl: &FnDecl) {
         fn_decl
             .inputs
             .iter()
@@ -352,6 +366,21 @@ impl<'a> AstValidator<'a> {
             });
     }
 
+    fn check_decl_self_param(&self, fn_decl: &FnDecl, self_semantic: SelfSemantic) {
+        if let (SelfSemantic::No, [param, ..]) = (self_semantic, &*fn_decl.inputs) {
+            if param.is_self() {
+                self.err_handler()
+                    .struct_span_err(
+                        param.span,
+                        "`self` parameter only allowed in associated `fn`s",
+                    )
+                    .span_label(param.span, "not semantically valid as function parameter")
+                    .note("associated `fn`s are those in `impl` or `trait` definitions")
+                    .emit();
+            }
+        }
+    }
+
     fn check_defaultness(&self, span: Span, defaultness: Defaultness) {
         if let Defaultness::Default = defaultness {
             self.err_handler()
@@ -504,7 +533,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
     fn visit_expr(&mut self, expr: &'a Expr) {
         match &expr.kind {
             ExprKind::Closure(_, _, _, fn_decl, _, _) => {
-                self.check_fn_decl(fn_decl);
+                self.check_fn_decl(fn_decl, SelfSemantic::No);
             }
             ExprKind::InlineAsm(..) if !self.session.target.target.options.allow_asm => {
                 struct_span_err!(
@@ -524,7 +553,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
     fn visit_ty(&mut self, ty: &'a Ty) {
         match ty.kind {
             TyKind::BareFn(ref bfty) => {
-                self.check_fn_decl(&bfty.decl);
+                self.check_fn_decl(&bfty.decl, SelfSemantic::No);
                 Self::check_decl_no_pat(&bfty.decl, |span, _| {
                     struct_span_err!(
                         self.session,
@@ -685,7 +714,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
             }
             ItemKind::Fn(ref sig, ref generics, _) => {
                 self.visit_fn_header(&sig.header);
-                self.check_fn_decl(&sig.decl);
+                self.check_fn_decl(&sig.decl, SelfSemantic::No);
                 // We currently do not permit const generics in `const fn`, as
                 // this is tantamount to allowing compile-time dependent typing.
                 if sig.header.constness.node == Constness::Const {
@@ -793,7 +822,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
     fn visit_foreign_item(&mut self, fi: &'a ForeignItem) {
         match fi.kind {
             ForeignItemKind::Fn(ref decl, _) => {
-                self.check_fn_decl(decl);
+                self.check_fn_decl(decl, SelfSemantic::No);
                 Self::check_decl_no_pat(decl, |span, _| {
                     struct_span_err!(
                         self.session,
@@ -987,9 +1016,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
             AssocItemKind::Const(_, body) => {
                 self.check_impl_item_provided(ii.span, body, "constant", " = <expr>;");
             }
-            AssocItemKind::Fn(sig, body) => {
+            AssocItemKind::Fn(_, body) => {
                 self.check_impl_item_provided(ii.span, body, "function", " { <body> }");
-                self.check_fn_decl(&sig.decl);
             }
             AssocItemKind::TyAlias(bounds, body) => {
                 self.check_impl_item_provided(ii.span, body, "type", " = <type>;");
@@ -1005,7 +1033,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
         self.check_defaultness(ti.span, ti.defaultness);
 
         if let AssocItemKind::Fn(sig, block) = &ti.kind {
-            self.check_fn_decl(&sig.decl);
             self.check_trait_fn_not_async(ti.span, sig.header.asyncness.node);
             self.check_trait_fn_not_const(sig.header.constness);
             if block.is_none() {
@@ -1035,6 +1062,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
 
     fn visit_assoc_item(&mut self, item: &'a AssocItem) {
         if let AssocItemKind::Fn(sig, _) = &item.kind {
+            self.check_fn_decl(&sig.decl, SelfSemantic::Yes);
             self.check_c_varadic_type(&sig.decl);
         }
         visit::walk_assoc_item(self, item);
diff --git a/src/librustc_parse/parser/diagnostics.rs b/src/librustc_parse/parser/diagnostics.rs
index 80bc5c158a64f..09f393a81abad 100644
--- a/src/librustc_parse/parser/diagnostics.rs
+++ b/src/librustc_parse/parser/diagnostics.rs
@@ -1336,8 +1336,8 @@ impl<'a> Parser<'a> {
         err: &mut DiagnosticBuilder<'_>,
         pat: P<ast::Pat>,
         require_name: bool,
-        is_self_allowed: bool,
-        is_trait_item: bool,
+        is_self_semantic: bool,
+        in_assoc_item: bool,
     ) -> Option<Ident> {
         // If we find a pattern followed by an identifier, it could be an (incorrect)
         // C-style parameter declaration.
@@ -1357,13 +1357,13 @@ impl<'a> Parser<'a> {
             return Some(ident);
         } else if let PatKind::Ident(_, ident, _) = pat.kind {
             if require_name
-                && (is_trait_item
+                && (in_assoc_item
                     || self.token == token::Comma
                     || self.token == token::Lt
                     || self.token == token::CloseDelim(token::Paren))
             {
                 // `fn foo(a, b) {}`, `fn foo(a<x>, b<y>) {}` or `fn foo(usize, usize) {}`
-                if is_self_allowed {
+                if is_self_semantic {
                     err.span_suggestion(
                         pat.span,
                         "if this is a `self` type, give it a parameter name",
@@ -1423,12 +1423,12 @@ impl<'a> Parser<'a> {
     pub(super) fn recover_bad_self_param(
         &mut self,
         mut param: ast::Param,
-        is_trait_item: bool,
+        in_assoc_item: bool,
     ) -> PResult<'a, ast::Param> {
         let sp = param.pat.span;
         param.ty.kind = TyKind::Err;
         let mut err = self.struct_span_err(sp, "unexpected `self` parameter in function");
-        if is_trait_item {
+        if in_assoc_item {
             err.span_label(sp, "must be the first associated function parameter");
         } else {
             err.span_label(sp, "not valid as function parameter");
diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs
index 6611661132306..0ff595f444413 100644
--- a/src/librustc_parse/parser/item.rs
+++ b/src/librustc_parse/parser/item.rs
@@ -1715,8 +1715,9 @@ impl<'a> Parser<'a> {
 
 /// The parsing configuration used to parse a parameter list (see `parse_fn_params`).
 pub(super) struct ParamCfg {
-    /// Is `self` is allowed as the first parameter?
-    pub is_self_allowed: bool,
+    /// Is `self` is *semantically* allowed as the first parameter?
+    /// This is only used for diagnostics.
+    pub in_assoc_item: bool,
     /// `is_name_required` decides if, per-parameter,
     /// the parameter must have a pattern or just a type.
     pub is_name_required: fn(&token::Token) -> bool,
@@ -1732,8 +1733,8 @@ impl<'a> Parser<'a> {
         attrs: Vec<Attribute>,
         header: FnHeader,
     ) -> PResult<'a, Option<P<Item>>> {
-        let (ident, decl, generics) =
-            self.parse_fn_sig(ParamCfg { is_self_allowed: false, is_name_required: |_| true })?;
+        let cfg = ParamCfg { in_assoc_item: false, is_name_required: |_| true };
+        let (ident, decl, generics) = self.parse_fn_sig(&cfg)?;
         let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
         let kind = ItemKind::Fn(FnSig { decl, header }, generics, body);
         self.mk_item_with_info(attrs, lo, vis, (ident, kind, Some(inner_attrs)))
@@ -1747,20 +1748,13 @@ impl<'a> Parser<'a> {
         attrs: Vec<Attribute>,
         extern_sp: Span,
     ) -> PResult<'a, P<ForeignItem>> {
+        let cfg = ParamCfg { in_assoc_item: false, is_name_required: |_| true };
         self.expect_keyword(kw::Fn)?;
-        let (ident, decl, generics) =
-            self.parse_fn_sig(ParamCfg { is_self_allowed: false, is_name_required: |_| true })?;
+        let (ident, decl, generics) = self.parse_fn_sig(&cfg)?;
         let span = lo.to(self.token.span);
         self.parse_semi_or_incorrect_foreign_fn_body(&ident, extern_sp)?;
-        Ok(P(ast::ForeignItem {
-            ident,
-            attrs,
-            kind: ForeignItemKind::Fn(decl, generics),
-            id: DUMMY_NODE_ID,
-            span,
-            vis,
-            tokens: None,
-        }))
+        let kind = ForeignItemKind::Fn(decl, generics);
+        Ok(P(ast::ForeignItem { ident, attrs, kind, id: DUMMY_NODE_ID, span, vis, tokens: None }))
     }
 
     fn parse_assoc_fn(
@@ -1769,9 +1763,9 @@ impl<'a> Parser<'a> {
         attrs: &mut Vec<Attribute>,
         is_name_required: fn(&token::Token) -> bool,
     ) -> PResult<'a, (Ident, AssocItemKind, Generics)> {
+        let cfg = ParamCfg { in_assoc_item: true, is_name_required };
         let header = self.parse_fn_front_matter()?;
-        let (ident, decl, generics) =
-            self.parse_fn_sig(ParamCfg { is_self_allowed: true, is_name_required })?;
+        let (ident, decl, generics) = self.parse_fn_sig(&cfg)?;
         let sig = FnSig { header, decl };
         let body = self.parse_assoc_fn_body(at_end, attrs)?;
         Ok((ident, AssocItemKind::Fn(sig, body), generics))
@@ -1847,7 +1841,7 @@ impl<'a> Parser<'a> {
     }
 
     /// Parse the "signature", including the identifier, parameters, and generics of a function.
-    fn parse_fn_sig(&mut self, cfg: ParamCfg) -> PResult<'a, (Ident, P<FnDecl>, Generics)> {
+    fn parse_fn_sig(&mut self, cfg: &ParamCfg) -> PResult<'a, (Ident, P<FnDecl>, Generics)> {
         let ident = self.parse_ident()?;
         let mut generics = self.parse_generics()?;
         let decl = self.parse_fn_decl(cfg, true)?;
@@ -1858,7 +1852,7 @@ impl<'a> Parser<'a> {
     /// Parses the parameter list and result type of a function declaration.
     pub(super) fn parse_fn_decl(
         &mut self,
-        cfg: ParamCfg,
+        cfg: &ParamCfg,
         ret_allow_plus: bool,
     ) -> PResult<'a, P<FnDecl>> {
         Ok(P(FnDecl {
@@ -1868,11 +1862,11 @@ impl<'a> Parser<'a> {
     }
 
     /// Parses the parameter list of a function, including the `(` and `)` delimiters.
-    fn parse_fn_params(&mut self, mut cfg: ParamCfg) -> PResult<'a, Vec<Param>> {
-        let is_trait_item = cfg.is_self_allowed;
-        // Parse the arguments, starting out with `self` being possibly allowed...
+    fn parse_fn_params(&mut self, cfg: &ParamCfg) -> PResult<'a, Vec<Param>> {
+        let mut first_param = true;
+        // Parse the arguments, starting out with `self` being allowed...
         let (mut params, _) = self.parse_paren_comma_seq(|p| {
-            let param = p.parse_param_general(&cfg, is_trait_item).or_else(|mut e| {
+            let param = p.parse_param_general(&cfg, first_param).or_else(|mut e| {
                 e.emit();
                 let lo = p.prev_span;
                 // Skip every token until next possible arg or end.
@@ -1881,7 +1875,7 @@ impl<'a> Parser<'a> {
                 Ok(dummy_arg(Ident::new(kw::Invalid, lo.to(p.prev_span))))
             });
             // ...now that we've parsed the first argument, `self` is no longer allowed.
-            cfg.is_self_allowed = false;
+            first_param = false;
             param
         })?;
         // Replace duplicated recovered params with `_` pattern to avoid unnecessary errors.
@@ -1889,20 +1883,20 @@ impl<'a> Parser<'a> {
         Ok(params)
     }
 
-    /// Skips unexpected attributes and doc comments in this position and emits an appropriate
-    /// error.
-    /// This version of parse param doesn't necessarily require identifier names.
-    fn parse_param_general(&mut self, cfg: &ParamCfg, is_trait_item: bool) -> PResult<'a, Param> {
+    /// Parses a single function parameter.
+    ///
+    /// - `self` is syntactically allowed when `first_param` holds.
+    fn parse_param_general(&mut self, cfg: &ParamCfg, first_param: bool) -> PResult<'a, Param> {
         let lo = self.token.span;
         let attrs = self.parse_outer_attributes()?;
 
         // Possibly parse `self`. Recover if we parsed it and it wasn't allowed here.
         if let Some(mut param) = self.parse_self_param()? {
             param.attrs = attrs.into();
-            return if cfg.is_self_allowed {
+            return if first_param {
                 Ok(param)
             } else {
-                self.recover_bad_self_param(param, is_trait_item)
+                self.recover_bad_self_param(param, cfg.in_assoc_item)
             };
         }
 
@@ -1919,8 +1913,8 @@ impl<'a> Parser<'a> {
                     &mut err,
                     pat,
                     is_name_required,
-                    cfg.is_self_allowed,
-                    is_trait_item,
+                    first_param && cfg.in_assoc_item,
+                    cfg.in_assoc_item,
                 ) {
                     err.emit();
                     Ok(dummy_arg(ident))
@@ -1975,8 +1969,6 @@ impl<'a> Parser<'a> {
     }
 
     /// Returns the parsed optional self parameter and whether a self shortcut was used.
-    ///
-    /// See `parse_self_param_with_attrs` to collect attributes.
     fn parse_self_param(&mut self) -> PResult<'a, Option<Param>> {
         // Extract an identifier *after* having confirmed that the token is one.
         let expect_self_ident = |this: &mut Self| {
diff --git a/src/librustc_parse/parser/ty.rs b/src/librustc_parse/parser/ty.rs
index a4cc9fa48f2a6..51367a37ad70a 100644
--- a/src/librustc_parse/parser/ty.rs
+++ b/src/librustc_parse/parser/ty.rs
@@ -288,8 +288,8 @@ impl<'a> Parser<'a> {
         let unsafety = self.parse_unsafety();
         let ext = self.parse_extern()?;
         self.expect_keyword(kw::Fn)?;
-        let cfg = ParamCfg { is_self_allowed: false, is_name_required: |_| false };
-        let decl = self.parse_fn_decl(cfg, false)?;
+        let cfg = ParamCfg { in_assoc_item: false, is_name_required: |_| false };
+        let decl = self.parse_fn_decl(&cfg, false)?;
         Ok(TyKind::BareFn(P(BareFnTy { ext, unsafety, generic_params, decl })))
     }
 
diff --git a/src/test/ui/invalid-self-argument/bare-fn-start.rs b/src/test/ui/invalid-self-argument/bare-fn-start.rs
index a003a01941bde..8c92b7bc7c4b0 100644
--- a/src/test/ui/invalid-self-argument/bare-fn-start.rs
+++ b/src/test/ui/invalid-self-argument/bare-fn-start.rs
@@ -1,6 +1,6 @@
 fn a(&self) { }
-//~^ ERROR unexpected `self` parameter in function
-//~| NOTE not valid as function parameter
-//~| NOTE `self` is only valid as the first parameter of an associated function
+//~^ ERROR `self` parameter only allowed in associated `fn`s
+//~| NOTE not semantically valid as function parameter
+//~| NOTE associated `fn`s are those in `impl` or `trait` definitions
 
 fn main() { }
diff --git a/src/test/ui/invalid-self-argument/bare-fn-start.stderr b/src/test/ui/invalid-self-argument/bare-fn-start.stderr
index 23de6502094f0..59120a60a6df1 100644
--- a/src/test/ui/invalid-self-argument/bare-fn-start.stderr
+++ b/src/test/ui/invalid-self-argument/bare-fn-start.stderr
@@ -1,10 +1,10 @@
-error: unexpected `self` parameter in function
+error: `self` parameter only allowed in associated `fn`s
   --> $DIR/bare-fn-start.rs:1:6
    |
 LL | fn a(&self) { }
-   |      ^^^^^ not valid as function parameter
+   |      ^^^^^ not semantically valid as function parameter
    |
-   = note: `self` is only valid as the first parameter of an associated function
+   = note: associated `fn`s are those in `impl` or `trait` definitions
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/self-param-semantic-fail.rs b/src/test/ui/parser/self-param-semantic-fail.rs
new file mode 100644
index 0000000000000..773cf922b4da9
--- /dev/null
+++ b/src/test/ui/parser/self-param-semantic-fail.rs
@@ -0,0 +1,64 @@
+// This test ensures that `self` is semantically rejected
+// in contexts with `FnDecl` but outside of associated `fn`s.
+// FIXME(Centril): For now closures are an exception.
+
+fn main() {}
+
+fn free() {
+    fn f1(self) {}
+    //~^ ERROR `self` parameter only allowed in associated `fn`s
+    fn f2(mut self) {}
+    //~^ ERROR `self` parameter only allowed in associated `fn`s
+    fn f3(&self) {}
+    //~^ ERROR `self` parameter only allowed in associated `fn`s
+    fn f4(&mut self) {}
+    //~^ ERROR `self` parameter only allowed in associated `fn`s
+    fn f5<'a>(&'a self) {}
+    //~^ ERROR `self` parameter only allowed in associated `fn`s
+    fn f6<'a>(&'a mut self) {}
+    //~^ ERROR `self` parameter only allowed in associated `fn`s
+    fn f7(self: u8) {}
+    //~^ ERROR `self` parameter only allowed in associated `fn`s
+    fn f8(mut self: u8) {}
+    //~^ ERROR `self` parameter only allowed in associated `fn`s
+}
+
+extern {
+    fn f1(self);
+    //~^ ERROR `self` parameter only allowed in associated `fn`s
+    fn f2(mut self);
+    //~^ ERROR `self` parameter only allowed in associated `fn`s
+    //~| ERROR patterns aren't allowed in
+    fn f3(&self);
+    //~^ ERROR `self` parameter only allowed in associated `fn`s
+    fn f4(&mut self);
+    //~^ ERROR `self` parameter only allowed in associated `fn`s
+    fn f5<'a>(&'a self);
+    //~^ ERROR `self` parameter only allowed in associated `fn`s
+    fn f6<'a>(&'a mut self);
+    //~^ ERROR `self` parameter only allowed in associated `fn`s
+    fn f7(self: u8);
+    //~^ ERROR `self` parameter only allowed in associated `fn`s
+    fn f8(mut self: u8);
+    //~^ ERROR `self` parameter only allowed in associated `fn`s
+    //~| ERROR patterns aren't allowed in
+}
+
+type X1 = fn(self);
+//~^ ERROR `self` parameter only allowed in associated `fn`s
+type X2 = fn(mut self);
+//~^ ERROR `self` parameter only allowed in associated `fn`s
+//~| ERROR patterns aren't allowed in
+type X3 = fn(&self);
+//~^ ERROR `self` parameter only allowed in associated `fn`s
+type X4 = fn(&mut self);
+//~^ ERROR `self` parameter only allowed in associated `fn`s
+type X5 = for<'a> fn(&'a self);
+//~^ ERROR `self` parameter only allowed in associated `fn`s
+type X6 = for<'a> fn(&'a mut self);
+//~^ ERROR `self` parameter only allowed in associated `fn`s
+type X7 = fn(self: u8);
+//~^ ERROR `self` parameter only allowed in associated `fn`s
+type X8 = fn(mut self: u8);
+//~^ ERROR `self` parameter only allowed in associated `fn`s
+//~| ERROR patterns aren't allowed in
diff --git a/src/test/ui/parser/self-param-semantic-fail.stderr b/src/test/ui/parser/self-param-semantic-fail.stderr
new file mode 100644
index 0000000000000..b45e4a5d26f16
--- /dev/null
+++ b/src/test/ui/parser/self-param-semantic-fail.stderr
@@ -0,0 +1,220 @@
+error: `self` parameter only allowed in associated `fn`s
+  --> $DIR/self-param-semantic-fail.rs:8:11
+   |
+LL |     fn f1(self) {}
+   |           ^^^^ not semantically valid as function parameter
+   |
+   = note: associated `fn`s are those in `impl` or `trait` definitions
+
+error: `self` parameter only allowed in associated `fn`s
+  --> $DIR/self-param-semantic-fail.rs:10:11
+   |
+LL |     fn f2(mut self) {}
+   |           ^^^^^^^^ not semantically valid as function parameter
+   |
+   = note: associated `fn`s are those in `impl` or `trait` definitions
+
+error: `self` parameter only allowed in associated `fn`s
+  --> $DIR/self-param-semantic-fail.rs:12:11
+   |
+LL |     fn f3(&self) {}
+   |           ^^^^^ not semantically valid as function parameter
+   |
+   = note: associated `fn`s are those in `impl` or `trait` definitions
+
+error: `self` parameter only allowed in associated `fn`s
+  --> $DIR/self-param-semantic-fail.rs:14:11
+   |
+LL |     fn f4(&mut self) {}
+   |           ^^^^^^^^^ not semantically valid as function parameter
+   |
+   = note: associated `fn`s are those in `impl` or `trait` definitions
+
+error: `self` parameter only allowed in associated `fn`s
+  --> $DIR/self-param-semantic-fail.rs:16:15
+   |
+LL |     fn f5<'a>(&'a self) {}
+   |               ^^^^^^^^ not semantically valid as function parameter
+   |
+   = note: associated `fn`s are those in `impl` or `trait` definitions
+
+error: `self` parameter only allowed in associated `fn`s
+  --> $DIR/self-param-semantic-fail.rs:18:15
+   |
+LL |     fn f6<'a>(&'a mut self) {}
+   |               ^^^^^^^^^^^^ not semantically valid as function parameter
+   |
+   = note: associated `fn`s are those in `impl` or `trait` definitions
+
+error: `self` parameter only allowed in associated `fn`s
+  --> $DIR/self-param-semantic-fail.rs:20:11
+   |
+LL |     fn f7(self: u8) {}
+   |           ^^^^ not semantically valid as function parameter
+   |
+   = note: associated `fn`s are those in `impl` or `trait` definitions
+
+error: `self` parameter only allowed in associated `fn`s
+  --> $DIR/self-param-semantic-fail.rs:22:11
+   |
+LL |     fn f8(mut self: u8) {}
+   |           ^^^^^^^^ not semantically valid as function parameter
+   |
+   = note: associated `fn`s are those in `impl` or `trait` definitions
+
+error: `self` parameter only allowed in associated `fn`s
+  --> $DIR/self-param-semantic-fail.rs:27:11
+   |
+LL |     fn f1(self);
+   |           ^^^^ not semantically valid as function parameter
+   |
+   = note: associated `fn`s are those in `impl` or `trait` definitions
+
+error: `self` parameter only allowed in associated `fn`s
+  --> $DIR/self-param-semantic-fail.rs:29:11
+   |
+LL |     fn f2(mut self);
+   |           ^^^^^^^^ not semantically valid as function parameter
+   |
+   = note: associated `fn`s are those in `impl` or `trait` definitions
+
+error[E0130]: patterns aren't allowed in foreign function declarations
+  --> $DIR/self-param-semantic-fail.rs:29:11
+   |
+LL |     fn f2(mut self);
+   |           ^^^^^^^^ pattern not allowed in foreign function
+
+error: `self` parameter only allowed in associated `fn`s
+  --> $DIR/self-param-semantic-fail.rs:32:11
+   |
+LL |     fn f3(&self);
+   |           ^^^^^ not semantically valid as function parameter
+   |
+   = note: associated `fn`s are those in `impl` or `trait` definitions
+
+error: `self` parameter only allowed in associated `fn`s
+  --> $DIR/self-param-semantic-fail.rs:34:11
+   |
+LL |     fn f4(&mut self);
+   |           ^^^^^^^^^ not semantically valid as function parameter
+   |
+   = note: associated `fn`s are those in `impl` or `trait` definitions
+
+error: `self` parameter only allowed in associated `fn`s
+  --> $DIR/self-param-semantic-fail.rs:36:15
+   |
+LL |     fn f5<'a>(&'a self);
+   |               ^^^^^^^^ not semantically valid as function parameter
+   |
+   = note: associated `fn`s are those in `impl` or `trait` definitions
+
+error: `self` parameter only allowed in associated `fn`s
+  --> $DIR/self-param-semantic-fail.rs:38:15
+   |
+LL |     fn f6<'a>(&'a mut self);
+   |               ^^^^^^^^^^^^ not semantically valid as function parameter
+   |
+   = note: associated `fn`s are those in `impl` or `trait` definitions
+
+error: `self` parameter only allowed in associated `fn`s
+  --> $DIR/self-param-semantic-fail.rs:40:11
+   |
+LL |     fn f7(self: u8);
+   |           ^^^^ not semantically valid as function parameter
+   |
+   = note: associated `fn`s are those in `impl` or `trait` definitions
+
+error: `self` parameter only allowed in associated `fn`s
+  --> $DIR/self-param-semantic-fail.rs:42:11
+   |
+LL |     fn f8(mut self: u8);
+   |           ^^^^^^^^ not semantically valid as function parameter
+   |
+   = note: associated `fn`s are those in `impl` or `trait` definitions
+
+error[E0130]: patterns aren't allowed in foreign function declarations
+  --> $DIR/self-param-semantic-fail.rs:42:11
+   |
+LL |     fn f8(mut self: u8);
+   |           ^^^^^^^^ pattern not allowed in foreign function
+
+error: `self` parameter only allowed in associated `fn`s
+  --> $DIR/self-param-semantic-fail.rs:47:14
+   |
+LL | type X1 = fn(self);
+   |              ^^^^ not semantically valid as function parameter
+   |
+   = note: associated `fn`s are those in `impl` or `trait` definitions
+
+error: `self` parameter only allowed in associated `fn`s
+  --> $DIR/self-param-semantic-fail.rs:49:14
+   |
+LL | type X2 = fn(mut self);
+   |              ^^^^^^^^ not semantically valid as function parameter
+   |
+   = note: associated `fn`s are those in `impl` or `trait` definitions
+
+error[E0561]: patterns aren't allowed in function pointer types
+  --> $DIR/self-param-semantic-fail.rs:49:14
+   |
+LL | type X2 = fn(mut self);
+   |              ^^^^^^^^
+
+error: `self` parameter only allowed in associated `fn`s
+  --> $DIR/self-param-semantic-fail.rs:52:14
+   |
+LL | type X3 = fn(&self);
+   |              ^^^^^ not semantically valid as function parameter
+   |
+   = note: associated `fn`s are those in `impl` or `trait` definitions
+
+error: `self` parameter only allowed in associated `fn`s
+  --> $DIR/self-param-semantic-fail.rs:54:14
+   |
+LL | type X4 = fn(&mut self);
+   |              ^^^^^^^^^ not semantically valid as function parameter
+   |
+   = note: associated `fn`s are those in `impl` or `trait` definitions
+
+error: `self` parameter only allowed in associated `fn`s
+  --> $DIR/self-param-semantic-fail.rs:56:22
+   |
+LL | type X5 = for<'a> fn(&'a self);
+   |                      ^^^^^^^^ not semantically valid as function parameter
+   |
+   = note: associated `fn`s are those in `impl` or `trait` definitions
+
+error: `self` parameter only allowed in associated `fn`s
+  --> $DIR/self-param-semantic-fail.rs:58:22
+   |
+LL | type X6 = for<'a> fn(&'a mut self);
+   |                      ^^^^^^^^^^^^ not semantically valid as function parameter
+   |
+   = note: associated `fn`s are those in `impl` or `trait` definitions
+
+error: `self` parameter only allowed in associated `fn`s
+  --> $DIR/self-param-semantic-fail.rs:60:14
+   |
+LL | type X7 = fn(self: u8);
+   |              ^^^^ not semantically valid as function parameter
+   |
+   = note: associated `fn`s are those in `impl` or `trait` definitions
+
+error: `self` parameter only allowed in associated `fn`s
+  --> $DIR/self-param-semantic-fail.rs:62:14
+   |
+LL | type X8 = fn(mut self: u8);
+   |              ^^^^^^^^ not semantically valid as function parameter
+   |
+   = note: associated `fn`s are those in `impl` or `trait` definitions
+
+error[E0561]: patterns aren't allowed in function pointer types
+  --> $DIR/self-param-semantic-fail.rs:62:14
+   |
+LL | type X8 = fn(mut self: u8);
+   |              ^^^^^^^^
+
+error: aborting due to 28 previous errors
+
+Some errors have detailed explanations: E0130, E0561.
+For more information about an error, try `rustc --explain E0130`.
diff --git a/src/test/ui/parser/self-param-syntactic-pass.rs b/src/test/ui/parser/self-param-syntactic-pass.rs
new file mode 100644
index 0000000000000..9e215e6cdd4b7
--- /dev/null
+++ b/src/test/ui/parser/self-param-syntactic-pass.rs
@@ -0,0 +1,66 @@
+// This test ensures that `self` is syntactically accepted in all places an `FnDecl` is parsed.
+// FIXME(Centril): For now closures are an exception.
+
+// check-pass
+
+fn main() {}
+
+#[cfg(FALSE)]
+fn free() {
+    fn f(self) {}
+    fn f(mut self) {}
+    fn f(&self) {}
+    fn f(&mut self) {}
+    fn f(&'a self) {}
+    fn f(&'a mut self) {}
+    fn f(self: u8) {}
+    fn f(mut self: u8) {}
+}
+
+#[cfg(FALSE)]
+extern {
+    fn f(self);
+    fn f(mut self);
+    fn f(&self);
+    fn f(&mut self);
+    fn f(&'a self);
+    fn f(&'a mut self);
+    fn f(self: u8);
+    fn f(mut self: u8);
+}
+
+#[cfg(FALSE)]
+trait X {
+    fn f(self) {}
+    fn f(mut self) {}
+    fn f(&self) {}
+    fn f(&mut self) {}
+    fn f(&'a self) {}
+    fn f(&'a mut self) {}
+    fn f(self: u8) {}
+    fn f(mut self: u8) {}
+}
+
+#[cfg(FALSE)]
+impl X for Y {
+    fn f(self) {}
+    fn f(mut self) {}
+    fn f(&self) {}
+    fn f(&mut self) {}
+    fn f(&'a self) {}
+    fn f(&'a mut self) {}
+    fn f(self: u8) {}
+    fn f(mut self: u8) {}
+}
+
+#[cfg(FALSE)]
+impl X for Y {
+    type X = fn(self);
+    type X = fn(mut self);
+    type X = fn(&self);
+    type X = fn(&mut self);
+    type X = fn(&'a self);
+    type X = fn(&'a mut self);
+    type X = fn(self: u8);
+    type X = fn(mut self: u8);
+}

From 56ad8bcfe0025618d35c8479797bca5d05e81099 Mon Sep 17 00:00:00 2001
From: Yuki Okushi <huyuumi.dev@gmail.com>
Date: Sun, 2 Feb 2020 17:55:11 +0900
Subject: [PATCH 4/5] Do not suggest duplicate bounds

---
 src/librustc_typeck/check/method/suggest.rs   | 42 ++++++++++---------
 .../associated-item-duplicate-bounds.rs       | 11 +++++
 .../associated-item-duplicate-bounds.stderr   | 11 +++++
 src/test/ui/issues/issue-39559.stderr         |  4 --
 src/test/ui/span/issue-7575.stderr            | 13 ++----
 5 files changed, 49 insertions(+), 32 deletions(-)
 create mode 100644 src/test/ui/associated-item/associated-item-duplicate-bounds.rs
 create mode 100644 src/test/ui/associated-item/associated-item-duplicate-bounds.stderr

diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index e9942fad3bc64..490c69b55362b 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -853,26 +853,30 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                 } else {
                                     sp
                                 };
-                                // FIXME: contrast `t.def_id` against `param.bounds` to not suggest
-                                // traits already there. That can happen when the cause is that
-                                // we're in a const scope or associated function used as a method.
-                                err.span_suggestions(
-                                    sp,
-                                    &message(format!(
-                                        "restrict type parameter `{}` with",
-                                        param.name.ident(),
-                                    )),
-                                    candidates.iter().map(|t| {
-                                        format!(
-                                            "{}{} {}{}",
+                                let trait_def_ids: FxHashSet<DefId> = param
+                                    .bounds
+                                    .iter()
+                                    .filter_map(|bound| bound.trait_def_id())
+                                    .collect();
+                                if !candidates.iter().any(|t| trait_def_ids.contains(&t.def_id)) {
+                                    err.span_suggestions(
+                                        sp,
+                                        &message(format!(
+                                            "restrict type parameter `{}` with",
                                             param.name.ident(),
-                                            if impl_trait { " +" } else { ":" },
-                                            self.tcx.def_path_str(t.def_id),
-                                            if has_bounds.is_some() { " + " } else { "" },
-                                        )
-                                    }),
-                                    Applicability::MaybeIncorrect,
-                                );
+                                        )),
+                                        candidates.iter().map(|t| {
+                                            format!(
+                                                "{}{} {}{}",
+                                                param.name.ident(),
+                                                if impl_trait { " +" } else { ":" },
+                                                self.tcx.def_path_str(t.def_id),
+                                                if has_bounds.is_some() { " + " } else { "" },
+                                            )
+                                        }),
+                                        Applicability::MaybeIncorrect,
+                                    );
+                                }
                                 suggested = true;
                             }
                             Node::Item(hir::Item {
diff --git a/src/test/ui/associated-item/associated-item-duplicate-bounds.rs b/src/test/ui/associated-item/associated-item-duplicate-bounds.rs
new file mode 100644
index 0000000000000..bec922b0721b9
--- /dev/null
+++ b/src/test/ui/associated-item/associated-item-duplicate-bounds.rs
@@ -0,0 +1,11 @@
+trait Adapter {
+    const LINKS: usize;
+}
+
+struct Foo<A: Adapter> {
+    adapter: A,
+    links: [u32; A::LINKS], // Shouldn't suggest bounds already there.
+    //~^ ERROR: no associated item named `LINKS` found
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-item/associated-item-duplicate-bounds.stderr b/src/test/ui/associated-item/associated-item-duplicate-bounds.stderr
new file mode 100644
index 0000000000000..ff1ad4c006e78
--- /dev/null
+++ b/src/test/ui/associated-item/associated-item-duplicate-bounds.stderr
@@ -0,0 +1,11 @@
+error[E0599]: no associated item named `LINKS` found for type parameter `A` in the current scope
+  --> $DIR/associated-item-duplicate-bounds.rs:7:21
+   |
+LL |     links: [u32; A::LINKS], // Shouldn't suggest bounds already there.
+   |                     ^^^^^ associated item not found in `A`
+   |
+   = help: items from traits can only be used if the type parameter is bounded by the trait
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/src/test/ui/issues/issue-39559.stderr b/src/test/ui/issues/issue-39559.stderr
index 0554b232c248b..5e8d487f41658 100644
--- a/src/test/ui/issues/issue-39559.stderr
+++ b/src/test/ui/issues/issue-39559.stderr
@@ -5,10 +5,6 @@ LL |     entries: [T; D::dim()],
    |                     ^^^ function or associated item not found in `D`
    |
    = help: items from traits can only be used if the type parameter is bounded by the trait
-help: the following trait defines an item `dim`, perhaps you need to restrict type parameter `D` with it:
-   |
-LL | pub struct Vector<T, D: Dim + Dim> {
-   |                      ^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/span/issue-7575.stderr b/src/test/ui/span/issue-7575.stderr
index eb85be039ba04..89b36848a2897 100644
--- a/src/test/ui/span/issue-7575.stderr
+++ b/src/test/ui/span/issue-7575.stderr
@@ -61,7 +61,10 @@ error[E0599]: no method named `is_str` found for type parameter `T` in the curre
   --> $DIR/issue-7575.rs:70:7
    |
 LL |     t.is_str()
-   |       ^^^^^^ this is an associated function, not a method
+   |     --^^^^^^--
+   |     | |
+   |     | this is an associated function, not a method
+   |     help: disambiguate the method call for the candidate: `ManyImplTrait::is_str(t)`
    |
    = note: found the following associated functions; to be used as methods, functions must have a `self` parameter
 note: the candidate is defined in the trait `ManyImplTrait`
@@ -70,14 +73,6 @@ note: the candidate is defined in the trait `ManyImplTrait`
 LL |     fn is_str() -> bool {
    |     ^^^^^^^^^^^^^^^^^^^
    = help: items from traits can only be used if the type parameter is bounded by the trait
-help: disambiguate the method call for the candidate
-   |
-LL |     ManyImplTrait::is_str(t)
-   |
-help: the following trait defines an item `is_str`, perhaps you need to restrict type parameter `T` with it:
-   |
-LL | fn param_bound<T: ManyImplTrait + ManyImplTrait>(t: T) -> bool {
-   |                ^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 3 previous errors
 

From 71a6f58229c00720b35579856bdb64e2a19af521 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sun, 2 Feb 2020 11:10:27 +0100
Subject: [PATCH 5/5] parser: address review comments re. `self`.

---
 src/librustc_ast_passes/ast_validation.rs     |  4 +-
 src/librustc_parse/parser/diagnostics.rs      | 25 ++---
 src/librustc_parse/parser/item.rs             | 26 ++---
 src/librustc_parse/parser/ty.rs               |  3 +-
 .../ui/invalid-self-argument/bare-fn-start.rs |  4 +-
 .../bare-fn-start.stderr                      |  4 +-
 src/test/ui/invalid-self-argument/bare-fn.rs  |  3 +-
 .../ui/invalid-self-argument/bare-fn.stderr   |  4 +-
 src/test/ui/invalid-self-argument/trait-fn.rs |  2 +-
 .../ui/invalid-self-argument/trait-fn.stderr  |  2 +-
 src/test/ui/parser/inverted-parameters.rs     |  1 +
 src/test/ui/parser/inverted-parameters.stderr |  6 +-
 .../ui/parser/omitted-arg-in-item-fn.stderr   |  4 +
 src/test/ui/parser/pat-lt-bracket-2.stderr    |  4 +
 .../ui/parser/self-in-function-arg.stderr     |  4 +-
 .../ui/parser/self-param-semantic-fail.rs     | 48 +++++-----
 .../ui/parser/self-param-semantic-fail.stderr | 96 +++++++++----------
 src/test/ui/span/issue-34264.stderr           |  8 ++
 .../suggestions/issue-64252-self-type.stderr  |  4 +
 19 files changed, 124 insertions(+), 128 deletions(-)

diff --git a/src/librustc_ast_passes/ast_validation.rs b/src/librustc_ast_passes/ast_validation.rs
index f37f93c0254bd..23c5ef9b3d652 100644
--- a/src/librustc_ast_passes/ast_validation.rs
+++ b/src/librustc_ast_passes/ast_validation.rs
@@ -372,10 +372,10 @@ impl<'a> AstValidator<'a> {
                 self.err_handler()
                     .struct_span_err(
                         param.span,
-                        "`self` parameter only allowed in associated `fn`s",
+                        "`self` parameter is only allowed in associated functions",
                     )
                     .span_label(param.span, "not semantically valid as function parameter")
-                    .note("associated `fn`s are those in `impl` or `trait` definitions")
+                    .note("associated functions are those in `impl` or `trait` definitions")
                     .emit();
             }
         }
diff --git a/src/librustc_parse/parser/diagnostics.rs b/src/librustc_parse/parser/diagnostics.rs
index 09f393a81abad..4f259d314fbf1 100644
--- a/src/librustc_parse/parser/diagnostics.rs
+++ b/src/librustc_parse/parser/diagnostics.rs
@@ -1336,8 +1336,7 @@ impl<'a> Parser<'a> {
         err: &mut DiagnosticBuilder<'_>,
         pat: P<ast::Pat>,
         require_name: bool,
-        is_self_semantic: bool,
-        in_assoc_item: bool,
+        first_param: bool,
     ) -> Option<Ident> {
         // If we find a pattern followed by an identifier, it could be an (incorrect)
         // C-style parameter declaration.
@@ -1357,13 +1356,12 @@ impl<'a> Parser<'a> {
             return Some(ident);
         } else if let PatKind::Ident(_, ident, _) = pat.kind {
             if require_name
-                && (in_assoc_item
-                    || self.token == token::Comma
+                && (self.token == token::Comma
                     || self.token == token::Lt
                     || self.token == token::CloseDelim(token::Paren))
             {
                 // `fn foo(a, b) {}`, `fn foo(a<x>, b<y>) {}` or `fn foo(usize, usize) {}`
-                if is_self_semantic {
+                if first_param {
                     err.span_suggestion(
                         pat.span,
                         "if this is a `self` type, give it a parameter name",
@@ -1420,21 +1418,12 @@ impl<'a> Parser<'a> {
         Ok((pat, ty))
     }
 
-    pub(super) fn recover_bad_self_param(
-        &mut self,
-        mut param: ast::Param,
-        in_assoc_item: bool,
-    ) -> PResult<'a, ast::Param> {
+    pub(super) fn recover_bad_self_param(&mut self, mut param: Param) -> PResult<'a, Param> {
         let sp = param.pat.span;
         param.ty.kind = TyKind::Err;
-        let mut err = self.struct_span_err(sp, "unexpected `self` parameter in function");
-        if in_assoc_item {
-            err.span_label(sp, "must be the first associated function parameter");
-        } else {
-            err.span_label(sp, "not valid as function parameter");
-            err.note("`self` is only valid as the first parameter of an associated function");
-        }
-        err.emit();
+        self.struct_span_err(sp, "unexpected `self` parameter in function")
+            .span_label(sp, "must be the first parameter of an associated function")
+            .emit();
         Ok(param)
     }
 
diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs
index 0ff595f444413..da5cc0bb83e35 100644
--- a/src/librustc_parse/parser/item.rs
+++ b/src/librustc_parse/parser/item.rs
@@ -1715,9 +1715,6 @@ impl<'a> Parser<'a> {
 
 /// The parsing configuration used to parse a parameter list (see `parse_fn_params`).
 pub(super) struct ParamCfg {
-    /// Is `self` is *semantically* allowed as the first parameter?
-    /// This is only used for diagnostics.
-    pub in_assoc_item: bool,
     /// `is_name_required` decides if, per-parameter,
     /// the parameter must have a pattern or just a type.
     pub is_name_required: fn(&token::Token) -> bool,
@@ -1733,7 +1730,7 @@ impl<'a> Parser<'a> {
         attrs: Vec<Attribute>,
         header: FnHeader,
     ) -> PResult<'a, Option<P<Item>>> {
-        let cfg = ParamCfg { in_assoc_item: false, is_name_required: |_| true };
+        let cfg = ParamCfg { is_name_required: |_| true };
         let (ident, decl, generics) = self.parse_fn_sig(&cfg)?;
         let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
         let kind = ItemKind::Fn(FnSig { decl, header }, generics, body);
@@ -1748,7 +1745,7 @@ impl<'a> Parser<'a> {
         attrs: Vec<Attribute>,
         extern_sp: Span,
     ) -> PResult<'a, P<ForeignItem>> {
-        let cfg = ParamCfg { in_assoc_item: false, is_name_required: |_| true };
+        let cfg = ParamCfg { is_name_required: |_| true };
         self.expect_keyword(kw::Fn)?;
         let (ident, decl, generics) = self.parse_fn_sig(&cfg)?;
         let span = lo.to(self.token.span);
@@ -1763,9 +1760,8 @@ impl<'a> Parser<'a> {
         attrs: &mut Vec<Attribute>,
         is_name_required: fn(&token::Token) -> bool,
     ) -> PResult<'a, (Ident, AssocItemKind, Generics)> {
-        let cfg = ParamCfg { in_assoc_item: true, is_name_required };
         let header = self.parse_fn_front_matter()?;
-        let (ident, decl, generics) = self.parse_fn_sig(&cfg)?;
+        let (ident, decl, generics) = self.parse_fn_sig(&ParamCfg { is_name_required })?;
         let sig = FnSig { header, decl };
         let body = self.parse_assoc_fn_body(at_end, attrs)?;
         Ok((ident, AssocItemKind::Fn(sig, body), generics))
@@ -1893,11 +1889,7 @@ impl<'a> Parser<'a> {
         // Possibly parse `self`. Recover if we parsed it and it wasn't allowed here.
         if let Some(mut param) = self.parse_self_param()? {
             param.attrs = attrs.into();
-            return if first_param {
-                Ok(param)
-            } else {
-                self.recover_bad_self_param(param, cfg.in_assoc_item)
-            };
+            return if first_param { Ok(param) } else { self.recover_bad_self_param(param) };
         }
 
         let is_name_required = match self.token.kind {
@@ -1909,13 +1901,9 @@ impl<'a> Parser<'a> {
 
             let pat = self.parse_fn_param_pat()?;
             if let Err(mut err) = self.expect(&token::Colon) {
-                return if let Some(ident) = self.parameter_without_type(
-                    &mut err,
-                    pat,
-                    is_name_required,
-                    first_param && cfg.in_assoc_item,
-                    cfg.in_assoc_item,
-                ) {
+                return if let Some(ident) =
+                    self.parameter_without_type(&mut err, pat, is_name_required, first_param)
+                {
                     err.emit();
                     Ok(dummy_arg(ident))
                 } else {
diff --git a/src/librustc_parse/parser/ty.rs b/src/librustc_parse/parser/ty.rs
index 51367a37ad70a..c9c2cbb98ca40 100644
--- a/src/librustc_parse/parser/ty.rs
+++ b/src/librustc_parse/parser/ty.rs
@@ -288,8 +288,7 @@ impl<'a> Parser<'a> {
         let unsafety = self.parse_unsafety();
         let ext = self.parse_extern()?;
         self.expect_keyword(kw::Fn)?;
-        let cfg = ParamCfg { in_assoc_item: false, is_name_required: |_| false };
-        let decl = self.parse_fn_decl(&cfg, false)?;
+        let decl = self.parse_fn_decl(&ParamCfg { is_name_required: |_| false }, false)?;
         Ok(TyKind::BareFn(P(BareFnTy { ext, unsafety, generic_params, decl })))
     }
 
diff --git a/src/test/ui/invalid-self-argument/bare-fn-start.rs b/src/test/ui/invalid-self-argument/bare-fn-start.rs
index 8c92b7bc7c4b0..7c580bc5a5dea 100644
--- a/src/test/ui/invalid-self-argument/bare-fn-start.rs
+++ b/src/test/ui/invalid-self-argument/bare-fn-start.rs
@@ -1,6 +1,6 @@
 fn a(&self) { }
-//~^ ERROR `self` parameter only allowed in associated `fn`s
+//~^ ERROR `self` parameter is only allowed in associated functions
 //~| NOTE not semantically valid as function parameter
-//~| NOTE associated `fn`s are those in `impl` or `trait` definitions
+//~| NOTE associated functions are those in `impl` or `trait` definitions
 
 fn main() { }
diff --git a/src/test/ui/invalid-self-argument/bare-fn-start.stderr b/src/test/ui/invalid-self-argument/bare-fn-start.stderr
index 59120a60a6df1..37753e61f582a 100644
--- a/src/test/ui/invalid-self-argument/bare-fn-start.stderr
+++ b/src/test/ui/invalid-self-argument/bare-fn-start.stderr
@@ -1,10 +1,10 @@
-error: `self` parameter only allowed in associated `fn`s
+error: `self` parameter is only allowed in associated functions
   --> $DIR/bare-fn-start.rs:1:6
    |
 LL | fn a(&self) { }
    |      ^^^^^ not semantically valid as function parameter
    |
-   = note: associated `fn`s are those in `impl` or `trait` definitions
+   = note: associated functions are those in `impl` or `trait` definitions
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/invalid-self-argument/bare-fn.rs b/src/test/ui/invalid-self-argument/bare-fn.rs
index 73d68e8b7a5ab..342bdc31a7c82 100644
--- a/src/test/ui/invalid-self-argument/bare-fn.rs
+++ b/src/test/ui/invalid-self-argument/bare-fn.rs
@@ -1,6 +1,5 @@
 fn b(foo: u32, &mut self) { }
 //~^ ERROR unexpected `self` parameter in function
-//~| NOTE not valid as function parameter
-//~| NOTE `self` is only valid as the first parameter of an associated function
+//~| NOTE must be the first parameter of an associated function
 
 fn main() { }
diff --git a/src/test/ui/invalid-self-argument/bare-fn.stderr b/src/test/ui/invalid-self-argument/bare-fn.stderr
index 601a51bb4a96a..ff2217b5e80bc 100644
--- a/src/test/ui/invalid-self-argument/bare-fn.stderr
+++ b/src/test/ui/invalid-self-argument/bare-fn.stderr
@@ -2,9 +2,7 @@ error: unexpected `self` parameter in function
   --> $DIR/bare-fn.rs:1:16
    |
 LL | fn b(foo: u32, &mut self) { }
-   |                ^^^^^^^^^ not valid as function parameter
-   |
-   = note: `self` is only valid as the first parameter of an associated function
+   |                ^^^^^^^^^ must be the first parameter of an associated function
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/invalid-self-argument/trait-fn.rs b/src/test/ui/invalid-self-argument/trait-fn.rs
index 1e8220d7b4a78..5ccea589561cb 100644
--- a/src/test/ui/invalid-self-argument/trait-fn.rs
+++ b/src/test/ui/invalid-self-argument/trait-fn.rs
@@ -3,7 +3,7 @@ struct Foo {}
 impl Foo {
     fn c(foo: u32, self) {}
     //~^ ERROR unexpected `self` parameter in function
-    //~| NOTE must be the first associated function parameter
+    //~| NOTE must be the first parameter of an associated function
 
     fn good(&mut self, foo: u32) {}
 }
diff --git a/src/test/ui/invalid-self-argument/trait-fn.stderr b/src/test/ui/invalid-self-argument/trait-fn.stderr
index 96a2251c036b1..b9887af962cbc 100644
--- a/src/test/ui/invalid-self-argument/trait-fn.stderr
+++ b/src/test/ui/invalid-self-argument/trait-fn.stderr
@@ -2,7 +2,7 @@ error: unexpected `self` parameter in function
   --> $DIR/trait-fn.rs:4:20
    |
 LL |     fn c(foo: u32, self) {}
-   |                    ^^^^ must be the first associated function parameter
+   |                    ^^^^ must be the first parameter of an associated function
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/inverted-parameters.rs b/src/test/ui/parser/inverted-parameters.rs
index d6efc8be072bd..6f19ee9c7dc0d 100644
--- a/src/test/ui/parser/inverted-parameters.rs
+++ b/src/test/ui/parser/inverted-parameters.rs
@@ -21,6 +21,7 @@ fn pattern((i32, i32) (a, b)) {}
 fn fizz(i32) {}
 //~^ ERROR expected one of `:`, `@`
 //~| HELP if this was a parameter name, give it a type
+//~| HELP if this is a `self` type, give it a parameter name
 //~| HELP if this is a type, explicitly ignore the parameter name
 
 fn missing_colon(quux S) {}
diff --git a/src/test/ui/parser/inverted-parameters.stderr b/src/test/ui/parser/inverted-parameters.stderr
index 51e9087ffc1e1..043ff65f74e1a 100644
--- a/src/test/ui/parser/inverted-parameters.stderr
+++ b/src/test/ui/parser/inverted-parameters.stderr
@@ -35,6 +35,10 @@ LL | fn fizz(i32) {}
    |            ^ expected one of `:`, `@`, or `|`
    |
    = note: anonymous parameters are removed in the 2018 edition (see RFC 1685)
+help: if this is a `self` type, give it a parameter name
+   |
+LL | fn fizz(self: i32) {}
+   |         ^^^^^^^^^
 help: if this was a parameter name, give it a type
    |
 LL | fn fizz(i32: TypeName) {}
@@ -45,7 +49,7 @@ LL | fn fizz(_: i32) {}
    |         ^^^^^^
 
 error: expected one of `:`, `@`, or `|`, found `S`
-  --> $DIR/inverted-parameters.rs:26:23
+  --> $DIR/inverted-parameters.rs:27:23
    |
 LL | fn missing_colon(quux S) {}
    |                  -----^
diff --git a/src/test/ui/parser/omitted-arg-in-item-fn.stderr b/src/test/ui/parser/omitted-arg-in-item-fn.stderr
index c7c76a7f1d42c..9f138bf84ce19 100644
--- a/src/test/ui/parser/omitted-arg-in-item-fn.stderr
+++ b/src/test/ui/parser/omitted-arg-in-item-fn.stderr
@@ -5,6 +5,10 @@ LL | fn foo(x) {
    |         ^ expected one of `:`, `@`, or `|`
    |
    = note: anonymous parameters are removed in the 2018 edition (see RFC 1685)
+help: if this is a `self` type, give it a parameter name
+   |
+LL | fn foo(self: x) {
+   |        ^^^^^^^
 help: if this was a parameter name, give it a type
    |
 LL | fn foo(x: TypeName) {
diff --git a/src/test/ui/parser/pat-lt-bracket-2.stderr b/src/test/ui/parser/pat-lt-bracket-2.stderr
index e51dd57f9c707..6db9a4a0f15a6 100644
--- a/src/test/ui/parser/pat-lt-bracket-2.stderr
+++ b/src/test/ui/parser/pat-lt-bracket-2.stderr
@@ -5,6 +5,10 @@ LL | fn a(B<) {}
    |       ^ expected one of `:`, `@`, or `|`
    |
    = note: anonymous parameters are removed in the 2018 edition (see RFC 1685)
+help: if this is a `self` type, give it a parameter name
+   |
+LL | fn a(self: B<) {}
+   |      ^^^^^^^
 help: if this is a type, explicitly ignore the parameter name
    |
 LL | fn a(_: B<) {}
diff --git a/src/test/ui/parser/self-in-function-arg.stderr b/src/test/ui/parser/self-in-function-arg.stderr
index f58df9b9e79b3..47d8381b0b1da 100644
--- a/src/test/ui/parser/self-in-function-arg.stderr
+++ b/src/test/ui/parser/self-in-function-arg.stderr
@@ -2,9 +2,7 @@ error: unexpected `self` parameter in function
   --> $DIR/self-in-function-arg.rs:1:15
    |
 LL | fn foo(x:i32, self: i32) -> i32 { self }
-   |               ^^^^ not valid as function parameter
-   |
-   = note: `self` is only valid as the first parameter of an associated function
+   |               ^^^^ must be the first parameter of an associated function
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/self-param-semantic-fail.rs b/src/test/ui/parser/self-param-semantic-fail.rs
index 773cf922b4da9..5676971b01ae4 100644
--- a/src/test/ui/parser/self-param-semantic-fail.rs
+++ b/src/test/ui/parser/self-param-semantic-fail.rs
@@ -6,59 +6,59 @@ fn main() {}
 
 fn free() {
     fn f1(self) {}
-    //~^ ERROR `self` parameter only allowed in associated `fn`s
+    //~^ ERROR `self` parameter is only allowed in associated functions
     fn f2(mut self) {}
-    //~^ ERROR `self` parameter only allowed in associated `fn`s
+    //~^ ERROR `self` parameter is only allowed in associated functions
     fn f3(&self) {}
-    //~^ ERROR `self` parameter only allowed in associated `fn`s
+    //~^ ERROR `self` parameter is only allowed in associated functions
     fn f4(&mut self) {}
-    //~^ ERROR `self` parameter only allowed in associated `fn`s
+    //~^ ERROR `self` parameter is only allowed in associated functions
     fn f5<'a>(&'a self) {}
-    //~^ ERROR `self` parameter only allowed in associated `fn`s
+    //~^ ERROR `self` parameter is only allowed in associated functions
     fn f6<'a>(&'a mut self) {}
-    //~^ ERROR `self` parameter only allowed in associated `fn`s
+    //~^ ERROR `self` parameter is only allowed in associated functions
     fn f7(self: u8) {}
-    //~^ ERROR `self` parameter only allowed in associated `fn`s
+    //~^ ERROR `self` parameter is only allowed in associated functions
     fn f8(mut self: u8) {}
-    //~^ ERROR `self` parameter only allowed in associated `fn`s
+    //~^ ERROR `self` parameter is only allowed in associated functions
 }
 
 extern {
     fn f1(self);
-    //~^ ERROR `self` parameter only allowed in associated `fn`s
+    //~^ ERROR `self` parameter is only allowed in associated functions
     fn f2(mut self);
-    //~^ ERROR `self` parameter only allowed in associated `fn`s
+    //~^ ERROR `self` parameter is only allowed in associated functions
     //~| ERROR patterns aren't allowed in
     fn f3(&self);
-    //~^ ERROR `self` parameter only allowed in associated `fn`s
+    //~^ ERROR `self` parameter is only allowed in associated functions
     fn f4(&mut self);
-    //~^ ERROR `self` parameter only allowed in associated `fn`s
+    //~^ ERROR `self` parameter is only allowed in associated functions
     fn f5<'a>(&'a self);
-    //~^ ERROR `self` parameter only allowed in associated `fn`s
+    //~^ ERROR `self` parameter is only allowed in associated functions
     fn f6<'a>(&'a mut self);
-    //~^ ERROR `self` parameter only allowed in associated `fn`s
+    //~^ ERROR `self` parameter is only allowed in associated functions
     fn f7(self: u8);
-    //~^ ERROR `self` parameter only allowed in associated `fn`s
+    //~^ ERROR `self` parameter is only allowed in associated functions
     fn f8(mut self: u8);
-    //~^ ERROR `self` parameter only allowed in associated `fn`s
+    //~^ ERROR `self` parameter is only allowed in associated functions
     //~| ERROR patterns aren't allowed in
 }
 
 type X1 = fn(self);
-//~^ ERROR `self` parameter only allowed in associated `fn`s
+//~^ ERROR `self` parameter is only allowed in associated functions
 type X2 = fn(mut self);
-//~^ ERROR `self` parameter only allowed in associated `fn`s
+//~^ ERROR `self` parameter is only allowed in associated functions
 //~| ERROR patterns aren't allowed in
 type X3 = fn(&self);
-//~^ ERROR `self` parameter only allowed in associated `fn`s
+//~^ ERROR `self` parameter is only allowed in associated functions
 type X4 = fn(&mut self);
-//~^ ERROR `self` parameter only allowed in associated `fn`s
+//~^ ERROR `self` parameter is only allowed in associated functions
 type X5 = for<'a> fn(&'a self);
-//~^ ERROR `self` parameter only allowed in associated `fn`s
+//~^ ERROR `self` parameter is only allowed in associated functions
 type X6 = for<'a> fn(&'a mut self);
-//~^ ERROR `self` parameter only allowed in associated `fn`s
+//~^ ERROR `self` parameter is only allowed in associated functions
 type X7 = fn(self: u8);
-//~^ ERROR `self` parameter only allowed in associated `fn`s
+//~^ ERROR `self` parameter is only allowed in associated functions
 type X8 = fn(mut self: u8);
-//~^ ERROR `self` parameter only allowed in associated `fn`s
+//~^ ERROR `self` parameter is only allowed in associated functions
 //~| ERROR patterns aren't allowed in
diff --git a/src/test/ui/parser/self-param-semantic-fail.stderr b/src/test/ui/parser/self-param-semantic-fail.stderr
index b45e4a5d26f16..e5d679773696b 100644
--- a/src/test/ui/parser/self-param-semantic-fail.stderr
+++ b/src/test/ui/parser/self-param-semantic-fail.stderr
@@ -1,82 +1,82 @@
-error: `self` parameter only allowed in associated `fn`s
+error: `self` parameter is only allowed in associated functions
   --> $DIR/self-param-semantic-fail.rs:8:11
    |
 LL |     fn f1(self) {}
    |           ^^^^ not semantically valid as function parameter
    |
-   = note: associated `fn`s are those in `impl` or `trait` definitions
+   = note: associated functions are those in `impl` or `trait` definitions
 
-error: `self` parameter only allowed in associated `fn`s
+error: `self` parameter is only allowed in associated functions
   --> $DIR/self-param-semantic-fail.rs:10:11
    |
 LL |     fn f2(mut self) {}
    |           ^^^^^^^^ not semantically valid as function parameter
    |
-   = note: associated `fn`s are those in `impl` or `trait` definitions
+   = note: associated functions are those in `impl` or `trait` definitions
 
-error: `self` parameter only allowed in associated `fn`s
+error: `self` parameter is only allowed in associated functions
   --> $DIR/self-param-semantic-fail.rs:12:11
    |
 LL |     fn f3(&self) {}
    |           ^^^^^ not semantically valid as function parameter
    |
-   = note: associated `fn`s are those in `impl` or `trait` definitions
+   = note: associated functions are those in `impl` or `trait` definitions
 
-error: `self` parameter only allowed in associated `fn`s
+error: `self` parameter is only allowed in associated functions
   --> $DIR/self-param-semantic-fail.rs:14:11
    |
 LL |     fn f4(&mut self) {}
    |           ^^^^^^^^^ not semantically valid as function parameter
    |
-   = note: associated `fn`s are those in `impl` or `trait` definitions
+   = note: associated functions are those in `impl` or `trait` definitions
 
-error: `self` parameter only allowed in associated `fn`s
+error: `self` parameter is only allowed in associated functions
   --> $DIR/self-param-semantic-fail.rs:16:15
    |
 LL |     fn f5<'a>(&'a self) {}
    |               ^^^^^^^^ not semantically valid as function parameter
    |
-   = note: associated `fn`s are those in `impl` or `trait` definitions
+   = note: associated functions are those in `impl` or `trait` definitions
 
-error: `self` parameter only allowed in associated `fn`s
+error: `self` parameter is only allowed in associated functions
   --> $DIR/self-param-semantic-fail.rs:18:15
    |
 LL |     fn f6<'a>(&'a mut self) {}
    |               ^^^^^^^^^^^^ not semantically valid as function parameter
    |
-   = note: associated `fn`s are those in `impl` or `trait` definitions
+   = note: associated functions are those in `impl` or `trait` definitions
 
-error: `self` parameter only allowed in associated `fn`s
+error: `self` parameter is only allowed in associated functions
   --> $DIR/self-param-semantic-fail.rs:20:11
    |
 LL |     fn f7(self: u8) {}
    |           ^^^^ not semantically valid as function parameter
    |
-   = note: associated `fn`s are those in `impl` or `trait` definitions
+   = note: associated functions are those in `impl` or `trait` definitions
 
-error: `self` parameter only allowed in associated `fn`s
+error: `self` parameter is only allowed in associated functions
   --> $DIR/self-param-semantic-fail.rs:22:11
    |
 LL |     fn f8(mut self: u8) {}
    |           ^^^^^^^^ not semantically valid as function parameter
    |
-   = note: associated `fn`s are those in `impl` or `trait` definitions
+   = note: associated functions are those in `impl` or `trait` definitions
 
-error: `self` parameter only allowed in associated `fn`s
+error: `self` parameter is only allowed in associated functions
   --> $DIR/self-param-semantic-fail.rs:27:11
    |
 LL |     fn f1(self);
    |           ^^^^ not semantically valid as function parameter
    |
-   = note: associated `fn`s are those in `impl` or `trait` definitions
+   = note: associated functions are those in `impl` or `trait` definitions
 
-error: `self` parameter only allowed in associated `fn`s
+error: `self` parameter is only allowed in associated functions
   --> $DIR/self-param-semantic-fail.rs:29:11
    |
 LL |     fn f2(mut self);
    |           ^^^^^^^^ not semantically valid as function parameter
    |
-   = note: associated `fn`s are those in `impl` or `trait` definitions
+   = note: associated functions are those in `impl` or `trait` definitions
 
 error[E0130]: patterns aren't allowed in foreign function declarations
   --> $DIR/self-param-semantic-fail.rs:29:11
@@ -84,53 +84,53 @@ error[E0130]: patterns aren't allowed in foreign function declarations
 LL |     fn f2(mut self);
    |           ^^^^^^^^ pattern not allowed in foreign function
 
-error: `self` parameter only allowed in associated `fn`s
+error: `self` parameter is only allowed in associated functions
   --> $DIR/self-param-semantic-fail.rs:32:11
    |
 LL |     fn f3(&self);
    |           ^^^^^ not semantically valid as function parameter
    |
-   = note: associated `fn`s are those in `impl` or `trait` definitions
+   = note: associated functions are those in `impl` or `trait` definitions
 
-error: `self` parameter only allowed in associated `fn`s
+error: `self` parameter is only allowed in associated functions
   --> $DIR/self-param-semantic-fail.rs:34:11
    |
 LL |     fn f4(&mut self);
    |           ^^^^^^^^^ not semantically valid as function parameter
    |
-   = note: associated `fn`s are those in `impl` or `trait` definitions
+   = note: associated functions are those in `impl` or `trait` definitions
 
-error: `self` parameter only allowed in associated `fn`s
+error: `self` parameter is only allowed in associated functions
   --> $DIR/self-param-semantic-fail.rs:36:15
    |
 LL |     fn f5<'a>(&'a self);
    |               ^^^^^^^^ not semantically valid as function parameter
    |
-   = note: associated `fn`s are those in `impl` or `trait` definitions
+   = note: associated functions are those in `impl` or `trait` definitions
 
-error: `self` parameter only allowed in associated `fn`s
+error: `self` parameter is only allowed in associated functions
   --> $DIR/self-param-semantic-fail.rs:38:15
    |
 LL |     fn f6<'a>(&'a mut self);
    |               ^^^^^^^^^^^^ not semantically valid as function parameter
    |
-   = note: associated `fn`s are those in `impl` or `trait` definitions
+   = note: associated functions are those in `impl` or `trait` definitions
 
-error: `self` parameter only allowed in associated `fn`s
+error: `self` parameter is only allowed in associated functions
   --> $DIR/self-param-semantic-fail.rs:40:11
    |
 LL |     fn f7(self: u8);
    |           ^^^^ not semantically valid as function parameter
    |
-   = note: associated `fn`s are those in `impl` or `trait` definitions
+   = note: associated functions are those in `impl` or `trait` definitions
 
-error: `self` parameter only allowed in associated `fn`s
+error: `self` parameter is only allowed in associated functions
   --> $DIR/self-param-semantic-fail.rs:42:11
    |
 LL |     fn f8(mut self: u8);
    |           ^^^^^^^^ not semantically valid as function parameter
    |
-   = note: associated `fn`s are those in `impl` or `trait` definitions
+   = note: associated functions are those in `impl` or `trait` definitions
 
 error[E0130]: patterns aren't allowed in foreign function declarations
   --> $DIR/self-param-semantic-fail.rs:42:11
@@ -138,21 +138,21 @@ error[E0130]: patterns aren't allowed in foreign function declarations
 LL |     fn f8(mut self: u8);
    |           ^^^^^^^^ pattern not allowed in foreign function
 
-error: `self` parameter only allowed in associated `fn`s
+error: `self` parameter is only allowed in associated functions
   --> $DIR/self-param-semantic-fail.rs:47:14
    |
 LL | type X1 = fn(self);
    |              ^^^^ not semantically valid as function parameter
    |
-   = note: associated `fn`s are those in `impl` or `trait` definitions
+   = note: associated functions are those in `impl` or `trait` definitions
 
-error: `self` parameter only allowed in associated `fn`s
+error: `self` parameter is only allowed in associated functions
   --> $DIR/self-param-semantic-fail.rs:49:14
    |
 LL | type X2 = fn(mut self);
    |              ^^^^^^^^ not semantically valid as function parameter
    |
-   = note: associated `fn`s are those in `impl` or `trait` definitions
+   = note: associated functions are those in `impl` or `trait` definitions
 
 error[E0561]: patterns aren't allowed in function pointer types
   --> $DIR/self-param-semantic-fail.rs:49:14
@@ -160,53 +160,53 @@ error[E0561]: patterns aren't allowed in function pointer types
 LL | type X2 = fn(mut self);
    |              ^^^^^^^^
 
-error: `self` parameter only allowed in associated `fn`s
+error: `self` parameter is only allowed in associated functions
   --> $DIR/self-param-semantic-fail.rs:52:14
    |
 LL | type X3 = fn(&self);
    |              ^^^^^ not semantically valid as function parameter
    |
-   = note: associated `fn`s are those in `impl` or `trait` definitions
+   = note: associated functions are those in `impl` or `trait` definitions
 
-error: `self` parameter only allowed in associated `fn`s
+error: `self` parameter is only allowed in associated functions
   --> $DIR/self-param-semantic-fail.rs:54:14
    |
 LL | type X4 = fn(&mut self);
    |              ^^^^^^^^^ not semantically valid as function parameter
    |
-   = note: associated `fn`s are those in `impl` or `trait` definitions
+   = note: associated functions are those in `impl` or `trait` definitions
 
-error: `self` parameter only allowed in associated `fn`s
+error: `self` parameter is only allowed in associated functions
   --> $DIR/self-param-semantic-fail.rs:56:22
    |
 LL | type X5 = for<'a> fn(&'a self);
    |                      ^^^^^^^^ not semantically valid as function parameter
    |
-   = note: associated `fn`s are those in `impl` or `trait` definitions
+   = note: associated functions are those in `impl` or `trait` definitions
 
-error: `self` parameter only allowed in associated `fn`s
+error: `self` parameter is only allowed in associated functions
   --> $DIR/self-param-semantic-fail.rs:58:22
    |
 LL | type X6 = for<'a> fn(&'a mut self);
    |                      ^^^^^^^^^^^^ not semantically valid as function parameter
    |
-   = note: associated `fn`s are those in `impl` or `trait` definitions
+   = note: associated functions are those in `impl` or `trait` definitions
 
-error: `self` parameter only allowed in associated `fn`s
+error: `self` parameter is only allowed in associated functions
   --> $DIR/self-param-semantic-fail.rs:60:14
    |
 LL | type X7 = fn(self: u8);
    |              ^^^^ not semantically valid as function parameter
    |
-   = note: associated `fn`s are those in `impl` or `trait` definitions
+   = note: associated functions are those in `impl` or `trait` definitions
 
-error: `self` parameter only allowed in associated `fn`s
+error: `self` parameter is only allowed in associated functions
   --> $DIR/self-param-semantic-fail.rs:62:14
    |
 LL | type X8 = fn(mut self: u8);
    |              ^^^^^^^^ not semantically valid as function parameter
    |
-   = note: associated `fn`s are those in `impl` or `trait` definitions
+   = note: associated functions are those in `impl` or `trait` definitions
 
 error[E0561]: patterns aren't allowed in function pointer types
   --> $DIR/self-param-semantic-fail.rs:62:14
diff --git a/src/test/ui/span/issue-34264.stderr b/src/test/ui/span/issue-34264.stderr
index 56a2686945ca2..80a237ac6aad4 100644
--- a/src/test/ui/span/issue-34264.stderr
+++ b/src/test/ui/span/issue-34264.stderr
@@ -5,6 +5,10 @@ LL | fn foo(Option<i32>, String) {}
    |              ^ expected one of `:`, `@`, or `|`
    |
    = note: anonymous parameters are removed in the 2018 edition (see RFC 1685)
+help: if this is a `self` type, give it a parameter name
+   |
+LL | fn foo(self: Option<i32>, String) {}
+   |        ^^^^^^^^^^^^
 help: if this is a type, explicitly ignore the parameter name
    |
 LL | fn foo(_: Option<i32>, String) {}
@@ -33,6 +37,10 @@ LL | fn bar(x, y: usize) {}
    |         ^ expected one of `:`, `@`, or `|`
    |
    = note: anonymous parameters are removed in the 2018 edition (see RFC 1685)
+help: if this is a `self` type, give it a parameter name
+   |
+LL | fn bar(self: x, y: usize) {}
+   |        ^^^^^^^
 help: if this was a parameter name, give it a type
    |
 LL | fn bar(x: TypeName, y: usize) {}
diff --git a/src/test/ui/suggestions/issue-64252-self-type.stderr b/src/test/ui/suggestions/issue-64252-self-type.stderr
index 4abffb1ad79f6..e96db3f1e8630 100644
--- a/src/test/ui/suggestions/issue-64252-self-type.stderr
+++ b/src/test/ui/suggestions/issue-64252-self-type.stderr
@@ -5,6 +5,10 @@ LL | pub fn foo(Box<Self>) { }
    |               ^ expected one of `:`, `@`, or `|`
    |
    = note: anonymous parameters are removed in the 2018 edition (see RFC 1685)
+help: if this is a `self` type, give it a parameter name
+   |
+LL | pub fn foo(self: Box<Self>) { }
+   |            ^^^^^^^^^
 help: if this is a type, explicitly ignore the parameter name
    |
 LL | pub fn foo(_: Box<Self>) { }