From 7402eb001b7a49151b704d129be19ed325d2be72 Mon Sep 17 00:00:00 2001
From: EliseZeroTwo <mail@elise.moe>
Date: Mon, 25 Oct 2021 17:31:27 +0200
Subject: [PATCH 01/11] fix: inner attribute followed by outer attribute
 causing ICE

---
 compiler/rustc_ast/src/tokenstream.rs | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs
index 5d994dbad4d1f..51cabb50cd3de 100644
--- a/compiler/rustc_ast/src/tokenstream.rs
+++ b/compiler/rustc_ast/src/tokenstream.rs
@@ -221,12 +221,6 @@ impl AttrAnnotatedTokenStream {
                     for attr in &data.attrs {
                         match attr.style {
                             crate::AttrStyle::Outer => {
-                                assert!(
-                                    inner_attrs.len() == 0,
-                                    "Found outer attribute {:?} after inner attrs {:?}",
-                                    attr,
-                                    inner_attrs
-                                );
                                 outer_attrs.push(attr);
                             }
                             crate::AttrStyle::Inner => {

From 387675366868e19fe1a9542afa2738b8f9ca23de Mon Sep 17 00:00:00 2001
From: Jakob Degen <jakob@degen.com>
Date: Fri, 22 Oct 2021 23:21:46 -0400
Subject: [PATCH 02/11] Add diagnostic in case of failed `.try_into()` method
 call pre-Edition 2021

---
 compiler/rustc_typeck/src/check/method/suggest.rs | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs
index 183ebc559ae42..28b19981c2d40 100644
--- a/compiler/rustc_typeck/src/check/method/suggest.rs
+++ b/compiler/rustc_typeck/src/check/method/suggest.rs
@@ -1203,6 +1203,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             let mut candidates = valid_out_of_scope_traits;
             candidates.sort();
             candidates.dedup();
+
+            // `TryFrom` and `FromIterator` have no methods
+            let edition_fix = candidates
+                .iter()
+                .find(|did| self.tcx.is_diagnostic_item(sym::TryInto, **did))
+                .map(|&d| d);
+
             err.help("items from traits can only be used if the trait is in scope");
             let msg = format!(
                 "the following {traits_are} implemented but not in scope; \
@@ -1212,6 +1219,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             );
 
             self.suggest_use_candidates(err, msg, candidates);
+            if let Some(did) = edition_fix {
+                err.note(&format!(
+                    "'{}' is included in the prelude starting in Edition 2021",
+                    with_crate_prefix(|| self.tcx.def_path_str(did))
+                ));
+            }
+
             true
         } else {
             false

From e91d5ca197b966b841c4e49c921215a69f9d9c19 Mon Sep 17 00:00:00 2001
From: Jakob Degen <jakob@degen.com>
Date: Sun, 24 Oct 2021 21:09:52 -0400
Subject: [PATCH 03/11] Add test checking that Edition 2021 is suggested for
 .try_into() and fix other test

---
 .../future-prelude-collision-shadow.stderr    |  1 +
 .../suggest-tryinto-edition-change.rs         | 11 ++++++++++
 .../suggest-tryinto-edition-change.stderr     | 21 +++++++++++++++++++
 3 files changed, 33 insertions(+)
 create mode 100644 src/test/ui/suggestions/suggest-tryinto-edition-change.rs
 create mode 100644 src/test/ui/suggestions/suggest-tryinto-edition-change.stderr

diff --git a/src/test/ui/rust-2021/future-prelude-collision-shadow.stderr b/src/test/ui/rust-2021/future-prelude-collision-shadow.stderr
index e4662b430dccc..d945b4c94ca2f 100644
--- a/src/test/ui/rust-2021/future-prelude-collision-shadow.stderr
+++ b/src/test/ui/rust-2021/future-prelude-collision-shadow.stderr
@@ -15,6 +15,7 @@ LL |     fn try_into(self) -> Result<T, Self::Error>;
    |        the method is available for `Rc<u8>` here
    |
    = help: items from traits can only be used if the trait is in scope
+   = note: 'std::convert::TryInto' is included in the prelude starting in Edition 2021
 help: consider wrapping the receiver expression with the appropriate type
    |
 LL |         let _: u32 = Box::new(3u8).try_into().unwrap();
diff --git a/src/test/ui/suggestions/suggest-tryinto-edition-change.rs b/src/test/ui/suggestions/suggest-tryinto-edition-change.rs
new file mode 100644
index 0000000000000..f60ef587cfaad
--- /dev/null
+++ b/src/test/ui/suggestions/suggest-tryinto-edition-change.rs
@@ -0,0 +1,11 @@
+// Make sure that calling `.try_into()` in pre-2021 mentions Edition 2021 change
+// edition:2018
+
+fn test() {
+    let i: i16 = 0_i32.try_into().unwrap();
+    //~^ ERROR no method named `try_into` found for type `i32` in the current scope
+    //~| NOTE method not found in `i32`
+    //~| NOTE 'std::convert::TryInto' is included in the prelude starting in Edition 2021
+}
+
+fn main() {}
diff --git a/src/test/ui/suggestions/suggest-tryinto-edition-change.stderr b/src/test/ui/suggestions/suggest-tryinto-edition-change.stderr
new file mode 100644
index 0000000000000..7915937023c0f
--- /dev/null
+++ b/src/test/ui/suggestions/suggest-tryinto-edition-change.stderr
@@ -0,0 +1,21 @@
+error[E0599]: no method named `try_into` found for type `i32` in the current scope
+  --> $DIR/suggest-tryinto-edition-change.rs:5:24
+   |
+LL |     let i: i16 = 0_i32.try_into().unwrap();
+   |                        ^^^^^^^^ method not found in `i32`
+   |
+  ::: $SRC_DIR/core/src/convert/mod.rs:LL:COL
+   |
+LL |     fn try_into(self) -> Result<T, Self::Error>;
+   |        -------- the method is available for `i32` here
+   |
+   = help: items from traits can only be used if the trait is in scope
+   = note: 'std::convert::TryInto' is included in the prelude starting in Edition 2021
+help: the following trait is implemented but not in scope; perhaps add a `use` for it:
+   |
+LL | use std::convert::TryInto;
+   |
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0599`.

From 958e64594672ccd11fba5ec6925e33ef223301ee Mon Sep 17 00:00:00 2001
From: Jakob Degen <jakob@degen.com>
Date: Mon, 25 Oct 2021 20:04:35 -0400
Subject: [PATCH 04/11] Adds hint if a trait fails to resolve and a newly added
 one in Edition 2021 is suggested

---
 compiler/rustc_resolve/src/diagnostics.rs     | 57 ++++++++++++++--
 .../rustc_resolve/src/late/diagnostics.rs     |  1 +
 .../suggest-tryinto-edition-change.rs         | 26 +++++++-
 .../suggest-tryinto-edition-change.stderr     | 65 +++++++++++++++++--
 4 files changed, 134 insertions(+), 15 deletions(-)

diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index f94266c3aeaf0..57acca16d94a8 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -66,6 +66,8 @@ crate struct ImportSuggestion {
     pub descr: &'static str,
     pub path: Path,
     pub accessible: bool,
+    /// An extra note that should be issued if this item is suggested
+    pub note: Option<String>,
 }
 
 /// Adjust the impl span so that just the `impl` keyword is taken by removing
@@ -872,11 +874,38 @@ impl<'a> Resolver<'a> {
                         }
 
                         if candidates.iter().all(|v: &ImportSuggestion| v.did != did) {
+                            // See if we're recommending TryFrom, TryInto, or FromIterator and add
+                            // a note about editions
+                            let note = if let Some(did) = did {
+                                let requires_note = !did.is_local()
+                                    && this.cstore().item_attrs(did, this.session).iter().any(
+                                        |attr| {
+                                            if attr.has_name(sym::rustc_diagnostic_item) {
+                                                [sym::TryInto, sym::TryFrom, sym::FromIterator]
+                                                    .map(|x| Some(x))
+                                                    .contains(&attr.value_str())
+                                            } else {
+                                                false
+                                            }
+                                        },
+                                    );
+
+                                requires_note.then(|| {
+                                    format!(
+                                        "'{}' is included in the prelude starting in Edition 2021",
+                                        path_names_to_string(&path)
+                                    )
+                                })
+                            } else {
+                                None
+                            };
+
                             candidates.push(ImportSuggestion {
                                 did,
                                 descr: res.descr(),
                                 path,
                                 accessible: child_accessible,
+                                note,
                             });
                         }
                     }
@@ -1764,12 +1793,14 @@ crate fn show_candidates(
         return;
     }
 
-    let mut accessible_path_strings: Vec<(String, &str, Option<DefId>)> = Vec::new();
-    let mut inaccessible_path_strings: Vec<(String, &str, Option<DefId>)> = Vec::new();
+    let mut accessible_path_strings: Vec<(String, &str, Option<DefId>, &Option<String>)> =
+        Vec::new();
+    let mut inaccessible_path_strings: Vec<(String, &str, Option<DefId>, &Option<String>)> =
+        Vec::new();
 
     candidates.iter().for_each(|c| {
         (if c.accessible { &mut accessible_path_strings } else { &mut inaccessible_path_strings })
-            .push((path_names_to_string(&c.path), c.descr, c.did))
+            .push((path_names_to_string(&c.path), c.descr, c.did, &c.note))
     });
 
     // we want consistent results across executions, but candidates are produced
@@ -1792,6 +1823,11 @@ crate fn show_candidates(
         let instead = if instead { " instead" } else { "" };
         let mut msg = format!("consider importing {} {}{}", determiner, kind, instead);
 
+        // Issue notes
+        for note in accessible_path_strings.iter().map(|cand| cand.3.as_ref()).flatten() {
+            err.note(note);
+        }
+
         if let Some(span) = use_placement_span {
             for candidate in &mut accessible_path_strings {
                 // produce an additional newline to separate the new use statement
@@ -1820,7 +1856,7 @@ crate fn show_candidates(
         assert!(!inaccessible_path_strings.is_empty());
 
         if inaccessible_path_strings.len() == 1 {
-            let (name, descr, def_id) = &inaccessible_path_strings[0];
+            let (name, descr, def_id, note) = &inaccessible_path_strings[0];
             let msg = format!("{} `{}` exists but is inaccessible", descr, name);
 
             if let Some(local_def_id) = def_id.and_then(|did| did.as_local()) {
@@ -1832,12 +1868,15 @@ crate fn show_candidates(
             } else {
                 err.note(&msg);
             }
+            if let Some(note) = (*note).as_deref() {
+                err.note(note);
+            }
         } else {
-            let (_, descr_first, _) = &inaccessible_path_strings[0];
+            let (_, descr_first, _, _) = &inaccessible_path_strings[0];
             let descr = if inaccessible_path_strings
                 .iter()
                 .skip(1)
-                .all(|(_, descr, _)| descr == descr_first)
+                .all(|(_, descr, _, _)| descr == descr_first)
             {
                 descr_first.to_string()
             } else {
@@ -1848,7 +1887,7 @@ crate fn show_candidates(
             let mut has_colon = false;
 
             let mut spans = Vec::new();
-            for (name, _, def_id) in &inaccessible_path_strings {
+            for (name, _, def_id, _) in &inaccessible_path_strings {
                 if let Some(local_def_id) = def_id.and_then(|did| did.as_local()) {
                     let span = definitions.def_span(local_def_id);
                     let span = session.source_map().guess_head_span(span);
@@ -1868,6 +1907,10 @@ crate fn show_candidates(
                 multi_span.push_span_label(span, format!("`{}`: not accessible", name));
             }
 
+            for note in inaccessible_path_strings.iter().map(|cand| cand.3.as_ref()).flatten() {
+                err.note(note);
+            }
+
             err.span_note(multi_span, &msg);
         }
     }
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index 1748a9be8e13e..5f90fcdfa64e2 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -1502,6 +1502,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
                                 descr: "module",
                                 path,
                                 accessible: true,
+                                note: None,
                             },
                         ));
                     } else {
diff --git a/src/test/ui/suggestions/suggest-tryinto-edition-change.rs b/src/test/ui/suggestions/suggest-tryinto-edition-change.rs
index f60ef587cfaad..f03b42bbe4751 100644
--- a/src/test/ui/suggestions/suggest-tryinto-edition-change.rs
+++ b/src/test/ui/suggestions/suggest-tryinto-edition-change.rs
@@ -1,11 +1,31 @@
-// Make sure that calling `.try_into()` in pre-2021 mentions Edition 2021 change
+// Make sure that trying to access `TryInto`, `TryFrom`, `FromIterator` in pre-2021 mentions
+// Edition 2021 change
 // edition:2018
 
 fn test() {
-    let i: i16 = 0_i32.try_into().unwrap();
+    let _i: i16 = 0_i32.try_into().unwrap();
     //~^ ERROR no method named `try_into` found for type `i32` in the current scope
     //~| NOTE method not found in `i32`
     //~| NOTE 'std::convert::TryInto' is included in the prelude starting in Edition 2021
+
+    let _i: i16 = TryFrom::try_from(0_i32).unwrap();
+    //~^ ERROR failed to resolve: use of undeclared type
+    //~| NOTE not found in this scope
+    //~| NOTE 'std::convert::TryFrom' is included in the prelude starting in Edition 2021
+    //~| NOTE 'core::convert::TryFrom' is included in the prelude starting in Edition 2021
+
+    let _i: i16 = TryInto::try_into(0_i32).unwrap();
+    //~^ ERROR failed to resolve: use of undeclared type
+    //~| NOTE not found in this scope
+    //~| NOTE 'std::convert::TryInto' is included in the prelude starting in Edition 2021
+    //~| NOTE 'core::convert::TryInto' is included in the prelude starting in Edition 2021
+
+    let _v: Vec<_> = FromIterator::from_iter(&[1]);
+    //~^ ERROR failed to resolve: use of undeclared type
+    //~| NOTE 'std::iter::FromIterator' is included in the prelude starting in Edition 2021
+    //~| NOTE 'core::iter::FromIterator' is included in the prelude starting in Edition 2021
 }
 
-fn main() {}
+fn main() {
+    test();
+}
diff --git a/src/test/ui/suggestions/suggest-tryinto-edition-change.stderr b/src/test/ui/suggestions/suggest-tryinto-edition-change.stderr
index 7915937023c0f..80191ec4fd7b4 100644
--- a/src/test/ui/suggestions/suggest-tryinto-edition-change.stderr
+++ b/src/test/ui/suggestions/suggest-tryinto-edition-change.stderr
@@ -1,8 +1,62 @@
+error[E0433]: failed to resolve: use of undeclared type `TryFrom`
+  --> $DIR/suggest-tryinto-edition-change.rs:11:19
+   |
+LL |     let _i: i16 = TryFrom::try_from(0_i32).unwrap();
+   |                   ^^^^^^^ not found in this scope
+   |
+   = note: 'std::convert::TryFrom' is included in the prelude starting in Edition 2021
+   = note: 'core::convert::TryFrom' is included in the prelude starting in Edition 2021
+help: consider importing one of these items
+   |
+LL | use std::convert::TryFrom;
+   |
+LL | use core::convert::TryFrom;
+   |
+
+error[E0433]: failed to resolve: use of undeclared type `TryInto`
+  --> $DIR/suggest-tryinto-edition-change.rs:17:19
+   |
+LL |     let _i: i16 = TryInto::try_into(0_i32).unwrap();
+   |                   ^^^^^^^ not found in this scope
+   |
+   = note: 'std::convert::TryInto' is included in the prelude starting in Edition 2021
+   = note: 'core::convert::TryInto' is included in the prelude starting in Edition 2021
+help: consider importing one of these items
+   |
+LL | use std::convert::TryInto;
+   |
+LL | use core::convert::TryInto;
+   |
+
+error[E0433]: failed to resolve: use of undeclared type `FromIterator`
+  --> $DIR/suggest-tryinto-edition-change.rs:23:22
+   |
+LL |     let _v: Vec<_> = FromIterator::from_iter(&[1]);
+   |                      ^^^^^^^^^^^^
+   |
+  ::: $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+   |
+LL | pub trait IntoIterator {
+   | ---------------------- similarly named trait `IntoIterator` defined here
+   |
+   = note: 'std::iter::FromIterator' is included in the prelude starting in Edition 2021
+   = note: 'core::iter::FromIterator' is included in the prelude starting in Edition 2021
+help: a trait with a similar name exists
+   |
+LL |     let _v: Vec<_> = IntoIterator::from_iter(&[1]);
+   |                      ~~~~~~~~~~~~
+help: consider importing one of these items
+   |
+LL | use std::iter::FromIterator;
+   |
+LL | use core::iter::FromIterator;
+   |
+
 error[E0599]: no method named `try_into` found for type `i32` in the current scope
-  --> $DIR/suggest-tryinto-edition-change.rs:5:24
+  --> $DIR/suggest-tryinto-edition-change.rs:6:25
    |
-LL |     let i: i16 = 0_i32.try_into().unwrap();
-   |                        ^^^^^^^^ method not found in `i32`
+LL |     let _i: i16 = 0_i32.try_into().unwrap();
+   |                         ^^^^^^^^ method not found in `i32`
    |
   ::: $SRC_DIR/core/src/convert/mod.rs:LL:COL
    |
@@ -16,6 +70,7 @@ help: the following trait is implemented but not in scope; perhaps add a `use` f
 LL | use std::convert::TryInto;
    |
 
-error: aborting due to previous error
+error: aborting due to 4 previous errors
 
-For more information about this error, try `rustc --explain E0599`.
+Some errors have detailed explanations: E0433, E0599.
+For more information about an error, try `rustc --explain E0433`.

From 6ce3ae4b73b678c8c50fc9844ede20aaa214ad10 Mon Sep 17 00:00:00 2001
From: Jakob Degen <jakob@degen.com>
Date: Mon, 25 Oct 2021 22:56:18 -0400
Subject: [PATCH 05/11] Make `ui/suggestions/suggest-tryinto-edition-change.rs`
 no_std to avoid getting inconsistent output between local and CI.

---
 .../suggest-tryinto-edition-change.rs         | 24 +++++-----
 .../suggest-tryinto-edition-change.stderr     | 47 ++++++++-----------
 2 files changed, 30 insertions(+), 41 deletions(-)

diff --git a/src/test/ui/suggestions/suggest-tryinto-edition-change.rs b/src/test/ui/suggestions/suggest-tryinto-edition-change.rs
index f03b42bbe4751..e62990144c4c3 100644
--- a/src/test/ui/suggestions/suggest-tryinto-edition-change.rs
+++ b/src/test/ui/suggestions/suggest-tryinto-edition-change.rs
@@ -2,30 +2,28 @@
 // Edition 2021 change
 // edition:2018
 
-fn test() {
-    let _i: i16 = 0_i32.try_into().unwrap();
+// We mark this no_std to avoid emitting suggestions for both `std` and `core` traits. These were
+// inconsistently ordered between CI and at least one local build, causing test failures.
+#![no_std]
+#![crate_type = "lib"]
+
+pub fn test() {
+    let _i: Result<i16, _> = 0_i32.try_into();
     //~^ ERROR no method named `try_into` found for type `i32` in the current scope
     //~| NOTE method not found in `i32`
-    //~| NOTE 'std::convert::TryInto' is included in the prelude starting in Edition 2021
+    //~| NOTE 'core::convert::TryInto' is included in the prelude starting in Edition 2021
 
-    let _i: i16 = TryFrom::try_from(0_i32).unwrap();
+    let _i: Result<i16, _> = TryFrom::try_from(0_i32);
     //~^ ERROR failed to resolve: use of undeclared type
     //~| NOTE not found in this scope
-    //~| NOTE 'std::convert::TryFrom' is included in the prelude starting in Edition 2021
     //~| NOTE 'core::convert::TryFrom' is included in the prelude starting in Edition 2021
 
-    let _i: i16 = TryInto::try_into(0_i32).unwrap();
+    let _i: Result<i16, _> = TryInto::try_into(0_i32);
     //~^ ERROR failed to resolve: use of undeclared type
     //~| NOTE not found in this scope
-    //~| NOTE 'std::convert::TryInto' is included in the prelude starting in Edition 2021
     //~| NOTE 'core::convert::TryInto' is included in the prelude starting in Edition 2021
 
-    let _v: Vec<_> = FromIterator::from_iter(&[1]);
+    let _i: () = FromIterator::from_iter(core::iter::empty());
     //~^ ERROR failed to resolve: use of undeclared type
-    //~| NOTE 'std::iter::FromIterator' is included in the prelude starting in Edition 2021
     //~| NOTE 'core::iter::FromIterator' is included in the prelude starting in Edition 2021
 }
-
-fn main() {
-    test();
-}
diff --git a/src/test/ui/suggestions/suggest-tryinto-edition-change.stderr b/src/test/ui/suggestions/suggest-tryinto-edition-change.stderr
index 80191ec4fd7b4..e7013063d4524 100644
--- a/src/test/ui/suggestions/suggest-tryinto-edition-change.stderr
+++ b/src/test/ui/suggestions/suggest-tryinto-edition-change.stderr
@@ -1,62 +1,53 @@
 error[E0433]: failed to resolve: use of undeclared type `TryFrom`
-  --> $DIR/suggest-tryinto-edition-change.rs:11:19
+  --> $DIR/suggest-tryinto-edition-change.rs:14:30
    |
-LL |     let _i: i16 = TryFrom::try_from(0_i32).unwrap();
-   |                   ^^^^^^^ not found in this scope
+LL |     let _i: Result<i16, _> = TryFrom::try_from(0_i32);
+   |                              ^^^^^^^ not found in this scope
    |
-   = note: 'std::convert::TryFrom' is included in the prelude starting in Edition 2021
    = note: 'core::convert::TryFrom' is included in the prelude starting in Edition 2021
-help: consider importing one of these items
-   |
-LL | use std::convert::TryFrom;
+help: consider importing this trait
    |
 LL | use core::convert::TryFrom;
    |
 
 error[E0433]: failed to resolve: use of undeclared type `TryInto`
-  --> $DIR/suggest-tryinto-edition-change.rs:17:19
+  --> $DIR/suggest-tryinto-edition-change.rs:19:30
    |
-LL |     let _i: i16 = TryInto::try_into(0_i32).unwrap();
-   |                   ^^^^^^^ not found in this scope
+LL |     let _i: Result<i16, _> = TryInto::try_into(0_i32);
+   |                              ^^^^^^^ not found in this scope
    |
-   = note: 'std::convert::TryInto' is included in the prelude starting in Edition 2021
    = note: 'core::convert::TryInto' is included in the prelude starting in Edition 2021
-help: consider importing one of these items
-   |
-LL | use std::convert::TryInto;
+help: consider importing this trait
    |
 LL | use core::convert::TryInto;
    |
 
 error[E0433]: failed to resolve: use of undeclared type `FromIterator`
-  --> $DIR/suggest-tryinto-edition-change.rs:23:22
+  --> $DIR/suggest-tryinto-edition-change.rs:24:18
    |
-LL |     let _v: Vec<_> = FromIterator::from_iter(&[1]);
-   |                      ^^^^^^^^^^^^
+LL |     let _i: () = FromIterator::from_iter(core::iter::empty());
+   |                  ^^^^^^^^^^^^
    |
   ::: $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
    |
 LL | pub trait IntoIterator {
    | ---------------------- similarly named trait `IntoIterator` defined here
    |
-   = note: 'std::iter::FromIterator' is included in the prelude starting in Edition 2021
    = note: 'core::iter::FromIterator' is included in the prelude starting in Edition 2021
 help: a trait with a similar name exists
    |
-LL |     let _v: Vec<_> = IntoIterator::from_iter(&[1]);
-   |                      ~~~~~~~~~~~~
-help: consider importing one of these items
-   |
-LL | use std::iter::FromIterator;
+LL |     let _i: () = IntoIterator::from_iter(core::iter::empty());
+   |                  ~~~~~~~~~~~~
+help: consider importing this trait
    |
 LL | use core::iter::FromIterator;
    |
 
 error[E0599]: no method named `try_into` found for type `i32` in the current scope
-  --> $DIR/suggest-tryinto-edition-change.rs:6:25
+  --> $DIR/suggest-tryinto-edition-change.rs:9:36
    |
-LL |     let _i: i16 = 0_i32.try_into().unwrap();
-   |                         ^^^^^^^^ method not found in `i32`
+LL |     let _i: Result<i16, _> = 0_i32.try_into();
+   |                                    ^^^^^^^^ method not found in `i32`
    |
   ::: $SRC_DIR/core/src/convert/mod.rs:LL:COL
    |
@@ -64,10 +55,10 @@ LL |     fn try_into(self) -> Result<T, Self::Error>;
    |        -------- the method is available for `i32` here
    |
    = help: items from traits can only be used if the trait is in scope
-   = note: 'std::convert::TryInto' is included in the prelude starting in Edition 2021
+   = note: 'core::convert::TryInto' is included in the prelude starting in Edition 2021
 help: the following trait is implemented but not in scope; perhaps add a `use` for it:
    |
-LL | use std::convert::TryInto;
+LL | use core::convert::TryInto;
    |
 
 error: aborting due to 4 previous errors

From e41ef3643596440f459cfd6ec1b4997f9d123dc2 Mon Sep 17 00:00:00 2001
From: Jakob Degen <jakob@degen.com>
Date: Mon, 25 Oct 2021 23:14:48 -0400
Subject: [PATCH 06/11] Fix line numbers in test

---
 .../ui/suggestions/suggest-tryinto-edition-change.stderr  | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/test/ui/suggestions/suggest-tryinto-edition-change.stderr b/src/test/ui/suggestions/suggest-tryinto-edition-change.stderr
index e7013063d4524..e27c532dcf0e8 100644
--- a/src/test/ui/suggestions/suggest-tryinto-edition-change.stderr
+++ b/src/test/ui/suggestions/suggest-tryinto-edition-change.stderr
@@ -1,5 +1,5 @@
 error[E0433]: failed to resolve: use of undeclared type `TryFrom`
-  --> $DIR/suggest-tryinto-edition-change.rs:14:30
+  --> $DIR/suggest-tryinto-edition-change.rs:16:30
    |
 LL |     let _i: Result<i16, _> = TryFrom::try_from(0_i32);
    |                              ^^^^^^^ not found in this scope
@@ -11,7 +11,7 @@ LL | use core::convert::TryFrom;
    |
 
 error[E0433]: failed to resolve: use of undeclared type `TryInto`
-  --> $DIR/suggest-tryinto-edition-change.rs:19:30
+  --> $DIR/suggest-tryinto-edition-change.rs:21:30
    |
 LL |     let _i: Result<i16, _> = TryInto::try_into(0_i32);
    |                              ^^^^^^^ not found in this scope
@@ -23,7 +23,7 @@ LL | use core::convert::TryInto;
    |
 
 error[E0433]: failed to resolve: use of undeclared type `FromIterator`
-  --> $DIR/suggest-tryinto-edition-change.rs:24:18
+  --> $DIR/suggest-tryinto-edition-change.rs:26:18
    |
 LL |     let _i: () = FromIterator::from_iter(core::iter::empty());
    |                  ^^^^^^^^^^^^
@@ -44,7 +44,7 @@ LL | use core::iter::FromIterator;
    |
 
 error[E0599]: no method named `try_into` found for type `i32` in the current scope
-  --> $DIR/suggest-tryinto-edition-change.rs:9:36
+  --> $DIR/suggest-tryinto-edition-change.rs:11:36
    |
 LL |     let _i: Result<i16, _> = 0_i32.try_into();
    |                                    ^^^^^^^^ method not found in `i32`

From cb336f1f677374e463ffa1a1fcc32ce398cb4cbe Mon Sep 17 00:00:00 2001
From: Jakob Degen <jakob@degen.com>
Date: Tue, 26 Oct 2021 21:18:04 -0400
Subject: [PATCH 07/11] Reverting switching test to no_std and adjust output
 after rebase.

---
 compiler/rustc_resolve/src/diagnostics.rs     |  1 -
 .../suggest-tryinto-edition-change.rs         | 24 +++++-----
 .../suggest-tryinto-edition-change.stderr     | 47 +++++++++++--------
 3 files changed, 41 insertions(+), 31 deletions(-)

diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index 57acca16d94a8..ccfab263bd48e 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -1823,7 +1823,6 @@ crate fn show_candidates(
         let instead = if instead { " instead" } else { "" };
         let mut msg = format!("consider importing {} {}{}", determiner, kind, instead);
 
-        // Issue notes
         for note in accessible_path_strings.iter().map(|cand| cand.3.as_ref()).flatten() {
             err.note(note);
         }
diff --git a/src/test/ui/suggestions/suggest-tryinto-edition-change.rs b/src/test/ui/suggestions/suggest-tryinto-edition-change.rs
index e62990144c4c3..f03b42bbe4751 100644
--- a/src/test/ui/suggestions/suggest-tryinto-edition-change.rs
+++ b/src/test/ui/suggestions/suggest-tryinto-edition-change.rs
@@ -2,28 +2,30 @@
 // Edition 2021 change
 // edition:2018
 
-// We mark this no_std to avoid emitting suggestions for both `std` and `core` traits. These were
-// inconsistently ordered between CI and at least one local build, causing test failures.
-#![no_std]
-#![crate_type = "lib"]
-
-pub fn test() {
-    let _i: Result<i16, _> = 0_i32.try_into();
+fn test() {
+    let _i: i16 = 0_i32.try_into().unwrap();
     //~^ ERROR no method named `try_into` found for type `i32` in the current scope
     //~| NOTE method not found in `i32`
-    //~| NOTE 'core::convert::TryInto' is included in the prelude starting in Edition 2021
+    //~| NOTE 'std::convert::TryInto' is included in the prelude starting in Edition 2021
 
-    let _i: Result<i16, _> = TryFrom::try_from(0_i32);
+    let _i: i16 = TryFrom::try_from(0_i32).unwrap();
     //~^ ERROR failed to resolve: use of undeclared type
     //~| NOTE not found in this scope
+    //~| NOTE 'std::convert::TryFrom' is included in the prelude starting in Edition 2021
     //~| NOTE 'core::convert::TryFrom' is included in the prelude starting in Edition 2021
 
-    let _i: Result<i16, _> = TryInto::try_into(0_i32);
+    let _i: i16 = TryInto::try_into(0_i32).unwrap();
     //~^ ERROR failed to resolve: use of undeclared type
     //~| NOTE not found in this scope
+    //~| NOTE 'std::convert::TryInto' is included in the prelude starting in Edition 2021
     //~| NOTE 'core::convert::TryInto' is included in the prelude starting in Edition 2021
 
-    let _i: () = FromIterator::from_iter(core::iter::empty());
+    let _v: Vec<_> = FromIterator::from_iter(&[1]);
     //~^ ERROR failed to resolve: use of undeclared type
+    //~| NOTE 'std::iter::FromIterator' is included in the prelude starting in Edition 2021
     //~| NOTE 'core::iter::FromIterator' is included in the prelude starting in Edition 2021
 }
+
+fn main() {
+    test();
+}
diff --git a/src/test/ui/suggestions/suggest-tryinto-edition-change.stderr b/src/test/ui/suggestions/suggest-tryinto-edition-change.stderr
index e27c532dcf0e8..86f48716b16b5 100644
--- a/src/test/ui/suggestions/suggest-tryinto-edition-change.stderr
+++ b/src/test/ui/suggestions/suggest-tryinto-edition-change.stderr
@@ -1,53 +1,62 @@
 error[E0433]: failed to resolve: use of undeclared type `TryFrom`
-  --> $DIR/suggest-tryinto-edition-change.rs:16:30
+  --> $DIR/suggest-tryinto-edition-change.rs:11:19
    |
-LL |     let _i: Result<i16, _> = TryFrom::try_from(0_i32);
-   |                              ^^^^^^^ not found in this scope
+LL |     let _i: i16 = TryFrom::try_from(0_i32).unwrap();
+   |                   ^^^^^^^ not found in this scope
    |
+   = note: 'std::convert::TryFrom' is included in the prelude starting in Edition 2021
    = note: 'core::convert::TryFrom' is included in the prelude starting in Edition 2021
-help: consider importing this trait
+help: consider importing one of these items
    |
 LL | use core::convert::TryFrom;
    |
+LL | use std::convert::TryFrom;
+   |
 
 error[E0433]: failed to resolve: use of undeclared type `TryInto`
-  --> $DIR/suggest-tryinto-edition-change.rs:21:30
+  --> $DIR/suggest-tryinto-edition-change.rs:17:19
    |
-LL |     let _i: Result<i16, _> = TryInto::try_into(0_i32);
-   |                              ^^^^^^^ not found in this scope
+LL |     let _i: i16 = TryInto::try_into(0_i32).unwrap();
+   |                   ^^^^^^^ not found in this scope
    |
+   = note: 'std::convert::TryInto' is included in the prelude starting in Edition 2021
    = note: 'core::convert::TryInto' is included in the prelude starting in Edition 2021
-help: consider importing this trait
+help: consider importing one of these items
    |
 LL | use core::convert::TryInto;
    |
+LL | use std::convert::TryInto;
+   |
 
 error[E0433]: failed to resolve: use of undeclared type `FromIterator`
-  --> $DIR/suggest-tryinto-edition-change.rs:26:18
+  --> $DIR/suggest-tryinto-edition-change.rs:23:22
    |
-LL |     let _i: () = FromIterator::from_iter(core::iter::empty());
-   |                  ^^^^^^^^^^^^
+LL |     let _v: Vec<_> = FromIterator::from_iter(&[1]);
+   |                      ^^^^^^^^^^^^
    |
   ::: $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
    |
 LL | pub trait IntoIterator {
    | ---------------------- similarly named trait `IntoIterator` defined here
    |
+   = note: 'std::iter::FromIterator' is included in the prelude starting in Edition 2021
    = note: 'core::iter::FromIterator' is included in the prelude starting in Edition 2021
 help: a trait with a similar name exists
    |
-LL |     let _i: () = IntoIterator::from_iter(core::iter::empty());
-   |                  ~~~~~~~~~~~~
-help: consider importing this trait
+LL |     let _v: Vec<_> = IntoIterator::from_iter(&[1]);
+   |                      ~~~~~~~~~~~~
+help: consider importing one of these items
    |
 LL | use core::iter::FromIterator;
    |
+LL | use std::iter::FromIterator;
+   |
 
 error[E0599]: no method named `try_into` found for type `i32` in the current scope
-  --> $DIR/suggest-tryinto-edition-change.rs:11:36
+  --> $DIR/suggest-tryinto-edition-change.rs:6:25
    |
-LL |     let _i: Result<i16, _> = 0_i32.try_into();
-   |                                    ^^^^^^^^ method not found in `i32`
+LL |     let _i: i16 = 0_i32.try_into().unwrap();
+   |                         ^^^^^^^^ method not found in `i32`
    |
   ::: $SRC_DIR/core/src/convert/mod.rs:LL:COL
    |
@@ -55,10 +64,10 @@ LL |     fn try_into(self) -> Result<T, Self::Error>;
    |        -------- the method is available for `i32` here
    |
    = help: items from traits can only be used if the trait is in scope
-   = note: 'core::convert::TryInto' is included in the prelude starting in Edition 2021
+   = note: 'std::convert::TryInto' is included in the prelude starting in Edition 2021
 help: the following trait is implemented but not in scope; perhaps add a `use` for it:
    |
-LL | use core::convert::TryInto;
+LL | use std::convert::TryInto;
    |
 
 error: aborting due to 4 previous errors

From dae7c36b4277b9df180e02a99c4615a5b1e601e8 Mon Sep 17 00:00:00 2001
From: Bram van den Heuvel <bram@vandenheuvel.online>
Date: Tue, 26 Oct 2021 12:33:49 +0200
Subject: [PATCH 08/11] Add regression test for #75961

---
 src/test/ui/trait-bounds/issue-75961.rs | 7 +++++++
 1 file changed, 7 insertions(+)
 create mode 100644 src/test/ui/trait-bounds/issue-75961.rs

diff --git a/src/test/ui/trait-bounds/issue-75961.rs b/src/test/ui/trait-bounds/issue-75961.rs
new file mode 100644
index 0000000000000..367eac7182a26
--- /dev/null
+++ b/src/test/ui/trait-bounds/issue-75961.rs
@@ -0,0 +1,7 @@
+// check-pass
+
+pub fn foo<'a>(s: &'a mut ()) where &'a mut (): Clone {
+    <&mut () as Clone>::clone(&s);
+}
+
+fn main() {}

From 7f0d43a003a70ce4cc12d8239e379feb5e5e48f8 Mon Sep 17 00:00:00 2001
From: EliseZeroTwo <mail@elise.moe>
Date: Tue, 26 Oct 2021 11:45:15 +0200
Subject: [PATCH 09/11] test: add test for inner attribute followed by outer
 attribute causing ICE

---
 ...9971-outer-attr-following-inner-attr-ice.rs | 13 +++++++++++++
 ...9971-outer-attr-following-inner-attr-ice.rs | 15 +++++++++++++++
 ...-outer-attr-following-inner-attr-ice.stderr | 18 ++++++++++++++++++
 3 files changed, 46 insertions(+)
 create mode 100644 src/test/ui/parser/auxiliary/issue-89971-outer-attr-following-inner-attr-ice.rs
 create mode 100644 src/test/ui/parser/issue-89971-outer-attr-following-inner-attr-ice.rs
 create mode 100644 src/test/ui/parser/issue-89971-outer-attr-following-inner-attr-ice.stderr

diff --git a/src/test/ui/parser/auxiliary/issue-89971-outer-attr-following-inner-attr-ice.rs b/src/test/ui/parser/auxiliary/issue-89971-outer-attr-following-inner-attr-ice.rs
new file mode 100644
index 0000000000000..e5604b816b5e9
--- /dev/null
+++ b/src/test/ui/parser/auxiliary/issue-89971-outer-attr-following-inner-attr-ice.rs
@@ -0,0 +1,13 @@
+// force-host
+// no-prefer-dynamic
+
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+
+use proc_macro::TokenStream;
+
+#[proc_macro_derive(ICE)]
+pub fn derive(_: TokenStream) -> TokenStream {
+    r#"#[allow(missing_docs)] struct X { }"#.parse().unwrap()
+}
diff --git a/src/test/ui/parser/issue-89971-outer-attr-following-inner-attr-ice.rs b/src/test/ui/parser/issue-89971-outer-attr-following-inner-attr-ice.rs
new file mode 100644
index 0000000000000..fe67d9822fc9c
--- /dev/null
+++ b/src/test/ui/parser/issue-89971-outer-attr-following-inner-attr-ice.rs
@@ -0,0 +1,15 @@
+// aux-build:issue-89971-outer-attr-following-inner-attr-ice.rs
+
+#[macro_use]
+extern crate issue_89971_outer_attr_following_inner_attr_ice;
+
+fn main() {
+    Mew();
+    X {};
+}
+
+#![deny(missing_docs)]
+//~^ ERROR an inner attribute is not permitted in this context
+#[derive(ICE)]
+#[deny(missing_docs)]
+struct Mew();
diff --git a/src/test/ui/parser/issue-89971-outer-attr-following-inner-attr-ice.stderr b/src/test/ui/parser/issue-89971-outer-attr-following-inner-attr-ice.stderr
new file mode 100644
index 0000000000000..34a6ab00d7b2d
--- /dev/null
+++ b/src/test/ui/parser/issue-89971-outer-attr-following-inner-attr-ice.stderr
@@ -0,0 +1,18 @@
+error: an inner attribute is not permitted in this context
+  --> $DIR/issue-89971-outer-attr-following-inner-attr-ice.rs:11:1
+   |
+LL | #![deny(missing_docs)]
+   | ^^^^^^^^^^^^^^^^^^^^^^
+...
+LL | struct Mew();
+   | ------------- the inner attribute doesn't annotate this struct
+   |
+   = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
+help: to annotate the struct, change the attribute from inner to outer style
+   |
+LL - #![deny(missing_docs)]
+LL + #[deny(missing_docs)]
+   | 
+
+error: aborting due to previous error
+

From 50ca08c5f5be2e2b018f535aa758803364bae33b Mon Sep 17 00:00:00 2001
From: Konrad Borowski <konrad@borowski.pw>
Date: Wed, 27 Oct 2021 15:18:25 +0200
Subject: [PATCH 10/11] Add tracking issue number to const_cstr_unchecked

---
 library/std/src/ffi/c_str.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/library/std/src/ffi/c_str.rs b/library/std/src/ffi/c_str.rs
index 3cb3f480de31d..b7822b40a7ccf 100644
--- a/library/std/src/ffi/c_str.rs
+++ b/library/std/src/ffi/c_str.rs
@@ -1257,7 +1257,7 @@ impl CStr {
     #[inline]
     #[must_use]
     #[stable(feature = "cstr_from_bytes", since = "1.10.0")]
-    #[rustc_const_unstable(feature = "const_cstr_unchecked", issue = "none")]
+    #[rustc_const_unstable(feature = "const_cstr_unchecked", issue = "90343")]
     pub const unsafe fn from_bytes_with_nul_unchecked(bytes: &[u8]) -> &CStr {
         // SAFETY: Casting to CStr is safe because its internal representation
         // is a [u8] too (safe only inside std).

From b1b4c6cb004fca11d90102ea2d79dee3ad8597b9 Mon Sep 17 00:00:00 2001
From: r00ster91 <r00ster91@protonmail.com>
Date: Wed, 27 Oct 2021 17:43:14 +0200
Subject: [PATCH 11/11] Remove big O notation

---
 library/alloc/src/collections/btree/map.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs
index 07920a6dba619..e1d5ec97678fa 100644
--- a/library/alloc/src/collections/btree/map.rs
+++ b/library/alloc/src/collections/btree/map.rs
@@ -55,7 +55,7 @@ pub(super) const MIN_LEN: usize = node::MIN_LEN_AFTER_SPLIT;
 /// performance on *small* nodes of elements which are cheap to compare. However in the future we
 /// would like to further explore choosing the optimal search strategy based on the choice of B,
 /// and possibly other factors. Using linear search, searching for a random element is expected
-/// to take O(B * log(n)) comparisons, which is generally worse than a BST. In practice,
+/// to take B * log(n) comparisons, which is generally worse than a BST. In practice,
 /// however, performance is excellent.
 ///
 /// It is a logic error for a key to be modified in such a way that the key's ordering relative to