From 85a9c741588aaf296ce94f480e342c2bf5c131ba Mon Sep 17 00:00:00 2001
From: AngelicosPhosphoros <xuzin.timur@gmail.com>
Date: Sun, 17 Jul 2022 23:33:29 +0300
Subject: [PATCH 01/23] Add tests that check `Vec::retain` predicate execution
 order.

---
 library/alloc/tests/vec.rs | 45 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)

diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs
index 5520f6ebf1904..b17f7a8eebc56 100644
--- a/library/alloc/tests/vec.rs
+++ b/library/alloc/tests/vec.rs
@@ -292,6 +292,22 @@ fn test_retain() {
     assert_eq!(vec, [2, 4]);
 }
 
+#[test]
+fn test_retain_predicate_order() {
+    for to_keep in [true, false] {
+        let mut number_of_executions = 0;
+        let mut vec = vec![1, 2, 3, 4];
+        let mut next_expected = 1;
+        vec.retain(|&x| {
+            assert_eq!(next_expected, x);
+            next_expected += 1;
+            number_of_executions += 1;
+            to_keep
+        });
+        assert_eq!(number_of_executions, 4);
+    }
+}
+
 #[test]
 fn test_retain_pred_panic_with_hole() {
     let v = (0..5).map(Rc::new).collect::<Vec<_>>();
@@ -353,6 +369,35 @@ fn test_retain_drop_panic() {
     assert!(v.iter().all(|r| Rc::strong_count(r) == 1));
 }
 
+#[test]
+fn test_retain_maybeuninits() {
+    // This test aimed to be run under miri.
+    use core::mem::MaybeUninit;
+    let mut vec: Vec<_> = [1i32, 2, 3, 4].map(|v| MaybeUninit::new(vec![v])).into();
+    vec.retain(|x| {
+        // SAFETY: Retain must visit every element of Vec in original order and exactly once.
+        // Our values is initialized at creation of Vec.
+        let v = unsafe { x.assume_init_ref()[0] };
+        if v & 1 == 0 {
+            return true;
+        }
+        // SAFETY: Value is initialized.
+        // Value wouldn't be dropped by `Vec::retain`
+        // because `MaybeUninit` doesn't drop content.
+        drop(unsafe { x.assume_init_read() });
+        false
+    });
+    let vec: Vec<i32> = vec
+        .into_iter()
+        .map(|x| unsafe {
+            // SAFETY: All values dropped in retain predicate must be removed by `Vec::retain`.
+            // Remaining values are initialized.
+            x.assume_init()[0]
+        })
+        .collect();
+    assert_eq!(vec, [2, 4]);
+}
+
 #[test]
 fn test_dedup() {
     fn case(a: Vec<i32>, b: Vec<i32>) {

From c6558c0bc71024b8aca1db317c15cdf701d917d8 Mon Sep 17 00:00:00 2001
From: Maybe Waffle <waffle.lapkin@gmail.com>
Date: Fri, 29 Jul 2022 20:04:28 +0400
Subject: [PATCH 02/23] Recover keywords in bounds

For example, this fixes a error for `impl fn()` (notice the capitalization)
---
 compiler/rustc_parse/src/parser/ty.rs                |  8 +++++++-
 .../ui/rfc-2632-const-trait-impl/without-tilde.rs    |  3 ++-
 .../rfc-2632-const-trait-impl/without-tilde.stderr   | 12 +++++++++---
 3 files changed, 18 insertions(+), 5 deletions(-)

diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs
index 31b40a83e6052..b76ba8ff2d98c 100644
--- a/compiler/rustc_parse/src/parser/ty.rs
+++ b/compiler/rustc_parse/src/parser/ty.rs
@@ -640,7 +640,13 @@ impl<'a> Parser<'a> {
         let mut bounds = Vec::new();
         let mut negative_bounds = Vec::new();
 
-        while self.can_begin_bound() || self.token.is_keyword(kw::Dyn) {
+        while self.can_begin_bound()
+            // Continue even if we find a keyword.
+            // This is necessary for error recover on, for example, `impl fn()`.
+            //
+            // The only keyword that can go after generic bounds is `where`, so stop if it's it.
+            || (self.token.is_reserved_ident() && !self.token.is_keyword(kw::Where))
+        {
             if self.token.is_keyword(kw::Dyn) {
                 // Account for `&dyn Trait + dyn Other`.
                 self.struct_span_err(self.token.span, "invalid `dyn` keyword")
diff --git a/src/test/ui/rfc-2632-const-trait-impl/without-tilde.rs b/src/test/ui/rfc-2632-const-trait-impl/without-tilde.rs
index e8b261545499f..e0d3e0b497b3f 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/without-tilde.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/without-tilde.rs
@@ -3,4 +3,5 @@
 #![feature(const_trait_impl)]
 
 struct S<T: const Tr>;
-//~^ ERROR expected one of `!`, `(`, `,`, `=`, `>`, `?`, `for`, `~`, lifetime, or path
+//~^ ERROR expected identifier, found keyword `const`
+//~| ERROR expected one of `(`, `+`, `,`, `::`, `<`, `=`, or `>`, found `Tr`
diff --git a/src/test/ui/rfc-2632-const-trait-impl/without-tilde.stderr b/src/test/ui/rfc-2632-const-trait-impl/without-tilde.stderr
index b6b77ac4a2fb6..243f0979509bf 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/without-tilde.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/without-tilde.stderr
@@ -1,8 +1,14 @@
-error: expected one of `!`, `(`, `,`, `=`, `>`, `?`, `for`, `~`, lifetime, or path, found keyword `const`
+error: expected identifier, found keyword `const`
   --> $DIR/without-tilde.rs:5:13
    |
 LL | struct S<T: const Tr>;
-   |             ^^^^^ expected one of 10 possible tokens
+   |             ^^^^^ expected identifier, found keyword
 
-error: aborting due to previous error
+error: expected one of `(`, `+`, `,`, `::`, `<`, `=`, or `>`, found `Tr`
+  --> $DIR/without-tilde.rs:5:19
+   |
+LL | struct S<T: const Tr>;
+   |                   ^^ expected one of 7 possible tokens
+
+error: aborting due to 2 previous errors
 

From 798016c2df3a15da739e8c6d0968ba0f7b54e303 Mon Sep 17 00:00:00 2001
From: Maybe Waffle <waffle.lapkin@gmail.com>
Date: Fri, 29 Jul 2022 21:59:08 +0400
Subject: [PATCH 03/23] add a silly test for keywords in trait bounds recovery

---
 src/test/ui/parser/kw-in-trait-bounds.rs     |  47 +++++
 src/test/ui/parser/kw-in-trait-bounds.stderr | 171 +++++++++++++++++++
 2 files changed, 218 insertions(+)
 create mode 100644 src/test/ui/parser/kw-in-trait-bounds.rs
 create mode 100644 src/test/ui/parser/kw-in-trait-bounds.stderr

diff --git a/src/test/ui/parser/kw-in-trait-bounds.rs b/src/test/ui/parser/kw-in-trait-bounds.rs
new file mode 100644
index 0000000000000..fa037e5937dca
--- /dev/null
+++ b/src/test/ui/parser/kw-in-trait-bounds.rs
@@ -0,0 +1,47 @@
+// edition:2018
+
+fn _f<F: fn(), G>(_: impl fn(), _: &dyn fn())
+//~^ ERROR expected identifier, found keyword `fn`
+//~| ERROR expected identifier, found keyword `fn`
+//~| ERROR expected identifier, found keyword `fn`
+//~| ERROR cannot find trait `r#fn` in this scope
+//~| ERROR cannot find trait `r#fn` in this scope
+//~| ERROR cannot find trait `r#fn` in this scope
+//~| HELP  a trait with a similar name exists
+//~| HELP  a trait with a similar name exists
+//~| HELP  a trait with a similar name exists
+//~| HELP  escape `fn` to use it as an identifier
+//~| HELP  escape `fn` to use it as an identifier
+//~| HELP  escape `fn` to use it as an identifier
+where
+G: fn(),
+    //~^ ERROR expected identifier, found keyword `fn`
+    //~| ERROR cannot find trait `r#fn` in this scope
+    //~| HELP  a trait with a similar name exists
+    //~| HELP  escape `fn` to use it as an identifier
+{}
+
+fn _g<A: struct, B>(_: impl struct, _: &dyn struct)
+//~^ ERROR expected identifier, found keyword `struct`
+//~| ERROR expected identifier, found keyword `struct`
+//~| ERROR expected identifier, found keyword `struct`
+//~| ERROR cannot find trait `r#struct` in this scope
+//~| ERROR cannot find trait `r#struct` in this scope
+//~| ERROR cannot find trait `r#struct` in this scope
+//~| HELP  a trait with a similar name exists
+//~| HELP  a trait with a similar name exists
+//~| HELP  a trait with a similar name exists
+//~| HELP  escape `struct` to use it as an identifier
+//~| HELP  escape `struct` to use it as an identifier
+//~| HELP  escape `struct` to use it as an identifier
+where
+    B: struct,
+    //~^ ERROR expected identifier, found keyword `struct`
+    //~| ERROR cannot find trait `r#struct` in this scope
+    //~| HELP  a trait with a similar name exists
+    //~| HELP  escape `struct` to use it as an identifier
+{}
+
+trait Struct {}
+
+fn main() {}
diff --git a/src/test/ui/parser/kw-in-trait-bounds.stderr b/src/test/ui/parser/kw-in-trait-bounds.stderr
new file mode 100644
index 0000000000000..28196c7ce2de8
--- /dev/null
+++ b/src/test/ui/parser/kw-in-trait-bounds.stderr
@@ -0,0 +1,171 @@
+error: expected identifier, found keyword `fn`
+  --> $DIR/kw-in-trait-bounds.rs:3:10
+   |
+LL | fn _f<F: fn(), G>(_: impl fn(), _: &dyn fn())
+   |          ^^ expected identifier, found keyword
+   |
+help: escape `fn` to use it as an identifier
+   |
+LL | fn _f<F: r#fn(), G>(_: impl fn(), _: &dyn fn())
+   |          ++
+
+error: expected identifier, found keyword `fn`
+  --> $DIR/kw-in-trait-bounds.rs:3:27
+   |
+LL | fn _f<F: fn(), G>(_: impl fn(), _: &dyn fn())
+   |                           ^^ expected identifier, found keyword
+   |
+help: escape `fn` to use it as an identifier
+   |
+LL | fn _f<F: fn(), G>(_: impl r#fn(), _: &dyn fn())
+   |                           ++
+
+error: expected identifier, found keyword `fn`
+  --> $DIR/kw-in-trait-bounds.rs:3:41
+   |
+LL | fn _f<F: fn(), G>(_: impl fn(), _: &dyn fn())
+   |                                         ^^ expected identifier, found keyword
+   |
+help: escape `fn` to use it as an identifier
+   |
+LL | fn _f<F: fn(), G>(_: impl fn(), _: &dyn r#fn())
+   |                                         ++
+
+error: expected identifier, found keyword `fn`
+  --> $DIR/kw-in-trait-bounds.rs:17:4
+   |
+LL | G: fn(),
+   |    ^^ expected identifier, found keyword
+   |
+help: escape `fn` to use it as an identifier
+   |
+LL | G: r#fn(),
+   |    ++
+
+error: expected identifier, found keyword `struct`
+  --> $DIR/kw-in-trait-bounds.rs:24:10
+   |
+LL | fn _g<A: struct, B>(_: impl struct, _: &dyn struct)
+   |          ^^^^^^ expected identifier, found keyword
+   |
+help: escape `struct` to use it as an identifier
+   |
+LL | fn _g<A: r#struct, B>(_: impl struct, _: &dyn struct)
+   |          ++
+
+error: expected identifier, found keyword `struct`
+  --> $DIR/kw-in-trait-bounds.rs:24:29
+   |
+LL | fn _g<A: struct, B>(_: impl struct, _: &dyn struct)
+   |                             ^^^^^^ expected identifier, found keyword
+   |
+help: escape `struct` to use it as an identifier
+   |
+LL | fn _g<A: struct, B>(_: impl r#struct, _: &dyn struct)
+   |                             ++
+
+error: expected identifier, found keyword `struct`
+  --> $DIR/kw-in-trait-bounds.rs:24:45
+   |
+LL | fn _g<A: struct, B>(_: impl struct, _: &dyn struct)
+   |                                             ^^^^^^ expected identifier, found keyword
+   |
+help: escape `struct` to use it as an identifier
+   |
+LL | fn _g<A: struct, B>(_: impl struct, _: &dyn r#struct)
+   |                                             ++
+
+error: expected identifier, found keyword `struct`
+  --> $DIR/kw-in-trait-bounds.rs:38:8
+   |
+LL |     B: struct,
+   |        ^^^^^^ expected identifier, found keyword
+   |
+help: escape `struct` to use it as an identifier
+   |
+LL |     B: r#struct,
+   |        ++
+
+error[E0405]: cannot find trait `r#fn` in this scope
+  --> $DIR/kw-in-trait-bounds.rs:3:10
+   |
+LL | fn _f<F: fn(), G>(_: impl fn(), _: &dyn fn())
+   |          ^^ help: a trait with a similar name exists (notice the capitalization): `Fn`
+   |
+  ::: $SRC_DIR/core/src/ops/function.rs:LL:COL
+   |
+LL | pub trait Fn<Args>: FnMut<Args> {
+   | ------------------------------- similarly named trait `Fn` defined here
+
+error[E0405]: cannot find trait `r#fn` in this scope
+  --> $DIR/kw-in-trait-bounds.rs:17:4
+   |
+LL | G: fn(),
+   |    ^^ help: a trait with a similar name exists (notice the capitalization): `Fn`
+   |
+  ::: $SRC_DIR/core/src/ops/function.rs:LL:COL
+   |
+LL | pub trait Fn<Args>: FnMut<Args> {
+   | ------------------------------- similarly named trait `Fn` defined here
+
+error[E0405]: cannot find trait `r#fn` in this scope
+  --> $DIR/kw-in-trait-bounds.rs:3:27
+   |
+LL | fn _f<F: fn(), G>(_: impl fn(), _: &dyn fn())
+   |                           ^^ help: a trait with a similar name exists (notice the capitalization): `Fn`
+   |
+  ::: $SRC_DIR/core/src/ops/function.rs:LL:COL
+   |
+LL | pub trait Fn<Args>: FnMut<Args> {
+   | ------------------------------- similarly named trait `Fn` defined here
+
+error[E0405]: cannot find trait `r#fn` in this scope
+  --> $DIR/kw-in-trait-bounds.rs:3:41
+   |
+LL | fn _f<F: fn(), G>(_: impl fn(), _: &dyn fn())
+   |                                         ^^ help: a trait with a similar name exists (notice the capitalization): `Fn`
+   |
+  ::: $SRC_DIR/core/src/ops/function.rs:LL:COL
+   |
+LL | pub trait Fn<Args>: FnMut<Args> {
+   | ------------------------------- similarly named trait `Fn` defined here
+
+error[E0405]: cannot find trait `r#struct` in this scope
+  --> $DIR/kw-in-trait-bounds.rs:24:10
+   |
+LL | fn _g<A: struct, B>(_: impl struct, _: &dyn struct)
+   |          ^^^^^^ help: a trait with a similar name exists (notice the capitalization): `Struct`
+...
+LL | trait Struct {}
+   | ------------ similarly named trait `Struct` defined here
+
+error[E0405]: cannot find trait `r#struct` in this scope
+  --> $DIR/kw-in-trait-bounds.rs:38:8
+   |
+LL |     B: struct,
+   |        ^^^^^^ help: a trait with a similar name exists (notice the capitalization): `Struct`
+...
+LL | trait Struct {}
+   | ------------ similarly named trait `Struct` defined here
+
+error[E0405]: cannot find trait `r#struct` in this scope
+  --> $DIR/kw-in-trait-bounds.rs:24:29
+   |
+LL | fn _g<A: struct, B>(_: impl struct, _: &dyn struct)
+   |                             ^^^^^^ help: a trait with a similar name exists (notice the capitalization): `Struct`
+...
+LL | trait Struct {}
+   | ------------ similarly named trait `Struct` defined here
+
+error[E0405]: cannot find trait `r#struct` in this scope
+  --> $DIR/kw-in-trait-bounds.rs:24:45
+   |
+LL | fn _g<A: struct, B>(_: impl struct, _: &dyn struct)
+   |                                             ^^^^^^ help: a trait with a similar name exists (notice the capitalization): `Struct`
+...
+LL | trait Struct {}
+   | ------------ similarly named trait `Struct` defined here
+
+error: aborting due to 16 previous errors
+
+For more information about this error, try `rustc --explain E0405`.

From c198a20f7c2cb96842a705e770ea0b9dc35b9be0 Mon Sep 17 00:00:00 2001
From: ouz-a <oguz.agcayazi@gmail.com>
Date: Fri, 19 Aug 2022 17:08:59 +0300
Subject: [PATCH 04/23] Catch overflow early

---
 .../src/traits/project.rs                     | 12 ++++++++
 src/test/ui/issues/issue-23122-2.stderr       |  7 +----
 src/test/ui/recursion/issue-83150.stderr      |  6 ++--
 src/test/ui/recursion/issue-95134.rs          | 28 +++++++++++++++++++
 src/test/ui/recursion/issue-95134.stderr      |  7 +++++
 5 files changed, 52 insertions(+), 8 deletions(-)
 create mode 100644 src/test/ui/recursion/issue-95134.rs
 create mode 100644 src/test/ui/recursion/issue-95134.stderr

diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index 715b97492683b..aeaccffd5f5f7 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -554,6 +554,18 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
                     .flatten()
                     .unwrap_or_else(|| ty::Term::Ty(ty.super_fold_with(self)))
                 };
+                // For cases like #95134 we would like to catch overflows early
+                // otherwise they slip away away and cause ICE.
+                let recursion_limit = self.tcx().recursion_limit();
+                if !recursion_limit.value_within_limit(self.depth) {
+                    let obligation = Obligation::with_depth(
+                        self.cause.clone(),
+                        recursion_limit.0,
+                        self.param_env,
+                        ty,
+                    );
+                    self.selcx.infcx().report_overflow_error(&obligation, true);
+                }
                 debug!(
                     ?self.depth,
                     ?ty,
diff --git a/src/test/ui/issues/issue-23122-2.stderr b/src/test/ui/issues/issue-23122-2.stderr
index 3d8e7b969184e..f6cda3de5c763 100644
--- a/src/test/ui/issues/issue-23122-2.stderr
+++ b/src/test/ui/issues/issue-23122-2.stderr
@@ -1,15 +1,10 @@
-error[E0275]: overflow evaluating the requirement `<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<T as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next: Sized`
+error[E0275]: overflow evaluating the requirement `<T as Next>::Next`
   --> $DIR/issue-23122-2.rs:10:17
    |
 LL |     type Next = <GetNext<T::Next> as Next>::Next;
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_23122_2`)
-note: required for `GetNext<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<T as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next>` to implement `Next`
-  --> $DIR/issue-23122-2.rs:9:15
-   |
-LL | impl<T: Next> Next for GetNext<T> {
-   |               ^^^^     ^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/recursion/issue-83150.stderr b/src/test/ui/recursion/issue-83150.stderr
index 07f828475680f..ea49e82ac7ac9 100644
--- a/src/test/ui/recursion/issue-83150.stderr
+++ b/src/test/ui/recursion/issue-83150.stderr
@@ -9,10 +9,12 @@ LL |     func(&mut iter.map(|x| x + 1))
    = note: `#[warn(unconditional_recursion)]` on by default
    = help: a `loop` may express intention better if this is on purpose
 
-error[E0275]: overflow evaluating the requirement `Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut std::ops::Range<u8>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>: Iterator`
+error[E0275]: overflow evaluating the requirement `<std::ops::Range<u8> as Iterator>::Item`
    |
    = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_83150`)
-   = note: required for `&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut std::ops::Range<u8>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>` to implement `Iterator`
+   = note: required because of the requirements on the impl of `Iterator` for `Map<&mut std::ops::Range<u8>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>`
+   = note: 64 redundant requirements hidden
+   = note: required because of the requirements on the impl of `Iterator` for `&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut std::ops::Range<u8>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>`
 
 error: aborting due to previous error; 1 warning emitted
 
diff --git a/src/test/ui/recursion/issue-95134.rs b/src/test/ui/recursion/issue-95134.rs
new file mode 100644
index 0000000000000..adc9c6ee2d967
--- /dev/null
+++ b/src/test/ui/recursion/issue-95134.rs
@@ -0,0 +1,28 @@
+// build-fail
+// compile-flags: -Copt-level=0
+//~^^ ERROR overflow evaluating the requirement
+
+pub fn encode_num<Writer: ExampleWriter>(n: u32, mut writer: Writer) -> Result<(), Writer::Error> {
+    if n > 15 {
+        encode_num(n / 16, &mut writer)?;
+    }
+    Ok(())
+}
+
+pub trait ExampleWriter {
+    type Error;
+}
+
+impl<'a, T: ExampleWriter> ExampleWriter for &'a mut T {
+    type Error = T::Error;
+}
+
+struct EmptyWriter;
+
+impl ExampleWriter for EmptyWriter {
+    type Error = ();
+}
+
+fn main() {
+    encode_num(69, &mut EmptyWriter).unwrap();
+}
diff --git a/src/test/ui/recursion/issue-95134.stderr b/src/test/ui/recursion/issue-95134.stderr
new file mode 100644
index 0000000000000..57a498694b7c1
--- /dev/null
+++ b/src/test/ui/recursion/issue-95134.stderr
@@ -0,0 +1,7 @@
+error[E0275]: overflow evaluating the requirement `<EmptyWriter as ExampleWriter>::Error`
+   |
+   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_95134`)
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0275`.

From 4b47686e10caafebab36445072a17b6a0d4b99c7 Mon Sep 17 00:00:00 2001
From: ouz-a <oguz.agcayazi@gmail.com>
Date: Fri, 19 Aug 2022 17:43:20 +0300
Subject: [PATCH 05/23] Update issue-83150.stderr

---
 src/test/ui/recursion/issue-83150.stderr | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/test/ui/recursion/issue-83150.stderr b/src/test/ui/recursion/issue-83150.stderr
index ea49e82ac7ac9..32f25faf3e8ba 100644
--- a/src/test/ui/recursion/issue-83150.stderr
+++ b/src/test/ui/recursion/issue-83150.stderr
@@ -12,9 +12,9 @@ LL |     func(&mut iter.map(|x| x + 1))
 error[E0275]: overflow evaluating the requirement `<std::ops::Range<u8> as Iterator>::Item`
    |
    = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_83150`)
-   = note: required because of the requirements on the impl of `Iterator` for `Map<&mut std::ops::Range<u8>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>`
+   = note: required for `Map<&mut std::ops::Range<u8>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>` to implement `Iterator`
    = note: 64 redundant requirements hidden
-   = note: required because of the requirements on the impl of `Iterator` for `&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut std::ops::Range<u8>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>`
+   = note: required for `&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut std::ops::Range<u8>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>` to implement `Iterator`
 
 error: aborting due to previous error; 1 warning emitted
 

From 17ddcb434b8fca7eeb865985942b146647a3510f Mon Sep 17 00:00:00 2001
From: Cameron Steffen <cam.steffen94@gmail.com>
Date: Sat, 30 Apr 2022 12:01:31 -0500
Subject: [PATCH 06/23] Improve primitive/std docs separation and headers

---
 library/alloc/src/boxed.rs         |  2 +-
 library/alloc/src/slice.rs         | 80 ++----------------------------
 library/alloc/src/str.rs           | 22 +-------
 library/core/src/any.rs            |  5 +-
 library/core/src/array/mod.rs      |  2 +-
 library/core/src/borrow.rs         |  2 +-
 library/core/src/char/mod.rs       |  4 +-
 library/core/src/cmp.rs            |  4 +-
 library/core/src/default.rs        |  2 +-
 library/core/src/num/f32.rs        |  2 +-
 library/core/src/num/f64.rs        |  2 +-
 library/core/src/primitive_docs.rs | 61 ++++++++++++++++++++---
 library/std/src/error.rs           |  2 +-
 library/std/src/f32.rs             |  2 +-
 library/std/src/f64.rs             |  2 +-
 library/std/src/primitive_docs.rs  | 61 ++++++++++++++++++++---
 16 files changed, 127 insertions(+), 128 deletions(-)

diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs
index c1ceeb0deb837..6955d863c99e7 100644
--- a/library/alloc/src/boxed.rs
+++ b/library/alloc/src/boxed.rs
@@ -1,4 +1,4 @@
-//! A pointer type for heap allocation.
+//! The `Box<T>` type for heap allocation.
 //!
 //! [`Box<T>`], casually referred to as a 'box', provides the simplest form of
 //! heap allocation in Rust. Boxes provide ownership for this allocation, and
diff --git a/library/alloc/src/slice.rs b/library/alloc/src/slice.rs
index 63d4d94529008..2bc08f86def1e 100644
--- a/library/alloc/src/slice.rs
+++ b/library/alloc/src/slice.rs
@@ -1,82 +1,12 @@
-//! A dynamically-sized view into a contiguous sequence, `[T]`.
+//! Utilities for the slice primitive type.
 //!
 //! *[See also the slice primitive type](slice).*
 //!
-//! Slices are a view into a block of memory represented as a pointer and a
-//! length.
+//! Most of the structs in this module are iterator types which can only be created
+//! using a certain function. For example, `slice.iter()` yields an [`Iter`].
 //!
-//! ```
-//! // slicing a Vec
-//! let vec = vec![1, 2, 3];
-//! let int_slice = &vec[..];
-//! // coercing an array to a slice
-//! let str_slice: &[&str] = &["one", "two", "three"];
-//! ```
-//!
-//! Slices are either mutable or shared. The shared slice type is `&[T]`,
-//! while the mutable slice type is `&mut [T]`, where `T` represents the element
-//! type. For example, you can mutate the block of memory that a mutable slice
-//! points to:
-//!
-//! ```
-//! let x = &mut [1, 2, 3];
-//! x[1] = 7;
-//! assert_eq!(x, &[1, 7, 3]);
-//! ```
-//!
-//! Here are some of the things this module contains:
-//!
-//! ## Structs
-//!
-//! There are several structs that are useful for slices, such as [`Iter`], which
-//! represents iteration over a slice.
-//!
-//! ## Trait Implementations
-//!
-//! There are several implementations of common traits for slices. Some examples
-//! include:
-//!
-//! * [`Clone`]
-//! * [`Eq`], [`Ord`] - for slices whose element type are [`Eq`] or [`Ord`].
-//! * [`Hash`] - for slices whose element type is [`Hash`].
-//!
-//! ## Iteration
-//!
-//! The slices implement `IntoIterator`. The iterator yields references to the
-//! slice elements.
-//!
-//! ```
-//! let numbers = &[0, 1, 2];
-//! for n in numbers {
-//!     println!("{n} is a number!");
-//! }
-//! ```
-//!
-//! The mutable slice yields mutable references to the elements:
-//!
-//! ```
-//! let mut scores = [7, 8, 9];
-//! for score in &mut scores[..] {
-//!     *score += 1;
-//! }
-//! ```
-//!
-//! This iterator yields mutable references to the slice's elements, so while
-//! the element type of the slice is `i32`, the element type of the iterator is
-//! `&mut i32`.
-//!
-//! * [`.iter`] and [`.iter_mut`] are the explicit methods to return the default
-//!   iterators.
-//! * Further methods that return iterators are [`.split`], [`.splitn`],
-//!   [`.chunks`], [`.windows`] and more.
-//!
-//! [`Hash`]: core::hash::Hash
-//! [`.iter`]: slice::iter
-//! [`.iter_mut`]: slice::iter_mut
-//! [`.split`]: slice::split
-//! [`.splitn`]: slice::splitn
-//! [`.chunks`]: slice::chunks
-//! [`.windows`]: slice::windows
+//! A few functions are provided to create a slice from a value reference
+//! or from a raw pointer.
 #![stable(feature = "rust1", since = "1.0.0")]
 // Many of the usings in this module are only used in the test configuration.
 // It's cleaner to just turn off the unused_imports warning than to fix them.
diff --git a/library/alloc/src/str.rs b/library/alloc/src/str.rs
index d5ed2c4adf4f1..101dd1e57ec4d 100644
--- a/library/alloc/src/str.rs
+++ b/library/alloc/src/str.rs
@@ -1,26 +1,6 @@
-//! Unicode string slices.
+//! Utilities for the `str` primitive type.
 //!
 //! *[See also the `str` primitive type](str).*
-//!
-//! The `&str` type is one of the two main string types, the other being `String`.
-//! Unlike its `String` counterpart, its contents are borrowed.
-//!
-//! # Basic Usage
-//!
-//! A basic string declaration of `&str` type:
-//!
-//! ```
-//! let hello_world = "Hello, World!";
-//! ```
-//!
-//! Here we have declared a string literal, also known as a string slice.
-//! String literals have a static lifetime, which means the string `hello_world`
-//! is guaranteed to be valid for the duration of the entire program.
-//! We can explicitly specify `hello_world`'s lifetime as well:
-//!
-//! ```
-//! let hello_world: &'static str = "Hello, world!";
-//! ```
 
 #![stable(feature = "rust1", since = "1.0.0")]
 // Many of the usings in this module are only used in the test configuration.
diff --git a/library/core/src/any.rs b/library/core/src/any.rs
index f20c497a183b2..e54f6c912d594 100644
--- a/library/core/src/any.rs
+++ b/library/core/src/any.rs
@@ -1,7 +1,4 @@
-//! This module contains the `Any` trait, which enables dynamic typing
-//! of any `'static` type through runtime reflection. It also contains the
-//! `Provider` trait and accompanying API, which enable trait objects to provide
-//! data based on typed requests, an alternate form of runtime reflection.
+//! Utilities for dynamic typing or type reflection.
 //!
 //! # `Any` and `TypeId`
 //!
diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs
index c9823a136bc42..db5bfcab9d2b1 100644
--- a/library/core/src/array/mod.rs
+++ b/library/core/src/array/mod.rs
@@ -1,4 +1,4 @@
-//! Helper functions and types for fixed-length arrays.
+//! Utilities for the array primitive type.
 //!
 //! *[See also the array primitive type](array).*
 
diff --git a/library/core/src/borrow.rs b/library/core/src/borrow.rs
index 58eabecf3f091..8378611eb18c3 100644
--- a/library/core/src/borrow.rs
+++ b/library/core/src/borrow.rs
@@ -1,4 +1,4 @@
-//! A module for working with borrowed data.
+//! Utilities for working with borrowed data.
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
diff --git a/library/core/src/char/mod.rs b/library/core/src/char/mod.rs
index 0df23e7bbe695..a4bdd38f65530 100644
--- a/library/core/src/char/mod.rs
+++ b/library/core/src/char/mod.rs
@@ -1,4 +1,6 @@
-//! A character type.
+//! Utilities for the `char` primitive type.
+//!
+//! *[See also the `char` primitive type](primitive@char).*
 //!
 //! The `char` type represents a single character. More specifically, since
 //! 'character' isn't a well-defined concept in Unicode, `char` is a '[Unicode
diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs
index 5ca5b5fde1604..8a30bb6745060 100644
--- a/library/core/src/cmp.rs
+++ b/library/core/src/cmp.rs
@@ -1,6 +1,6 @@
-//! Functionality for ordering and comparison.
+//! Utilities for comparing and ordering values.
 //!
-//! This module contains various tools for ordering and comparing values. In
+//! This module contains various tools for comparing and ordering values. In
 //! summary:
 //!
 //! * [`Eq`] and [`PartialEq`] are traits that allow you to define total and
diff --git a/library/core/src/default.rs b/library/core/src/default.rs
index 1ce00828bf344..b53cd6074b532 100644
--- a/library/core/src/default.rs
+++ b/library/core/src/default.rs
@@ -1,4 +1,4 @@
-//! The `Default` trait for types which may have meaningful default values.
+//! The `Default` trait for types with a default value.
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs
index 23c46f1a74a31..94a8a1ec79284 100644
--- a/library/core/src/num/f32.rs
+++ b/library/core/src/num/f32.rs
@@ -1,4 +1,4 @@
-//! Constants specific to the `f32` single-precision floating point type.
+//! Constants for the `f32` single-precision floating point type.
 //!
 //! *[See also the `f32` primitive type][f32].*
 //!
diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs
index b5c8241d2943d..bc278fa806927 100644
--- a/library/core/src/num/f64.rs
+++ b/library/core/src/num/f64.rs
@@ -1,4 +1,4 @@
-//! Constants specific to the `f64` double-precision floating point type.
+//! Constants for the `f64` double-precision floating point type.
 //!
 //! *[See also the `f64` primitive type][f64].*
 //!
diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs
index 1c14b9341cac8..2b2ef64fdb1c3 100644
--- a/library/core/src/primitive_docs.rs
+++ b/library/core/src/primitive_docs.rs
@@ -801,11 +801,53 @@ mod prim_array {}
 /// assert_eq!(2 * pointer_size, std::mem::size_of::<Box<[u8]>>());
 /// assert_eq!(2 * pointer_size, std::mem::size_of::<Rc<[u8]>>());
 /// ```
+///
+/// ## Trait Implementations
+///
+/// Some traits are implemented for slices if the element type implements
+/// that trait. This includes [`Eq`], [`Hash`] and [`Ord`].
+///
+/// ## Iteration
+///
+/// The slices implement `IntoIterator`. The iterator yields references to the
+/// slice elements.
+///
+/// ```
+/// let numbers: &[i32] = &[0, 1, 2];
+/// for n in numbers {
+///     println!("{n} is a number!");
+/// }
+/// ```
+///
+/// The mutable slice yields mutable references to the elements:
+///
+/// ```
+/// let mut scores: &mut [i32] = &mut [7, 8, 9];
+/// for score in scores {
+///     *score += 1;
+/// }
+/// ```
+///
+/// This iterator yields mutable references to the slice's elements, so while
+/// the element type of the slice is `i32`, the element type of the iterator is
+/// `&mut i32`.
+///
+/// * [`.iter`] and [`.iter_mut`] are the explicit methods to return the default
+///   iterators.
+/// * Further methods that return iterators are [`.split`], [`.splitn`],
+///   [`.chunks`], [`.windows`] and more.
+///
+/// [`Hash`]: core::hash::Hash
+/// [`.iter`]: slice::iter
+/// [`.iter_mut`]: slice::iter_mut
+/// [`.split`]: slice::split
+/// [`.splitn`]: slice::splitn
+/// [`.chunks`]: slice::chunks
+/// [`.windows`]: slice::windows
 #[stable(feature = "rust1", since = "1.0.0")]
 mod prim_slice {}
 
 #[doc(primitive = "str")]
-//
 /// String slices.
 ///
 /// *[See also the `std::str` module](crate::str).*
@@ -816,19 +858,22 @@ mod prim_slice {}
 ///
 /// String slices are always valid UTF-8.
 ///
-/// # Examples
+/// # Basic Usage
 ///
 /// String literals are string slices:
 ///
 /// ```
-/// let hello = "Hello, world!";
-///
-/// // with an explicit type annotation
-/// let hello: &'static str = "Hello, world!";
+/// let hello_world = "Hello, World!";
 /// ```
 ///
-/// They are `'static` because they're stored directly in the final binary, and
-/// so will be valid for the `'static` duration.
+/// Here we have declared a string slice initialized with a string literal.
+/// String literals have a static lifetime, which means the string `hello_world`
+/// is guaranteed to be valid for the duration of the entire program.
+/// We can explicitly specify `hello_world`'s lifetime as well:
+///
+/// ```
+/// let hello_world: &'static str = "Hello, world!";
+/// ```
 ///
 /// # Representation
 ///
diff --git a/library/std/src/error.rs b/library/std/src/error.rs
index df7a49d258282..4fbcfd85d7c04 100644
--- a/library/std/src/error.rs
+++ b/library/std/src/error.rs
@@ -1,4 +1,4 @@
-//! Interfaces for working with Errors.
+//! The `Error` trait provides common functionality for errors.
 //!
 //! # Error Handling In Rust
 //!
diff --git a/library/std/src/f32.rs b/library/std/src/f32.rs
index 933b52b4dccbb..3dd5b12507fb2 100644
--- a/library/std/src/f32.rs
+++ b/library/std/src/f32.rs
@@ -1,4 +1,4 @@
-//! Constants specific to the `f32` single-precision floating point type.
+//! Constants for the `f32` single-precision floating point type.
 //!
 //! *[See also the `f32` primitive type](primitive@f32).*
 //!
diff --git a/library/std/src/f64.rs b/library/std/src/f64.rs
index a9aa84f70d19e..31351a87978c9 100644
--- a/library/std/src/f64.rs
+++ b/library/std/src/f64.rs
@@ -1,4 +1,4 @@
-//! Constants specific to the `f64` double-precision floating point type.
+//! Constants for the `f64` double-precision floating point type.
 //!
 //! *[See also the `f64` primitive type](primitive@f64).*
 //!
diff --git a/library/std/src/primitive_docs.rs b/library/std/src/primitive_docs.rs
index 1c14b9341cac8..2b2ef64fdb1c3 100644
--- a/library/std/src/primitive_docs.rs
+++ b/library/std/src/primitive_docs.rs
@@ -801,11 +801,53 @@ mod prim_array {}
 /// assert_eq!(2 * pointer_size, std::mem::size_of::<Box<[u8]>>());
 /// assert_eq!(2 * pointer_size, std::mem::size_of::<Rc<[u8]>>());
 /// ```
+///
+/// ## Trait Implementations
+///
+/// Some traits are implemented for slices if the element type implements
+/// that trait. This includes [`Eq`], [`Hash`] and [`Ord`].
+///
+/// ## Iteration
+///
+/// The slices implement `IntoIterator`. The iterator yields references to the
+/// slice elements.
+///
+/// ```
+/// let numbers: &[i32] = &[0, 1, 2];
+/// for n in numbers {
+///     println!("{n} is a number!");
+/// }
+/// ```
+///
+/// The mutable slice yields mutable references to the elements:
+///
+/// ```
+/// let mut scores: &mut [i32] = &mut [7, 8, 9];
+/// for score in scores {
+///     *score += 1;
+/// }
+/// ```
+///
+/// This iterator yields mutable references to the slice's elements, so while
+/// the element type of the slice is `i32`, the element type of the iterator is
+/// `&mut i32`.
+///
+/// * [`.iter`] and [`.iter_mut`] are the explicit methods to return the default
+///   iterators.
+/// * Further methods that return iterators are [`.split`], [`.splitn`],
+///   [`.chunks`], [`.windows`] and more.
+///
+/// [`Hash`]: core::hash::Hash
+/// [`.iter`]: slice::iter
+/// [`.iter_mut`]: slice::iter_mut
+/// [`.split`]: slice::split
+/// [`.splitn`]: slice::splitn
+/// [`.chunks`]: slice::chunks
+/// [`.windows`]: slice::windows
 #[stable(feature = "rust1", since = "1.0.0")]
 mod prim_slice {}
 
 #[doc(primitive = "str")]
-//
 /// String slices.
 ///
 /// *[See also the `std::str` module](crate::str).*
@@ -816,19 +858,22 @@ mod prim_slice {}
 ///
 /// String slices are always valid UTF-8.
 ///
-/// # Examples
+/// # Basic Usage
 ///
 /// String literals are string slices:
 ///
 /// ```
-/// let hello = "Hello, world!";
-///
-/// // with an explicit type annotation
-/// let hello: &'static str = "Hello, world!";
+/// let hello_world = "Hello, World!";
 /// ```
 ///
-/// They are `'static` because they're stored directly in the final binary, and
-/// so will be valid for the `'static` duration.
+/// Here we have declared a string slice initialized with a string literal.
+/// String literals have a static lifetime, which means the string `hello_world`
+/// is guaranteed to be valid for the duration of the entire program.
+/// We can explicitly specify `hello_world`'s lifetime as well:
+///
+/// ```
+/// let hello_world: &'static str = "Hello, world!";
+/// ```
 ///
 /// # Representation
 ///

From 5d5e451618d3f364ce4a19d1d2c4f8903bc30dde Mon Sep 17 00:00:00 2001
From: Maybe Waffle <waffle.lapkin@gmail.com>
Date: Sun, 21 Aug 2022 14:58:42 +0400
Subject: [PATCH 07/23] recover `const Tr` bounds (no `~`)

---
 compiler/rustc_parse/src/parser/ty.rs              | 14 ++++++++++++++
 .../ui/rfc-2632-const-trait-impl/without-tilde.rs  |  3 +--
 .../rfc-2632-const-trait-impl/without-tilde.stderr | 14 +++++---------
 3 files changed, 20 insertions(+), 11 deletions(-)

diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs
index b76ba8ff2d98c..298198f2cf7d7 100644
--- a/compiler/rustc_parse/src/parser/ty.rs
+++ b/compiler/rustc_parse/src/parser/ty.rs
@@ -809,6 +809,20 @@ impl<'a> Parser<'a> {
             self.expect_keyword(kw::Const)?;
             let span = tilde.to(self.prev_token.span);
             self.sess.gated_spans.gate(sym::const_trait_impl, span);
+            Some(span)
+        } else if self.eat_keyword(kw::Const) {
+            let span = self.prev_token.span;
+            self.sess.gated_spans.gate(sym::const_trait_impl, span);
+
+            self.struct_span_err(span, "const bounds must start with `~`")
+                .span_suggestion(
+                    span.shrink_to_lo(),
+                    "add `~`",
+                    "~",
+                    Applicability::MachineApplicable,
+                )
+                .emit();
+
             Some(span)
         } else {
             None
diff --git a/src/test/ui/rfc-2632-const-trait-impl/without-tilde.rs b/src/test/ui/rfc-2632-const-trait-impl/without-tilde.rs
index e0d3e0b497b3f..d63381b5f2cc9 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/without-tilde.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/without-tilde.rs
@@ -3,5 +3,4 @@
 #![feature(const_trait_impl)]
 
 struct S<T: const Tr>;
-//~^ ERROR expected identifier, found keyword `const`
-//~| ERROR expected one of `(`, `+`, `,`, `::`, `<`, `=`, or `>`, found `Tr`
+//~^ ERROR const bounds must start with `~`
diff --git a/src/test/ui/rfc-2632-const-trait-impl/without-tilde.stderr b/src/test/ui/rfc-2632-const-trait-impl/without-tilde.stderr
index 243f0979509bf..31300354a5737 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/without-tilde.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/without-tilde.stderr
@@ -1,14 +1,10 @@
-error: expected identifier, found keyword `const`
+error: const bounds must start with `~`
   --> $DIR/without-tilde.rs:5:13
    |
 LL | struct S<T: const Tr>;
-   |             ^^^^^ expected identifier, found keyword
+   |             -^^^^
+   |             |
+   |             help: add `~`: `~`
 
-error: expected one of `(`, `+`, `,`, `::`, `<`, `=`, or `>`, found `Tr`
-  --> $DIR/without-tilde.rs:5:19
-   |
-LL | struct S<T: const Tr>;
-   |                   ^^ expected one of 7 possible tokens
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 

From d6fdf14eb783969b4e20e91d39a97bb56b50f1c6 Mon Sep 17 00:00:00 2001
From: finalchild <finalchild2@gmail.com>
Date: Wed, 17 Aug 2022 23:51:01 +0900
Subject: [PATCH 08/23] Migrate forbidden_let

---
 Cargo.lock                                    |  1 +
 compiler/rustc_ast_passes/Cargo.toml          |  1 +
 .../rustc_ast_passes/src/ast_validation.rs    | 22 +++----------
 compiler/rustc_ast_passes/src/errors.rs       | 32 +++++++++++++++++++
 compiler/rustc_ast_passes/src/lib.rs          |  1 +
 .../locales/en-US/ast_passes.ftl              |  5 +++
 compiler/rustc_error_messages/src/lib.rs      |  1 +
 7 files changed, 45 insertions(+), 18 deletions(-)
 create mode 100644 compiler/rustc_ast_passes/src/errors.rs
 create mode 100644 compiler/rustc_error_messages/locales/en-US/ast_passes.ftl

diff --git a/Cargo.lock b/Cargo.lock
index 3a35985836c93..cb245ce0ff828 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3595,6 +3595,7 @@ dependencies = [
  "rustc_data_structures",
  "rustc_errors",
  "rustc_feature",
+ "rustc_macros",
  "rustc_parse",
  "rustc_session",
  "rustc_span",
diff --git a/compiler/rustc_ast_passes/Cargo.toml b/compiler/rustc_ast_passes/Cargo.toml
index 22742b2adbd4f..37eff9207c128 100644
--- a/compiler/rustc_ast_passes/Cargo.toml
+++ b/compiler/rustc_ast_passes/Cargo.toml
@@ -11,6 +11,7 @@ rustc_attr = { path = "../rustc_attr" }
 rustc_data_structures = { path = "../rustc_data_structures" }
 rustc_errors = { path = "../rustc_errors" }
 rustc_feature = { path = "../rustc_feature" }
+rustc_macros = { path = "../rustc_macros" }
 rustc_parse = { path = "../rustc_parse" }
 rustc_session = { path = "../rustc_session" }
 rustc_span = { path = "../rustc_span" }
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index e61dfef7bd380..f8eca6a933711 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -27,6 +27,8 @@ use rustc_target::spec::abi;
 use std::mem;
 use std::ops::{Deref, DerefMut};
 
+use crate::errors::ForbiddenLet;
+
 const MORE_EXTERN: &str =
     "for more information, visit https://doc.rust-lang.org/std/keyword.extern.html";
 
@@ -117,23 +119,7 @@ impl<'a> AstValidator<'a> {
 
     /// Emits an error banning the `let` expression provided in the given location.
     fn ban_let_expr(&self, expr: &'a Expr, forbidden_let_reason: ForbiddenLetReason) {
-        let err = "`let` expressions are not supported here";
-        let mut diag = self.session.struct_span_err(expr.span, err);
-        diag.note("only supported directly in conditions of `if` and `while` expressions");
-        match forbidden_let_reason {
-            ForbiddenLetReason::GenericForbidden => {}
-            ForbiddenLetReason::NotSupportedOr(span) => {
-                diag.span_note(span, "`||` operators are not supported in let chain expressions");
-            }
-            ForbiddenLetReason::NotSupportedParentheses(span) => {
-                diag.span_note(
-                    span,
-                    "`let`s wrapped in parentheses are not supported in a context with let \
-                    chains",
-                );
-            }
-        }
-        diag.emit();
+        self.session.emit_err(ForbiddenLet { span: expr.span, reason: forbidden_let_reason });
     }
 
     fn check_gat_where(
@@ -1876,7 +1862,7 @@ pub fn check_crate(session: &Session, krate: &Crate, lints: &mut LintBuffer) ->
 
 /// Used to forbid `let` expressions in certain syntactic locations.
 #[derive(Clone, Copy)]
-enum ForbiddenLetReason {
+pub(crate) enum ForbiddenLetReason {
     /// `let` is not valid and the source environment is not important
     GenericForbidden,
     /// A let chain with the `||` operator
diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs
new file mode 100644
index 0000000000000..397acd3b60912
--- /dev/null
+++ b/compiler/rustc_ast_passes/src/errors.rs
@@ -0,0 +1,32 @@
+//! Errors emitted by ast_passes.
+
+use rustc_errors::fluent;
+use rustc_errors::{AddSubdiagnostic, Diagnostic};
+use rustc_macros::SessionDiagnostic;
+use rustc_span::Span;
+
+use crate::ast_validation::ForbiddenLetReason;
+
+#[derive(SessionDiagnostic)]
+#[error(ast_passes::forbidden_let)]
+#[note]
+pub struct ForbiddenLet {
+    #[primary_span]
+    pub span: Span,
+    #[subdiagnostic]
+    pub(crate) reason: ForbiddenLetReason,
+}
+
+impl AddSubdiagnostic for ForbiddenLetReason {
+    fn add_to_diagnostic(self, diag: &mut Diagnostic) {
+        match self {
+            Self::GenericForbidden => {}
+            Self::NotSupportedOr(span) => {
+                diag.span_note(span, fluent::ast_passes::not_supported_or);
+            }
+            Self::NotSupportedParentheses(span) => {
+                diag.span_note(span, fluent::ast_passes::not_supported_parentheses);
+            },
+        }
+    }
+}
diff --git a/compiler/rustc_ast_passes/src/lib.rs b/compiler/rustc_ast_passes/src/lib.rs
index 2bc3b6f361643..6a8262989850c 100644
--- a/compiler/rustc_ast_passes/src/lib.rs
+++ b/compiler/rustc_ast_passes/src/lib.rs
@@ -12,6 +12,7 @@
 #![recursion_limit = "256"]
 
 pub mod ast_validation;
+mod errors;
 pub mod feature_gate;
 pub mod node_count;
 pub mod show_span;
diff --git a/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl b/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl
new file mode 100644
index 0000000000000..4f4235b6c8155
--- /dev/null
+++ b/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl
@@ -0,0 +1,5 @@
+ast_passes_forbidden_let =
+    `let` expressions are not supported here
+    .note = only supported directly in conditions of `if` and `while` expressions
+    .not_supported_or = `||` operators are not supported in let chain expressions
+    .not_supported_parentheses = `let`s wrapped in parentheses are not supported in a context with let chains
diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs
index ee978f04be2a5..3569c7f063064 100644
--- a/compiler/rustc_error_messages/src/lib.rs
+++ b/compiler/rustc_error_messages/src/lib.rs
@@ -32,6 +32,7 @@ pub use unic_langid::{langid, LanguageIdentifier};
 
 // Generates `DEFAULT_LOCALE_RESOURCES` static and `fluent_generated` module.
 fluent_messages! {
+    ast_passes => "../locales/en-US/ast_passes.ftl",
     borrowck => "../locales/en-US/borrowck.ftl",
     builtin_macros => "../locales/en-US/builtin_macros.ftl",
     const_eval => "../locales/en-US/const_eval.ftl",

From 80451de390dde969057230345e44adfab21de6b8 Mon Sep 17 00:00:00 2001
From: finalchild <finalchild2@gmail.com>
Date: Wed, 17 Aug 2022 23:52:16 +0900
Subject: [PATCH 09/23] Use DiagnosticMessage for BufferedEarlyLint.msg

---
 compiler/rustc_builtin_macros/src/format.rs | 2 +-
 compiler/rustc_lint/src/early.rs            | 2 +-
 compiler/rustc_lint_defs/src/lib.rs         | 8 ++++----
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs
index 08026c9d35784..e76f5711b7b63 100644
--- a/compiler/rustc_builtin_macros/src/format.rs
+++ b/compiler/rustc_builtin_macros/src/format.rs
@@ -1176,7 +1176,7 @@ fn create_lints_for_named_arguments_used_positionally(cx: &mut Context<'_, '_>)
 
         cx.ecx.buffered_early_lint.push(BufferedEarlyLint {
             span: MultiSpan::from_span(named_arg.positional_named_arg_span),
-            msg: msg.clone(),
+            msg: msg.clone().into(),
             node_id: ast::CRATE_NODE_ID,
             lint_id: LintId::of(&NAMED_ARGUMENTS_USED_POSITIONALLY),
             diagnostic: BuiltinLintDiagnostics::NamedArgumentUsedPositionally {
diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs
index 580a4566869f0..cdb5b3c4284a8 100644
--- a/compiler/rustc_lint/src/early.rs
+++ b/compiler/rustc_lint/src/early.rs
@@ -45,7 +45,7 @@ impl<'a, T: EarlyLintPass> EarlyContextAndPass<'a, T> {
                 lint_id.lint,
                 Some(span),
                 |lint| {
-                    lint.build(&msg).emit();
+                    lint.build(msg).emit();
                 },
                 diagnostic,
             );
diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs
index a826f599e9cd5..32b653f669bd1 100644
--- a/compiler/rustc_lint_defs/src/lib.rs
+++ b/compiler/rustc_lint_defs/src/lib.rs
@@ -9,7 +9,7 @@ pub use self::Level::*;
 use rustc_ast::node_id::{NodeId, NodeMap};
 use rustc_ast::{AttrId, Attribute};
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
-use rustc_error_messages::MultiSpan;
+use rustc_error_messages::{MultiSpan, DiagnosticMessage};
 use rustc_hir::HashStableContext;
 use rustc_hir::HirId;
 use rustc_span::edition::Edition;
@@ -491,7 +491,7 @@ pub struct BufferedEarlyLint {
     pub span: MultiSpan,
 
     /// The lint message.
-    pub msg: String,
+    pub msg: DiagnosticMessage,
 
     /// The `NodeId` of the AST node that generated the lint.
     pub node_id: NodeId,
@@ -520,11 +520,11 @@ impl LintBuffer {
         lint: &'static Lint,
         node_id: NodeId,
         span: MultiSpan,
-        msg: &str,
+        msg: impl Into<DiagnosticMessage>,
         diagnostic: BuiltinLintDiagnostics,
     ) {
         let lint_id = LintId::of(lint);
-        let msg = msg.to_string();
+        let msg = msg.into();
         self.add_early_lint(BufferedEarlyLint { lint_id, node_id, span, msg, diagnostic });
     }
 

From e144a2367aab5c628752580de8a4f625b08ea6f3 Mon Sep 17 00:00:00 2001
From: finalchild <finalchild2@gmail.com>
Date: Thu, 18 Aug 2022 04:36:57 +0900
Subject: [PATCH 10/23] Migrate deprecated_where_clause_location,
 forbidden_assoc_constraint, keyword_lifetime, invalid_label,
 invalid_visibility

---
 .../rustc_ast_passes/src/ast_validation.rs    | 36 ++++++---------
 compiler/rustc_ast_passes/src/errors.rs       | 45 ++++++++++++++++++-
 .../locales/en-US/ast_passes.ftl              | 18 ++++++++
 compiler/rustc_lint_defs/src/lib.rs           |  4 +-
 4 files changed, 77 insertions(+), 26 deletions(-)

diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index f8eca6a933711..fee876489f7ee 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -13,7 +13,7 @@ use rustc_ast::walk_list;
 use rustc_ast::*;
 use rustc_ast_pretty::pprust::{self, State};
 use rustc_data_structures::fx::FxHashMap;
-use rustc_errors::{error_code, pluralize, struct_span_err, Applicability, Diagnostic};
+use rustc_errors::{error_code, fluent, pluralize, struct_span_err, Applicability, Diagnostic};
 use rustc_parse::validate_attr;
 use rustc_session::lint::builtin::{
     DEPRECATED_WHERE_CLAUSE_LOCATION, MISSING_ABI, PATTERNS_IN_FNS_WITHOUT_BODY,
@@ -27,7 +27,7 @@ use rustc_target::spec::abi;
 use std::mem;
 use std::ops::{Deref, DerefMut};
 
-use crate::errors::ForbiddenLet;
+use crate::errors::*;
 
 const MORE_EXTERN: &str =
     "for more information, visit https://doc.rust-lang.org/std/keyword.extern.html";
@@ -149,7 +149,7 @@ impl<'a> AstValidator<'a> {
                 DEPRECATED_WHERE_CLAUSE_LOCATION,
                 id,
                 where_clauses.0.1,
-                "where clause not allowed here",
+                fluent::ast_passes::deprecated_where_clause_location,
                 BuiltinLintDiagnostics::DeprecatedWhereclauseLocation(
                     where_clauses.1.1.shrink_to_hi(),
                     suggestion,
@@ -179,10 +179,7 @@ impl<'a> AstValidator<'a> {
             AssocConstraintKind::Equality { .. } => {}
             AssocConstraintKind::Bound { .. } => {
                 if self.is_assoc_ty_bound_banned {
-                    self.err_handler().span_err(
-                        constraint.span,
-                        "associated type bounds are not allowed within structs, enums, or unions",
-                    );
+                    self.session.emit_err(ForbiddenAssocConstraint { span: constraint.span });
                 }
             }
         }
@@ -254,31 +251,26 @@ impl<'a> AstValidator<'a> {
     fn check_lifetime(&self, ident: Ident) {
         let valid_names = [kw::UnderscoreLifetime, kw::StaticLifetime, kw::Empty];
         if !valid_names.contains(&ident.name) && ident.without_first_quote().is_reserved() {
-            self.err_handler().span_err(ident.span, "lifetimes cannot use keyword names");
+            self.session.emit_err(KeywordLifetime { span: ident.span });
         }
     }
 
     fn check_label(&self, ident: Ident) {
         if ident.without_first_quote().is_reserved() {
-            self.err_handler()
-                .span_err(ident.span, &format!("invalid label name `{}`", ident.name));
+            self.session.emit_err(InvalidLabel { span: ident.span, name: ident.name });
         }
     }
 
-    fn invalid_visibility(&self, vis: &Visibility, note: Option<&str>) {
+    fn invalid_visibility(&self, vis: &Visibility, note: Option<InvalidVisibilityNote>) {
         if let VisibilityKind::Inherited = vis.kind {
             return;
         }
 
-        let mut err =
-            struct_span_err!(self.session, vis.span, E0449, "unnecessary visibility qualifier");
-        if vis.kind.is_pub() {
-            err.span_label(vis.span, "`pub` not permitted here because it's implied");
-        }
-        if let Some(note) = note {
-            err.note(note);
-        }
-        err.emit();
+        self.session.emit_err(InvalidVisibility {
+            span: vis.span,
+            implied: if vis.kind.is_pub() { Some(vis.span) } else { None },
+            note,
+        });
     }
 
     fn check_decl_no_pat(decl: &FnDecl, mut report_err: impl FnMut(Span, Option<Ident>, bool)) {
@@ -1154,7 +1146,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
 
                 self.invalid_visibility(
                     &item.vis,
-                    Some("place qualifiers on individual impl items instead"),
+                    Some(InvalidVisibilityNote::IndividualImplItems),
                 );
                 if let Unsafe::Yes(span) = unsafety {
                     error(span, "unsafe").code(error_code!(E0197)).emit();
@@ -1222,7 +1214,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                 let old_item = mem::replace(&mut self.extern_mod, Some(item));
                 self.invalid_visibility(
                     &item.vis,
-                    Some("place qualifiers on individual foreign items instead"),
+                    Some(InvalidVisibilityNote::IndividualForeignItems),
                 );
                 if let Unsafe::Yes(span) = unsafety {
                     self.err_handler().span_err(span, "extern block cannot be declared unsafe");
diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs
index 397acd3b60912..0d5a41771ea88 100644
--- a/compiler/rustc_ast_passes/src/errors.rs
+++ b/compiler/rustc_ast_passes/src/errors.rs
@@ -2,8 +2,8 @@
 
 use rustc_errors::fluent;
 use rustc_errors::{AddSubdiagnostic, Diagnostic};
-use rustc_macros::SessionDiagnostic;
-use rustc_span::Span;
+use rustc_macros::{SessionDiagnostic, SessionSubdiagnostic};
+use rustc_span::{Span, Symbol};
 
 use crate::ast_validation::ForbiddenLetReason;
 
@@ -30,3 +30,44 @@ impl AddSubdiagnostic for ForbiddenLetReason {
         }
     }
 }
+
+#[derive(SessionDiagnostic)]
+#[error(ast_passes::forbidden_assoc_constraint)]
+pub struct ForbiddenAssocConstraint {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[error(ast_passes::keyword_lifetime)]
+pub struct KeywordLifetime {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[error(ast_passes::invalid_label)]
+pub struct InvalidLabel {
+    #[primary_span]
+    pub span: Span,
+    pub name: Symbol,
+}
+
+#[derive(SessionDiagnostic)]
+#[error(ast_passes::invalid_visibility, code = "E0449")]
+pub struct InvalidVisibility {
+    #[primary_span]
+    pub span: Span,
+    #[label(ast_passes::implied)]
+    pub implied: Option<Span>,
+    #[subdiagnostic]
+    pub note: Option<InvalidVisibilityNote>,
+}
+
+#[derive(SessionSubdiagnostic)]
+pub enum InvalidVisibilityNote {
+    #[note(ast_passes::individual_impl_items)]
+    IndividualImplItems,
+    #[note(ast_passes::individual_foreign_items)]
+    IndividualForeignItems,
+}
diff --git a/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl b/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl
index 4f4235b6c8155..153a91cc7e2bb 100644
--- a/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl
@@ -3,3 +3,21 @@ ast_passes_forbidden_let =
     .note = only supported directly in conditions of `if` and `while` expressions
     .not_supported_or = `||` operators are not supported in let chain expressions
     .not_supported_parentheses = `let`s wrapped in parentheses are not supported in a context with let chains
+
+ast_passes_deprecated_where_clause_location =
+    where clause not allowed here
+
+ast_passes_forbidden_assoc_constraint =
+    associated type bounds are not allowed within structs, enums, or unions
+
+ast_passes_keyword_lifetime =
+    lifetimes cannot use keyword names
+
+ast_passes_invalid_label =
+    invalid label name `{$name}`
+
+ast_passes_invalid_visibility =
+    unnecessary visibility qualifier
+    .implied = `pub` not permitted here because it's implied
+    .individual_impl_items = place qualifiers on individual impl items instead
+    .individual_foreign_items = place qualifiers on individual foreign items instead
diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs
index 32b653f669bd1..609a7894d8605 100644
--- a/compiler/rustc_lint_defs/src/lib.rs
+++ b/compiler/rustc_lint_defs/src/lib.rs
@@ -537,7 +537,7 @@ impl LintBuffer {
         lint: &'static Lint,
         id: NodeId,
         sp: impl Into<MultiSpan>,
-        msg: &str,
+        msg: impl Into<DiagnosticMessage>,
     ) {
         self.add_lint(lint, id, sp.into(), msg, BuiltinLintDiagnostics::Normal)
     }
@@ -547,7 +547,7 @@ impl LintBuffer {
         lint: &'static Lint,
         id: NodeId,
         sp: impl Into<MultiSpan>,
-        msg: &str,
+        msg: impl Into<DiagnosticMessage>,
         diagnostic: BuiltinLintDiagnostics,
     ) {
         self.add_lint(lint, id, sp.into(), msg, diagnostic)

From 88afae5d1adf809510aee801cab639d5ef484713 Mon Sep 17 00:00:00 2001
From: finalchild <finalchild2@gmail.com>
Date: Thu, 18 Aug 2022 15:23:00 +0900
Subject: [PATCH 11/23] Tidy

---
 compiler/rustc_ast_passes/src/errors.rs | 2 +-
 compiler/rustc_lint_defs/src/lib.rs     | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs
index 0d5a41771ea88..8bea95ea092dd 100644
--- a/compiler/rustc_ast_passes/src/errors.rs
+++ b/compiler/rustc_ast_passes/src/errors.rs
@@ -26,7 +26,7 @@ impl AddSubdiagnostic for ForbiddenLetReason {
             }
             Self::NotSupportedParentheses(span) => {
                 diag.span_note(span, fluent::ast_passes::not_supported_parentheses);
-            },
+            }
         }
     }
 }
diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs
index 609a7894d8605..9e7cbba9511b2 100644
--- a/compiler/rustc_lint_defs/src/lib.rs
+++ b/compiler/rustc_lint_defs/src/lib.rs
@@ -9,7 +9,7 @@ pub use self::Level::*;
 use rustc_ast::node_id::{NodeId, NodeMap};
 use rustc_ast::{AttrId, Attribute};
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
-use rustc_error_messages::{MultiSpan, DiagnosticMessage};
+use rustc_error_messages::{DiagnosticMessage, MultiSpan};
 use rustc_hir::HashStableContext;
 use rustc_hir::HirId;
 use rustc_span::edition::Edition;

From e3d4c4039a3b041c7610735c641e5688c25af8b2 Mon Sep 17 00:00:00 2001
From: finalchild <finalchild2@gmail.com>
Date: Thu, 18 Aug 2022 16:49:52 +0900
Subject: [PATCH 12/23] Migrate trait_fn_async

---
 compiler/rustc_ast_passes/src/ast_validation.rs       | 11 +----------
 compiler/rustc_ast_passes/src/errors.rs               | 11 +++++++++++
 .../rustc_error_messages/locales/en-US/ast_passes.ftl |  6 ++++++
 3 files changed, 18 insertions(+), 10 deletions(-)

diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index fee876489f7ee..234243f372c25 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -287,16 +287,7 @@ impl<'a> AstValidator<'a> {
 
     fn check_trait_fn_not_async(&self, fn_span: Span, asyncness: Async) {
         if let Async::Yes { span, .. } = asyncness {
-            struct_span_err!(
-                self.session,
-                fn_span,
-                E0706,
-                "functions in traits cannot be declared `async`"
-            )
-            .span_label(span, "`async` because of this")
-            .note("`async` trait functions are not currently supported")
-            .note("consider using the `async-trait` crate: https://crates.io/crates/async-trait")
-            .emit();
+            self.session.emit_err(TraitFnAsync { fn_span, span });
         }
     }
 
diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs
index 8bea95ea092dd..ed44beafff21a 100644
--- a/compiler/rustc_ast_passes/src/errors.rs
+++ b/compiler/rustc_ast_passes/src/errors.rs
@@ -71,3 +71,14 @@ pub enum InvalidVisibilityNote {
     #[note(ast_passes::individual_foreign_items)]
     IndividualForeignItems,
 }
+
+#[derive(SessionDiagnostic)]
+#[error(ast_passes::trait_fn_async, code = "E0706")]
+#[note]
+#[note(ast_passes::note2)]
+pub struct TraitFnAsync {
+    #[primary_span]
+    pub fn_span: Span,
+    #[label]
+    pub span: Span,
+}
diff --git a/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl b/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl
index 153a91cc7e2bb..ab2313fd86cd8 100644
--- a/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl
@@ -21,3 +21,9 @@ ast_passes_invalid_visibility =
     .implied = `pub` not permitted here because it's implied
     .individual_impl_items = place qualifiers on individual impl items instead
     .individual_foreign_items = place qualifiers on individual foreign items instead
+
+ast_passes_trait_fn_async =
+    functions in traits cannot be declared `async`
+    .label = `async` because of this
+    .note = `async` trait functions are not currently supported
+    .note2 = consider using the `async-trait` crate: https://crates.io/crates/async-trait

From 8d042f4483b60ceaa98a6bb2a778fa5ac4226bbe Mon Sep 17 00:00:00 2001
From: finalchild <finalchild2@gmail.com>
Date: Thu, 18 Aug 2022 16:57:25 +0900
Subject: [PATCH 13/23] Migrate trait_fn_const

---
 compiler/rustc_ast_passes/src/errors.rs                   | 8 ++++++++
 .../rustc_error_messages/locales/en-US/ast_passes.ftl     | 4 ++++
 2 files changed, 12 insertions(+)

diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs
index ed44beafff21a..7a7073b5a5107 100644
--- a/compiler/rustc_ast_passes/src/errors.rs
+++ b/compiler/rustc_ast_passes/src/errors.rs
@@ -82,3 +82,11 @@ pub struct TraitFnAsync {
     #[label]
     pub span: Span,
 }
+
+#[derive(SessionDiagnostic)]
+#[error(ast_passes::trait_fn_const, code = "E0379")]
+pub struct TraitFnConst {
+    #[primary_span]
+    #[label]
+    pub span: Span,
+}
diff --git a/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl b/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl
index ab2313fd86cd8..fa6a02493f3b7 100644
--- a/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl
@@ -27,3 +27,7 @@ ast_passes_trait_fn_async =
     .label = `async` because of this
     .note = `async` trait functions are not currently supported
     .note2 = consider using the `async-trait` crate: https://crates.io/crates/async-trait
+
+ast_passes_trait_fn_const =
+    functions in traits cannot be declared const
+    .label = functions in traits cannot be const

From 269c85390c7eac7e9708a1d5529e54e10bd9631a Mon Sep 17 00:00:00 2001
From: finalchild <finalchild2@gmail.com>
Date: Thu, 18 Aug 2022 17:38:11 +0900
Subject: [PATCH 14/23] Migrate forbidden_lifetime_bound,
 forbidden_non_lifetime_param, too_many_params, c_var_args_without_named_arg,
 c_var_args_not_last

---
 .../rustc_ast_passes/src/ast_validation.rs    | 32 ++++-------------
 compiler/rustc_ast_passes/src/errors.rs       | 36 +++++++++++++++++++
 .../locales/en-US/ast_passes.ftl              | 15 ++++++++
 3 files changed, 57 insertions(+), 26 deletions(-)

diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index 234243f372c25..7735d95f71ee9 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -293,14 +293,7 @@ impl<'a> AstValidator<'a> {
 
     fn check_trait_fn_not_const(&self, constness: Const) {
         if let Const::Yes(span) = constness {
-            struct_span_err!(
-                self.session,
-                span,
-                E0379,
-                "functions in traits cannot be declared const"
-            )
-            .span_label(span, "functions in traits cannot be const")
-            .emit();
+            self.session.emit_err(TraitFnConst { span });
         }
     }
 
@@ -313,8 +306,7 @@ impl<'a> AstValidator<'a> {
                 GenericParamKind::Lifetime { .. } => {
                     if !param.bounds.is_empty() {
                         let spans: Vec<_> = param.bounds.iter().map(|b| b.span()).collect();
-                        self.err_handler()
-                            .span_err(spans, "lifetime bounds cannot be used in this context");
+                        self.session.emit_err(ForbiddenLifetimeBound { spans });
                     }
                     None
                 }
@@ -322,10 +314,7 @@ impl<'a> AstValidator<'a> {
             })
             .collect();
         if !non_lt_param_spans.is_empty() {
-            self.err_handler().span_err(
-                non_lt_param_spans,
-                "only lifetime parameters can be used in this context",
-            );
+            self.session.emit_err(ForbiddenNonLifetimeParam { spans: non_lt_param_spans });
         }
     }
 
@@ -342,10 +331,7 @@ impl<'a> AstValidator<'a> {
         let max_num_args: usize = u16::MAX.into();
         if fn_decl.inputs.len() > max_num_args {
             let Param { span, .. } = fn_decl.inputs[0];
-            self.err_handler().span_fatal(
-                span,
-                &format!("function can not have more than {} arguments", max_num_args),
-            );
+            self.session.emit_err(TooManyParams { span, max_num_args });
         }
     }
 
@@ -353,19 +339,13 @@ impl<'a> AstValidator<'a> {
         match &*fn_decl.inputs {
             [Param { ty, span, .. }] => {
                 if let TyKind::CVarArgs = ty.kind {
-                    self.err_handler().span_err(
-                        *span,
-                        "C-variadic function must be declared with at least one named argument",
-                    );
+                    self.session.emit_err(CVarArgsWithoutNamedArg { span: *span });
                 }
             }
             [ps @ .., _] => {
                 for Param { ty, span, .. } in ps {
                     if let TyKind::CVarArgs = ty.kind {
-                        self.err_handler().span_err(
-                            *span,
-                            "`...` must be the last argument of a C-variadic function",
-                        );
+                        self.session.emit_err(CVarArgsNotLast { span: *span });
                     }
                 }
             }
diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs
index 7a7073b5a5107..cc92f00714de0 100644
--- a/compiler/rustc_ast_passes/src/errors.rs
+++ b/compiler/rustc_ast_passes/src/errors.rs
@@ -90,3 +90,39 @@ pub struct TraitFnConst {
     #[label]
     pub span: Span,
 }
+
+#[derive(SessionDiagnostic)]
+#[error(ast_passes::forbidden_lifetime_bound)]
+pub struct ForbiddenLifetimeBound {
+    #[primary_span]
+    pub spans: Vec<Span>,
+}
+
+#[derive(SessionDiagnostic)]
+#[error(ast_passes::forbidden_non_lifetime_param)]
+pub struct ForbiddenNonLifetimeParam {
+    #[primary_span]
+    pub spans: Vec<Span>,
+}
+
+#[derive(SessionDiagnostic)]
+#[error(ast_passes::too_many_params)]
+pub struct TooManyParams {
+    #[primary_span]
+    pub span: Span,
+    pub max_num_args: usize,
+}
+
+#[derive(SessionDiagnostic)]
+#[error(ast_passes::c_var_args_without_named_arg)]
+pub struct CVarArgsWithoutNamedArg {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[error(ast_passes::c_var_args_not_last)]
+pub struct CVarArgsNotLast {
+    #[primary_span]
+    pub span: Span,
+}
diff --git a/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl b/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl
index fa6a02493f3b7..c0994063fc343 100644
--- a/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl
@@ -31,3 +31,18 @@ ast_passes_trait_fn_async =
 ast_passes_trait_fn_const =
     functions in traits cannot be declared const
     .label = functions in traits cannot be const
+
+ast_passes_forbidden_lifetime_bound =
+    lifetime bounds cannot be used in this context
+
+ast_passes_forbidden_non_lifetime_param =
+    only lifetime parameters can be used in this context
+
+ast_passes_too_many_params =
+    function can not have more than {$max_num_args} arguments
+
+ast_passes_c_var_args_without_named_arg =
+    C-variadic function must be declared with at least one named argument
+
+ast_passes_c_var_args_not_last =
+    `...` must be the last argument of a C-variadic function

From c6903c04b1c95061680aafa9da7e8dbccabb9069 Mon Sep 17 00:00:00 2001
From: finalchild <finalchild2@gmail.com>
Date: Thu, 18 Aug 2022 17:46:01 +0900
Subject: [PATCH 15/23] Migrate doc_comment_on_fn_param,
 forbidden_attr_on_fn_param

---
 compiler/rustc_ast_passes/src/ast_validation.rs   | 14 ++------------
 compiler/rustc_ast_passes/src/errors.rs           | 15 +++++++++++++++
 .../locales/en-US/ast_passes.ftl                  |  7 +++++++
 3 files changed, 24 insertions(+), 12 deletions(-)

diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index 7735d95f71ee9..e42d716d5ae06 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -372,19 +372,9 @@ impl<'a> AstValidator<'a> {
             })
             .for_each(|attr| {
                 if attr.is_doc_comment() {
-                    self.err_handler()
-                        .struct_span_err(
-                            attr.span,
-                            "documentation comments cannot be applied to function parameters",
-                        )
-                        .span_label(attr.span, "doc comments are not allowed here")
-                        .emit();
+                    self.session.emit_err(DocCommentOnFnParam { span: attr.span });
                 } else {
-                    self.err_handler().span_err(
-                        attr.span,
-                        "allow, cfg, cfg_attr, deny, expect, \
-                forbid, and warn are the only allowed built-in attributes in function parameters",
-                    );
+                    self.session.emit_err(ForbiddenAttrOnFnParam { span: attr.span });
                 }
             });
     }
diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs
index cc92f00714de0..2b6d3d2a39a2e 100644
--- a/compiler/rustc_ast_passes/src/errors.rs
+++ b/compiler/rustc_ast_passes/src/errors.rs
@@ -126,3 +126,18 @@ pub struct CVarArgsNotLast {
     #[primary_span]
     pub span: Span,
 }
+
+#[derive(SessionDiagnostic)]
+#[error(ast_passes::doc_comment_on_fn_param)]
+pub struct DocCommentOnFnParam {
+    #[primary_span]
+    #[label]
+    pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[error(ast_passes::forbidden_attr_on_fn_param)]
+pub struct ForbiddenAttrOnFnParam {
+    #[primary_span]
+    pub span: Span,
+}
diff --git a/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl b/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl
index c0994063fc343..bca73baea0049 100644
--- a/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl
@@ -46,3 +46,10 @@ ast_passes_c_var_args_without_named_arg =
 
 ast_passes_c_var_args_not_last =
     `...` must be the last argument of a C-variadic function
+
+ast_passes_doc_comment_on_fn_param =
+    documentation comments cannot be applied to function parameters
+    .label = doc comments are not allowed here
+
+ast_passes_forbidden_attr_on_fn_param =
+    allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed built-in attributes in function parameters

From 07e0bc9600128aef1922cd67939c303d92b3fafc Mon Sep 17 00:00:00 2001
From: finalchild <finalchild2@gmail.com>
Date: Thu, 18 Aug 2022 17:53:59 +0900
Subject: [PATCH 16/23] Rename c_var_args_without_named_arg to
 c_var_args_is_sole_param

---
 compiler/rustc_ast_passes/src/ast_validation.rs            | 2 +-
 compiler/rustc_ast_passes/src/errors.rs                    | 4 ++--
 compiler/rustc_error_messages/locales/en-US/ast_passes.ftl | 2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index e42d716d5ae06..3dd3cc537e6f1 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -339,7 +339,7 @@ impl<'a> AstValidator<'a> {
         match &*fn_decl.inputs {
             [Param { ty, span, .. }] => {
                 if let TyKind::CVarArgs = ty.kind {
-                    self.session.emit_err(CVarArgsWithoutNamedArg { span: *span });
+                    self.session.emit_err(CVarArgsIsSoleParam { span: *span });
                 }
             }
             [ps @ .., _] => {
diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs
index 2b6d3d2a39a2e..d376f638bd2e1 100644
--- a/compiler/rustc_ast_passes/src/errors.rs
+++ b/compiler/rustc_ast_passes/src/errors.rs
@@ -114,8 +114,8 @@ pub struct TooManyParams {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(ast_passes::c_var_args_without_named_arg)]
-pub struct CVarArgsWithoutNamedArg {
+#[error(ast_passes::c_var_args_is_sole_param)]
+pub struct CVarArgsIsSoleParam {
     #[primary_span]
     pub span: Span,
 }
diff --git a/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl b/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl
index bca73baea0049..49ef0cc83de3d 100644
--- a/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl
@@ -41,7 +41,7 @@ ast_passes_forbidden_non_lifetime_param =
 ast_passes_too_many_params =
     function can not have more than {$max_num_args} arguments
 
-ast_passes_c_var_args_without_named_arg =
+ast_passes_c_var_args_is_sole_param =
     C-variadic function must be declared with at least one named argument
 
 ast_passes_c_var_args_not_last =

From bfefefbcfa87cc468d081da371686432ca77c245 Mon Sep 17 00:00:00 2001
From: finalchild <finalchild2@gmail.com>
Date: Thu, 18 Aug 2022 18:20:14 +0900
Subject: [PATCH 17/23] Migrate fn_param_forbidden_self and rename others to
 have prefix fn_param_

---
 .../rustc_ast_passes/src/ast_validation.rs    | 19 ++++--------
 compiler/rustc_ast_passes/src/errors.rs       | 29 ++++++++++++-------
 .../locales/en-US/ast_passes.ftl              | 15 ++++++----
 3 files changed, 35 insertions(+), 28 deletions(-)

diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index 3dd3cc537e6f1..1c3a4ab7c6764 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -331,7 +331,7 @@ impl<'a> AstValidator<'a> {
         let max_num_args: usize = u16::MAX.into();
         if fn_decl.inputs.len() > max_num_args {
             let Param { span, .. } = fn_decl.inputs[0];
-            self.session.emit_err(TooManyParams { span, max_num_args });
+            self.session.emit_err(FnParamTooMany { span, max_num_args });
         }
     }
 
@@ -339,13 +339,13 @@ impl<'a> AstValidator<'a> {
         match &*fn_decl.inputs {
             [Param { ty, span, .. }] => {
                 if let TyKind::CVarArgs = ty.kind {
-                    self.session.emit_err(CVarArgsIsSoleParam { span: *span });
+                    self.session.emit_err(FnParamCVarArgsOnly { span: *span });
                 }
             }
             [ps @ .., _] => {
                 for Param { ty, span, .. } in ps {
                     if let TyKind::CVarArgs = ty.kind {
-                        self.session.emit_err(CVarArgsNotLast { span: *span });
+                        self.session.emit_err(FnParamCVarArgsNotLast { span: *span });
                     }
                 }
             }
@@ -372,9 +372,9 @@ impl<'a> AstValidator<'a> {
             })
             .for_each(|attr| {
                 if attr.is_doc_comment() {
-                    self.session.emit_err(DocCommentOnFnParam { span: attr.span });
+                    self.session.emit_err(FnParamDocComment { span: attr.span });
                 } else {
-                    self.session.emit_err(ForbiddenAttrOnFnParam { span: attr.span });
+                    self.session.emit_err(FnParamForbiddenAttr { span: attr.span });
                 }
             });
     }
@@ -382,14 +382,7 @@ 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 is only allowed in associated functions",
-                    )
-                    .span_label(param.span, "not semantically valid as function parameter")
-                    .note("associated functions are those in `impl` or `trait` definitions")
-                    .emit();
+                self.session.emit_err(FnParamForbiddenSelf { span: param.span });
             }
         }
     }
diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs
index d376f638bd2e1..ee375f1ced7e0 100644
--- a/compiler/rustc_ast_passes/src/errors.rs
+++ b/compiler/rustc_ast_passes/src/errors.rs
@@ -106,38 +106,47 @@ pub struct ForbiddenNonLifetimeParam {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(ast_passes::too_many_params)]
-pub struct TooManyParams {
+#[error(ast_passes::fn_param_too_many)]
+pub struct FnParamTooMany {
     #[primary_span]
     pub span: Span,
     pub max_num_args: usize,
 }
 
 #[derive(SessionDiagnostic)]
-#[error(ast_passes::c_var_args_is_sole_param)]
-pub struct CVarArgsIsSoleParam {
+#[error(ast_passes::fn_param_c_var_args_only)]
+pub struct FnParamCVarArgsOnly {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(SessionDiagnostic)]
-#[error(ast_passes::c_var_args_not_last)]
-pub struct CVarArgsNotLast {
+#[error(ast_passes::fn_param_c_var_args_not_last)]
+pub struct FnParamCVarArgsNotLast {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(SessionDiagnostic)]
-#[error(ast_passes::doc_comment_on_fn_param)]
-pub struct DocCommentOnFnParam {
+#[error(ast_passes::fn_param_doc_comment)]
+pub struct FnParamDocComment {
     #[primary_span]
     #[label]
     pub span: Span,
 }
 
 #[derive(SessionDiagnostic)]
-#[error(ast_passes::forbidden_attr_on_fn_param)]
-pub struct ForbiddenAttrOnFnParam {
+#[error(ast_passes::fn_param_forbidden_attr)]
+pub struct FnParamForbiddenAttr {
     #[primary_span]
     pub span: Span,
 }
+
+#[derive(SessionDiagnostic)]
+#[error(ast_passes::fn_param_forbidden_self)]
+#[note]
+pub struct FnParamForbiddenSelf {
+    #[primary_span]
+    #[label]
+    pub span: Span,
+}
diff --git a/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl b/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl
index 49ef0cc83de3d..77826f639f4dc 100644
--- a/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl
@@ -38,18 +38,23 @@ ast_passes_forbidden_lifetime_bound =
 ast_passes_forbidden_non_lifetime_param =
     only lifetime parameters can be used in this context
 
-ast_passes_too_many_params =
+ast_passes_fn_param_too_many =
     function can not have more than {$max_num_args} arguments
 
-ast_passes_c_var_args_is_sole_param =
+ast_passes_fn_param_c_var_args_only =
     C-variadic function must be declared with at least one named argument
 
-ast_passes_c_var_args_not_last =
+ast_passes_fn_param_c_var_args_not_last =
     `...` must be the last argument of a C-variadic function
 
-ast_passes_doc_comment_on_fn_param =
+ast_passes_fn_param_doc_comment =
     documentation comments cannot be applied to function parameters
     .label = doc comments are not allowed here
 
-ast_passes_forbidden_attr_on_fn_param =
+ast_passes_fn_param_forbidden_attr =
     allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed built-in attributes in function parameters
+
+ast_passes_fn_param_forbidden_self =
+    `self` parameter is only allowed in associated functions
+    .label = not semantically valid as function parameter
+    .note = associated functions are those in `impl` or `trait` definitions

From b28cc097cfbdc9e2f105a7e644389266027bcf7d Mon Sep 17 00:00:00 2001
From: finalchild <finalchild2@gmail.com>
Date: Thu, 18 Aug 2022 21:20:50 +0900
Subject: [PATCH 18/23] Support #[fatal(..)]

---
 compiler/rustc_ast_passes/src/ast_validation.rs |  2 +-
 compiler/rustc_ast_passes/src/errors.rs         |  2 +-
 compiler/rustc_session/src/parse.rs             | 16 ++++++++++++++++
 compiler/rustc_session/src/session.rs           |  9 +++++++++
 4 files changed, 27 insertions(+), 2 deletions(-)

diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index 1c3a4ab7c6764..c8b46dde1c741 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -331,7 +331,7 @@ impl<'a> AstValidator<'a> {
         let max_num_args: usize = u16::MAX.into();
         if fn_decl.inputs.len() > max_num_args {
             let Param { span, .. } = fn_decl.inputs[0];
-            self.session.emit_err(FnParamTooMany { span, max_num_args });
+            self.session.emit_fatal(FnParamTooMany { span, max_num_args });
         }
     }
 
diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs
index ee375f1ced7e0..0287d71feb33e 100644
--- a/compiler/rustc_ast_passes/src/errors.rs
+++ b/compiler/rustc_ast_passes/src/errors.rs
@@ -106,7 +106,7 @@ pub struct ForbiddenNonLifetimeParam {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(ast_passes::fn_param_too_many)]
+#[fatal(ast_passes::fn_param_too_many)]
 pub struct FnParamTooMany {
     #[primary_span]
     pub span: Span,
diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs
index b9b2356130a59..17866dc6bddcb 100644
--- a/compiler/rustc_session/src/parse.rs
+++ b/compiler/rustc_session/src/parse.rs
@@ -360,6 +360,17 @@ impl ParseSess {
         self.create_warning(warning).emit()
     }
 
+    pub fn create_fatal<'a>(
+        &'a self,
+        fatal: impl SessionDiagnostic<'a, !>,
+    ) -> DiagnosticBuilder<'a, !> {
+        fatal.into_diagnostic(self)
+    }
+
+    pub fn emit_fatal<'a>(&'a self, fatal: impl SessionDiagnostic<'a, !>) -> ! {
+        self.create_fatal(fatal).emit()
+    }
+
     #[rustc_lint_diagnostics]
     pub fn struct_err(
         &self,
@@ -373,6 +384,11 @@ impl ParseSess {
         self.span_diagnostic.struct_warn(msg)
     }
 
+    #[rustc_lint_diagnostics]
+    pub fn struct_fatal(&self, msg: impl Into<DiagnosticMessage>) -> DiagnosticBuilder<'_, !> {
+        self.span_diagnostic.struct_fatal(msg)
+    }
+
     #[rustc_lint_diagnostics]
     pub fn struct_diagnostic<G: EmissionGuarantee>(
         &self,
diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs
index 80de451276c2c..255d919eb1452 100644
--- a/compiler/rustc_session/src/session.rs
+++ b/compiler/rustc_session/src/session.rs
@@ -482,6 +482,15 @@ impl Session {
     pub fn emit_warning<'a>(&'a self, warning: impl SessionDiagnostic<'a, ()>) {
         self.parse_sess.emit_warning(warning)
     }
+    pub fn create_fatal<'a>(
+        &'a self,
+        fatal: impl SessionDiagnostic<'a, !>,
+    ) -> DiagnosticBuilder<'a, !> {
+        self.parse_sess.create_fatal(fatal)
+    }
+    pub fn emit_fatal<'a>(&'a self, fatal: impl SessionDiagnostic<'a, !>) {
+        self.parse_sess.emit_fatal(fatal)
+    }
     #[inline]
     pub fn err_count(&self) -> usize {
         self.diagnostic().err_count()

From 8ed8aac3caa9c943e600392e49702c7215428d23 Mon Sep 17 00:00:00 2001
From: finalchild <finalchild2@gmail.com>
Date: Fri, 19 Aug 2022 02:21:35 +0900
Subject: [PATCH 19/23] Fix `build_format` not unescaping braces properly

Co-authored-by: RanolP <public.ranolp@gmail.com>
---
 .../rustc_macros/src/diagnostics/utils.rs     | 59 ++++++++++---------
 1 file changed, 32 insertions(+), 27 deletions(-)

diff --git a/compiler/rustc_macros/src/diagnostics/utils.rs b/compiler/rustc_macros/src/diagnostics/utils.rs
index 002abb152f759..ad9ecd39b9e85 100644
--- a/compiler/rustc_macros/src/diagnostics/utils.rs
+++ b/compiler/rustc_macros/src/diagnostics/utils.rs
@@ -235,35 +235,40 @@ pub(crate) trait HasFieldMap {
         // the referenced fields. Leaves `it` sitting on the closing brace of the format string, so
         // the next call to `it.next()` retrieves the next character.
         while let Some(c) = it.next() {
-            if c == '{' && *it.peek().unwrap_or(&'\0') != '{' {
-                let mut eat_argument = || -> Option<String> {
-                    let mut result = String::new();
-                    // Format specifiers look like:
-                    //
-                    //   format   := '{' [ argument ] [ ':' format_spec ] '}' .
-                    //
-                    // Therefore, we only need to eat until ':' or '}' to find the argument.
-                    while let Some(c) = it.next() {
-                        result.push(c);
-                        let next = *it.peek().unwrap_or(&'\0');
-                        if next == '}' {
-                            break;
-                        } else if next == ':' {
-                            // Eat the ':' character.
-                            assert_eq!(it.next().unwrap(), ':');
-                            break;
-                        }
-                    }
-                    // Eat until (and including) the matching '}'
-                    while it.next()? != '}' {
-                        continue;
+            if c != '{' {
+                continue;
+            }
+            if *it.peek().unwrap_or(&'\0') == '{' {
+                assert_eq!(it.next().unwrap(), '{');
+                continue;
+            }
+            let mut eat_argument = || -> Option<String> {
+                let mut result = String::new();
+                // Format specifiers look like:
+                //
+                //   format   := '{' [ argument ] [ ':' format_spec ] '}' .
+                //
+                // Therefore, we only need to eat until ':' or '}' to find the argument.
+                while let Some(c) = it.next() {
+                    result.push(c);
+                    let next = *it.peek().unwrap_or(&'\0');
+                    if next == '}' {
+                        break;
+                    } else if next == ':' {
+                        // Eat the ':' character.
+                        assert_eq!(it.next().unwrap(), ':');
+                        break;
                     }
-                    Some(result)
-                };
-
-                if let Some(referenced_field) = eat_argument() {
-                    referenced_fields.insert(referenced_field);
                 }
+                // Eat until (and including) the matching '}'
+                while it.next()? != '}' {
+                    continue;
+                }
+                Some(result)
+            };
+
+            if let Some(referenced_field) = eat_argument() {
+                referenced_fields.insert(referenced_field);
             }
         }
 

From e331ae57df08e6eab346a9caab3fc354ce61c5d5 Mon Sep 17 00:00:00 2001
From: finalchild <finalchild2@gmail.com>
Date: Fri, 19 Aug 2022 02:43:01 +0900
Subject: [PATCH 20/23] Migrate forbidden_default and *_without_body

---
 .../rustc_ast_passes/src/ast_validation.rs    | 128 ++++++++----------
 compiler/rustc_ast_passes/src/errors.rs       | 100 +++++++++++++-
 .../locales/en-US/ast_passes.ftl              |  33 +++++
 3 files changed, 185 insertions(+), 76 deletions(-)

diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index c8b46dde1c741..b337e5328c5df 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -13,7 +13,7 @@ use rustc_ast::walk_list;
 use rustc_ast::*;
 use rustc_ast_pretty::pprust::{self, State};
 use rustc_data_structures::fx::FxHashMap;
-use rustc_errors::{error_code, fluent, pluralize, struct_span_err, Applicability, Diagnostic};
+use rustc_errors::{error_code, fluent, pluralize, struct_span_err, Applicability};
 use rustc_parse::validate_attr;
 use rustc_session::lint::builtin::{
     DEPRECATED_WHERE_CLAUSE_LOCATION, MISSING_ABI, PATTERNS_IN_FNS_WITHOUT_BODY,
@@ -390,47 +390,20 @@ impl<'a> AstValidator<'a> {
     fn check_defaultness(&self, span: Span, defaultness: Defaultness) {
         if let Defaultness::Default(def_span) = defaultness {
             let span = self.session.source_map().guess_head_span(span);
-            self.err_handler()
-                .struct_span_err(span, "`default` is only allowed on items in trait impls")
-                .span_label(def_span, "`default` because of this")
-                .emit();
+            self.session.emit_err(ForbiddenDefault { span, def_span });
         }
     }
 
-    fn error_item_without_body(&self, sp: Span, ctx: &str, msg: &str, sugg: &str) {
-        self.error_item_without_body_with_help(sp, ctx, msg, sugg, |_| ());
-    }
-
-    fn error_item_without_body_with_help(
-        &self,
-        sp: Span,
-        ctx: &str,
-        msg: &str,
-        sugg: &str,
-        help: impl FnOnce(&mut Diagnostic),
-    ) {
+    /// If `sp` ends with a semicolon, returns it as a `Span`
+    /// Otherwise, returns `sp.shrink_to_hi()`
+    fn ending_semi_or_hi(&self, sp: Span) -> Span {
         let source_map = self.session.source_map();
         let end = source_map.end_point(sp);
-        let replace_span = if source_map.span_to_snippet(end).map(|s| s == ";").unwrap_or(false) {
+
+        if source_map.span_to_snippet(end).map(|s| s == ";").unwrap_or(false) {
             end
         } else {
             sp.shrink_to_hi()
-        };
-        let mut err = self.err_handler().struct_span_err(sp, msg);
-        err.span_suggestion(
-            replace_span,
-            &format!("provide a definition for the {}", ctx),
-            sugg,
-            Applicability::HasPlaceholders,
-        );
-        help(&mut err);
-        err.emit();
-    }
-
-    fn check_impl_item_provided<T>(&self, sp: Span, body: &Option<T>, ctx: &str, sugg: &str) {
-        if body.is_none() {
-            let msg = format!("associated {} in `impl` without body", ctx);
-            self.error_item_without_body(sp, ctx, &msg, sugg);
         }
     }
 
@@ -1123,37 +1096,23 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                 self.check_defaultness(item.span, defaultness);
 
                 if body.is_none() {
-                    let msg = "free function without a body";
-                    let ext = sig.header.ext;
-
-                    let f = |e: &mut Diagnostic| {
-                        if let Extern::Implicit(start_span) | Extern::Explicit(_, start_span) = &ext
-                        {
-                            let start_suggestion = if let Extern::Explicit(abi, _) = ext {
-                                format!("extern \"{}\" {{", abi.symbol_unescaped)
-                            } else {
-                                "extern {".to_owned()
-                            };
-
-                            let end_suggestion = " }".to_owned();
-                            let end_span = item.span.shrink_to_hi();
-
-                            e
-                            .multipart_suggestion(
-                                "if you meant to declare an externally defined function, use an `extern` block",
-                                vec![(*start_span, start_suggestion), (end_span, end_suggestion)],
-                                Applicability::MaybeIncorrect,
-                             );
-                        }
-                    };
-
-                    self.error_item_without_body_with_help(
-                        item.span,
-                        "function",
-                        msg,
-                        " { <body> }",
-                        f,
-                    );
+                    self.session.emit_err(FnWithoutBody {
+                        span: item.span,
+                        replace_span: self.ending_semi_or_hi(item.span),
+                        extern_block_suggestion: match sig.header.ext {
+                            Extern::None => None,
+                            Extern::Implicit(start_span) => Some(ExternBlockSuggestion {
+                                start_span,
+                                end_span: item.span.shrink_to_hi(),
+                                abi: None,
+                            }),
+                            Extern::Explicit(abi, start_span) => Some(ExternBlockSuggestion {
+                                start_span,
+                                end_span: item.span.shrink_to_hi(),
+                                abi: Some(abi.symbol_unescaped),
+                            }),
+                        },
+                    });
                 }
 
                 self.visit_vis(&item.vis);
@@ -1259,12 +1218,16 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
             }
             ItemKind::Const(def, .., None) => {
                 self.check_defaultness(item.span, def);
-                let msg = "free constant item without body";
-                self.error_item_without_body(item.span, "constant", msg, " = <expr>;");
+                self.session.emit_err(ConstWithoutBody {
+                    span: item.span,
+                    replace_span: self.ending_semi_or_hi(item.span),
+                });
             }
             ItemKind::Static(.., None) => {
-                let msg = "free static item without body";
-                self.error_item_without_body(item.span, "static", msg, " = <expr>;");
+                self.session.emit_err(StaticWithoutBody {
+                    span: item.span,
+                    replace_span: self.ending_semi_or_hi(item.span),
+                });
             }
             ItemKind::TyAlias(box TyAlias {
                 defaultness,
@@ -1275,8 +1238,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
             }) => {
                 self.check_defaultness(item.span, defaultness);
                 if ty.is_none() {
-                    let msg = "free type alias without body";
-                    self.error_item_without_body(item.span, "type", msg, " = <type>;");
+                    self.session.emit_err(TyAliasWithoutBody {
+                        span: item.span,
+                        replace_span: self.ending_semi_or_hi(item.span),
+                    });
                 }
                 self.check_type_no_bounds(bounds, "this context");
                 if where_clauses.1.0 {
@@ -1580,10 +1545,20 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
         if ctxt == AssocCtxt::Impl {
             match &item.kind {
                 AssocItemKind::Const(_, _, body) => {
-                    self.check_impl_item_provided(item.span, body, "constant", " = <expr>;");
+                    if body.is_none() {
+                        self.session.emit_err(AssocConstWithoutBody {
+                            span: item.span,
+                            replace_span: self.ending_semi_or_hi(item.span),
+                        });
+                    }
                 }
                 AssocItemKind::Fn(box Fn { body, .. }) => {
-                    self.check_impl_item_provided(item.span, body, "function", " { <body> }");
+                    if body.is_none() {
+                        self.session.emit_err(AssocFnWithoutBody {
+                            span: item.span,
+                            replace_span: self.ending_semi_or_hi(item.span),
+                        });
+                    }
                 }
                 AssocItemKind::TyAlias(box TyAlias {
                     generics,
@@ -1593,7 +1568,12 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                     ty,
                     ..
                 }) => {
-                    self.check_impl_item_provided(item.span, ty, "type", " = <type>;");
+                    if ty.is_none() {
+                        self.session.emit_err(AssocTypeWithoutBody {
+                            span: item.span,
+                            replace_span: self.ending_semi_or_hi(item.span),
+                        });
+                    }
                     self.check_type_no_bounds(bounds, "`impl`s");
                     if ty.is_some() {
                         self.check_gat_where(
diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs
index 0287d71feb33e..1ac4dac10e2b3 100644
--- a/compiler/rustc_ast_passes/src/errors.rs
+++ b/compiler/rustc_ast_passes/src/errors.rs
@@ -1,7 +1,6 @@
 //! Errors emitted by ast_passes.
 
-use rustc_errors::fluent;
-use rustc_errors::{AddSubdiagnostic, Diagnostic};
+use rustc_errors::{fluent, AddSubdiagnostic, Applicability, Diagnostic};
 use rustc_macros::{SessionDiagnostic, SessionSubdiagnostic};
 use rustc_span::{Span, Symbol};
 
@@ -150,3 +149,100 @@ pub struct FnParamForbiddenSelf {
     #[label]
     pub span: Span,
 }
+
+#[derive(SessionDiagnostic)]
+#[error(ast_passes::forbidden_default)]
+pub struct ForbiddenDefault {
+    #[primary_span]
+    pub span: Span,
+    #[label]
+    pub def_span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[error(ast_passes::assoc_const_without_body)]
+pub struct AssocConstWithoutBody {
+    #[primary_span]
+    pub span: Span,
+    #[suggestion(code = " = <expr>;", applicability = "has-placeholders")]
+    pub replace_span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[error(ast_passes::assoc_fn_without_body)]
+pub struct AssocFnWithoutBody {
+    #[primary_span]
+    pub span: Span,
+    #[suggestion(code = " {{ <body> }}", applicability = "has-placeholders")]
+    pub replace_span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[error(ast_passes::assoc_type_without_body)]
+pub struct AssocTypeWithoutBody {
+    #[primary_span]
+    pub span: Span,
+    #[suggestion(code = " = <type>;", applicability = "has-placeholders")]
+    pub replace_span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[error(ast_passes::const_without_body)]
+pub struct ConstWithoutBody {
+    #[primary_span]
+    pub span: Span,
+    #[suggestion(code = " = <expr>;", applicability = "has-placeholders")]
+    pub replace_span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[error(ast_passes::static_without_body)]
+pub struct StaticWithoutBody {
+    #[primary_span]
+    pub span: Span,
+    #[suggestion(code = " = <expr>;", applicability = "has-placeholders")]
+    pub replace_span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[error(ast_passes::ty_alias_without_body)]
+pub struct TyAliasWithoutBody {
+    #[primary_span]
+    pub span: Span,
+    #[suggestion(code = " = <type>;", applicability = "has-placeholders")]
+    pub replace_span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[error(ast_passes::fn_without_body)]
+pub struct FnWithoutBody {
+    #[primary_span]
+    pub span: Span,
+    #[suggestion(code = " {{ <body> }}", applicability = "has-placeholders")]
+    pub replace_span: Span,
+    #[subdiagnostic]
+    pub extern_block_suggestion: Option<ExternBlockSuggestion>,
+}
+
+pub struct ExternBlockSuggestion {
+    pub start_span: Span,
+    pub end_span: Span,
+    pub abi: Option<Symbol>,
+}
+
+impl AddSubdiagnostic for ExternBlockSuggestion {
+    fn add_to_diagnostic(self, diag: &mut Diagnostic) {
+        let start_suggestion = if let Some(abi) = self.abi {
+            format!("extern \"{}\" {{", abi)
+        } else {
+            "extern {".to_owned()
+        };
+        let end_suggestion = " }".to_owned();
+
+        diag.multipart_suggestion(
+            fluent::ast_passes::extern_block_suggestion,
+            vec![(self.start_span, start_suggestion), (self.end_span, end_suggestion)],
+            Applicability::MaybeIncorrect,
+        );
+    }
+}
diff --git a/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl b/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl
index 77826f639f4dc..db91a886c725e 100644
--- a/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl
@@ -58,3 +58,36 @@ ast_passes_fn_param_forbidden_self =
     `self` parameter is only allowed in associated functions
     .label = not semantically valid as function parameter
     .note = associated functions are those in `impl` or `trait` definitions
+
+ast_passes_forbidden_default =
+    `default` is only allowed on items in trait impls
+    .label = `default` because of this
+
+ast_passes_assoc_const_without_body =
+    associated constant in `impl` without body
+    .suggestion = provide a definition for the constant
+
+ast_passes_assoc_fn_without_body =
+    associated function in `impl` without body
+    .suggestion = provide a definition for the function
+
+ast_passes_assoc_type_without_body =
+    associated type in `impl` without body
+    .suggestion = provide a definition for the type
+
+ast_passes_const_without_body =
+    free constant item without body
+    .suggestion = provide a definition for the constant
+
+ast_passes_static_without_body =
+    free static item without body
+    .suggestion = provide a definition for the static
+
+ast_passes_ty_alias_without_body =
+    free type alias without body
+    .suggestion = provide a definition for the type
+
+ast_passes_fn_without_body =
+    free function without a body
+    .suggestion = provide a definition for the function
+    .extern_block_suggestion = if you meant to declare an externally defined function, use an `extern` block

From 6a340741bde70856ece1cd99f61698e816436767 Mon Sep 17 00:00:00 2001
From: finalchild <finalchild2@gmail.com>
Date: Fri, 19 Aug 2022 03:36:43 +0900
Subject: [PATCH 21/23] Remove redundant clone

---
 compiler/rustc_builtin_macros/src/format.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs
index e76f5711b7b63..fd517c1e12136 100644
--- a/compiler/rustc_builtin_macros/src/format.rs
+++ b/compiler/rustc_builtin_macros/src/format.rs
@@ -1176,7 +1176,7 @@ fn create_lints_for_named_arguments_used_positionally(cx: &mut Context<'_, '_>)
 
         cx.ecx.buffered_early_lint.push(BufferedEarlyLint {
             span: MultiSpan::from_span(named_arg.positional_named_arg_span),
-            msg: msg.clone().into(),
+            msg: msg.into(),
             node_id: ast::CRATE_NODE_ID,
             lint_id: LintId::of(&NAMED_ARGUMENTS_USED_POSITIONALLY),
             diagnostic: BuiltinLintDiagnostics::NamedArgumentUsedPositionally {

From 70e0af632d0e3903616693dbe834da752ba26d4c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Park=20Jaeon=20=5B=ED=8C=8C=EC=B0=A8=5D?=
 <finalchild2@gmail.com>
Date: Sun, 21 Aug 2022 02:22:05 +0900
Subject: [PATCH 22/23] Fix incorrect return type of emit_fatal

Co-authored-by: Giacomo Stevanato <giaco.stevanato@gmail.com>
---
 compiler/rustc_session/src/session.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs
index 255d919eb1452..4972ae2014d50 100644
--- a/compiler/rustc_session/src/session.rs
+++ b/compiler/rustc_session/src/session.rs
@@ -488,7 +488,7 @@ impl Session {
     ) -> DiagnosticBuilder<'a, !> {
         self.parse_sess.create_fatal(fatal)
     }
-    pub fn emit_fatal<'a>(&'a self, fatal: impl SessionDiagnostic<'a, !>) {
+    pub fn emit_fatal<'a>(&'a self, fatal: impl SessionDiagnostic<'a, !>) -> ! {
         self.parse_sess.emit_fatal(fatal)
     }
     #[inline]

From 09d495cc15e3ef3e80fc36f0c217c08c5bfb34de Mon Sep 17 00:00:00 2001
From: finalchild <finalchild2@gmail.com>
Date: Mon, 22 Aug 2022 01:24:47 +0900
Subject: [PATCH 23/23] Replace #[error(..)] etc. to #[diag(..)]

---
 compiler/rustc_ast_passes/src/errors.rs | 46 ++++++++++++-------------
 1 file changed, 23 insertions(+), 23 deletions(-)

diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs
index 1ac4dac10e2b3..16ba14e909216 100644
--- a/compiler/rustc_ast_passes/src/errors.rs
+++ b/compiler/rustc_ast_passes/src/errors.rs
@@ -7,7 +7,7 @@ use rustc_span::{Span, Symbol};
 use crate::ast_validation::ForbiddenLetReason;
 
 #[derive(SessionDiagnostic)]
-#[error(ast_passes::forbidden_let)]
+#[diag(ast_passes::forbidden_let)]
 #[note]
 pub struct ForbiddenLet {
     #[primary_span]
@@ -31,21 +31,21 @@ impl AddSubdiagnostic for ForbiddenLetReason {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(ast_passes::forbidden_assoc_constraint)]
+#[diag(ast_passes::forbidden_assoc_constraint)]
 pub struct ForbiddenAssocConstraint {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(SessionDiagnostic)]
-#[error(ast_passes::keyword_lifetime)]
+#[diag(ast_passes::keyword_lifetime)]
 pub struct KeywordLifetime {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(SessionDiagnostic)]
-#[error(ast_passes::invalid_label)]
+#[diag(ast_passes::invalid_label)]
 pub struct InvalidLabel {
     #[primary_span]
     pub span: Span,
@@ -53,7 +53,7 @@ pub struct InvalidLabel {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(ast_passes::invalid_visibility, code = "E0449")]
+#[diag(ast_passes::invalid_visibility, code = "E0449")]
 pub struct InvalidVisibility {
     #[primary_span]
     pub span: Span,
@@ -72,7 +72,7 @@ pub enum InvalidVisibilityNote {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(ast_passes::trait_fn_async, code = "E0706")]
+#[diag(ast_passes::trait_fn_async, code = "E0706")]
 #[note]
 #[note(ast_passes::note2)]
 pub struct TraitFnAsync {
@@ -83,7 +83,7 @@ pub struct TraitFnAsync {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(ast_passes::trait_fn_const, code = "E0379")]
+#[diag(ast_passes::trait_fn_const, code = "E0379")]
 pub struct TraitFnConst {
     #[primary_span]
     #[label]
@@ -91,21 +91,21 @@ pub struct TraitFnConst {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(ast_passes::forbidden_lifetime_bound)]
+#[diag(ast_passes::forbidden_lifetime_bound)]
 pub struct ForbiddenLifetimeBound {
     #[primary_span]
     pub spans: Vec<Span>,
 }
 
 #[derive(SessionDiagnostic)]
-#[error(ast_passes::forbidden_non_lifetime_param)]
+#[diag(ast_passes::forbidden_non_lifetime_param)]
 pub struct ForbiddenNonLifetimeParam {
     #[primary_span]
     pub spans: Vec<Span>,
 }
 
 #[derive(SessionDiagnostic)]
-#[fatal(ast_passes::fn_param_too_many)]
+#[diag(ast_passes::fn_param_too_many)]
 pub struct FnParamTooMany {
     #[primary_span]
     pub span: Span,
@@ -113,21 +113,21 @@ pub struct FnParamTooMany {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(ast_passes::fn_param_c_var_args_only)]
+#[diag(ast_passes::fn_param_c_var_args_only)]
 pub struct FnParamCVarArgsOnly {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(SessionDiagnostic)]
-#[error(ast_passes::fn_param_c_var_args_not_last)]
+#[diag(ast_passes::fn_param_c_var_args_not_last)]
 pub struct FnParamCVarArgsNotLast {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(SessionDiagnostic)]
-#[error(ast_passes::fn_param_doc_comment)]
+#[diag(ast_passes::fn_param_doc_comment)]
 pub struct FnParamDocComment {
     #[primary_span]
     #[label]
@@ -135,14 +135,14 @@ pub struct FnParamDocComment {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(ast_passes::fn_param_forbidden_attr)]
+#[diag(ast_passes::fn_param_forbidden_attr)]
 pub struct FnParamForbiddenAttr {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(SessionDiagnostic)]
-#[error(ast_passes::fn_param_forbidden_self)]
+#[diag(ast_passes::fn_param_forbidden_self)]
 #[note]
 pub struct FnParamForbiddenSelf {
     #[primary_span]
@@ -151,7 +151,7 @@ pub struct FnParamForbiddenSelf {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(ast_passes::forbidden_default)]
+#[diag(ast_passes::forbidden_default)]
 pub struct ForbiddenDefault {
     #[primary_span]
     pub span: Span,
@@ -160,7 +160,7 @@ pub struct ForbiddenDefault {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(ast_passes::assoc_const_without_body)]
+#[diag(ast_passes::assoc_const_without_body)]
 pub struct AssocConstWithoutBody {
     #[primary_span]
     pub span: Span,
@@ -169,7 +169,7 @@ pub struct AssocConstWithoutBody {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(ast_passes::assoc_fn_without_body)]
+#[diag(ast_passes::assoc_fn_without_body)]
 pub struct AssocFnWithoutBody {
     #[primary_span]
     pub span: Span,
@@ -178,7 +178,7 @@ pub struct AssocFnWithoutBody {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(ast_passes::assoc_type_without_body)]
+#[diag(ast_passes::assoc_type_without_body)]
 pub struct AssocTypeWithoutBody {
     #[primary_span]
     pub span: Span,
@@ -187,7 +187,7 @@ pub struct AssocTypeWithoutBody {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(ast_passes::const_without_body)]
+#[diag(ast_passes::const_without_body)]
 pub struct ConstWithoutBody {
     #[primary_span]
     pub span: Span,
@@ -196,7 +196,7 @@ pub struct ConstWithoutBody {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(ast_passes::static_without_body)]
+#[diag(ast_passes::static_without_body)]
 pub struct StaticWithoutBody {
     #[primary_span]
     pub span: Span,
@@ -205,7 +205,7 @@ pub struct StaticWithoutBody {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(ast_passes::ty_alias_without_body)]
+#[diag(ast_passes::ty_alias_without_body)]
 pub struct TyAliasWithoutBody {
     #[primary_span]
     pub span: Span,
@@ -214,7 +214,7 @@ pub struct TyAliasWithoutBody {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(ast_passes::fn_without_body)]
+#[diag(ast_passes::fn_without_body)]
 pub struct FnWithoutBody {
     #[primary_span]
     pub span: Span,