diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs
index cecdcc9789609..49ebca0502c08 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs
@@ -163,61 +163,65 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
             flags.push((sym::from_desugaring, None));
             flags.push((sym::from_desugaring, Some(format!("{:?}", k))));
         }
-        let generics = self.tcx.generics_of(def_id);
-        let self_ty = trait_ref.self_ty();
-        // This is also included through the generics list as `Self`,
-        // but the parser won't allow you to use it
-        flags.push((sym::_Self, Some(self_ty.to_string())));
-        if let Some(def) = self_ty.ty_adt_def() {
-            // We also want to be able to select self's original
-            // signature with no type arguments resolved
-            flags.push((sym::_Self, Some(self.tcx.type_of(def.did).to_string())));
-        }
 
-        for param in generics.params.iter() {
-            let value = match param.kind {
-                GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. } => {
-                    trait_ref.substs[param.index as usize].to_string()
-                }
-                GenericParamDefKind::Lifetime => continue,
-            };
-            let name = param.name;
-            flags.push((name, Some(value)));
-        }
+        // Add all types without trimmed paths.
+        ty::print::with_no_trimmed_paths(|| {
+            let generics = self.tcx.generics_of(def_id);
+            let self_ty = trait_ref.self_ty();
+            // This is also included through the generics list as `Self`,
+            // but the parser won't allow you to use it
+            flags.push((sym::_Self, Some(self_ty.to_string())));
+            if let Some(def) = self_ty.ty_adt_def() {
+                // We also want to be able to select self's original
+                // signature with no type arguments resolved
+                flags.push((sym::_Self, Some(self.tcx.type_of(def.did).to_string())));
+            }
 
-        if let Some(true) = self_ty.ty_adt_def().map(|def| def.did.is_local()) {
-            flags.push((sym::crate_local, None));
-        }
+            for param in generics.params.iter() {
+                let value = match param.kind {
+                    GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. } => {
+                        trait_ref.substs[param.index as usize].to_string()
+                    }
+                    GenericParamDefKind::Lifetime => continue,
+                };
+                let name = param.name;
+                flags.push((name, Some(value)));
+            }
 
-        // Allow targeting all integers using `{integral}`, even if the exact type was resolved
-        if self_ty.is_integral() {
-            flags.push((sym::_Self, Some("{integral}".to_owned())));
-        }
+            if let Some(true) = self_ty.ty_adt_def().map(|def| def.did.is_local()) {
+                flags.push((sym::crate_local, None));
+            }
 
-        if let ty::Array(aty, len) = self_ty.kind() {
-            flags.push((sym::_Self, Some("[]".to_owned())));
-            flags.push((sym::_Self, Some(format!("[{}]", aty))));
-            if let Some(def) = aty.ty_adt_def() {
-                // We also want to be able to select the array's type's original
-                // signature with no type arguments resolved
-                let type_string = self.tcx.type_of(def.did).to_string();
-                flags.push((sym::_Self, Some(format!("[{}]", type_string))));
+            // Allow targeting all integers using `{integral}`, even if the exact type was resolved
+            if self_ty.is_integral() {
+                flags.push((sym::_Self, Some("{integral}".to_owned())));
+            }
 
-                let len = len.val.try_to_value().and_then(|v| v.try_to_machine_usize(self.tcx));
-                let string = match len {
-                    Some(n) => format!("[{}; {}]", type_string, n),
-                    None => format!("[{}; _]", type_string),
-                };
-                flags.push((sym::_Self, Some(string)));
+            if let ty::Array(aty, len) = self_ty.kind() {
+                flags.push((sym::_Self, Some("[]".to_owned())));
+                flags.push((sym::_Self, Some(format!("[{}]", aty))));
+                if let Some(def) = aty.ty_adt_def() {
+                    // We also want to be able to select the array's type's original
+                    // signature with no type arguments resolved
+                    let type_string = self.tcx.type_of(def.did).to_string();
+                    flags.push((sym::_Self, Some(format!("[{}]", type_string))));
+
+                    let len = len.val.try_to_value().and_then(|v| v.try_to_machine_usize(self.tcx));
+                    let string = match len {
+                        Some(n) => format!("[{}; {}]", type_string, n),
+                        None => format!("[{}; _]", type_string),
+                    };
+                    flags.push((sym::_Self, Some(string)));
+                }
             }
-        }
-        if let ty::Dynamic(traits, _) = self_ty.kind() {
-            for t in traits.iter() {
-                if let ty::ExistentialPredicate::Trait(trait_ref) = t.skip_binder() {
-                    flags.push((sym::_Self, Some(self.tcx.def_path_str(trait_ref.def_id))))
+            if let ty::Dynamic(traits, _) = self_ty.kind() {
+                for t in traits.iter() {
+                    if let ty::ExistentialPredicate::Trait(trait_ref) = t.skip_binder() {
+                        flags.push((sym::_Self, Some(self.tcx.def_path_str(trait_ref.def_id))))
+                    }
                 }
             }
-        }
+        });
 
         if let Ok(Some(command)) =
             OnUnimplementedDirective::of_item(self.tcx, trait_ref.def_id, def_id)
diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs
index 46e1a3a4aa2fe..e75a36477188c 100644
--- a/library/core/src/iter/traits/iterator.rs
+++ b/library/core/src/iter/traits/iterator.rs
@@ -81,8 +81,8 @@ fn _assert_is_object_safe(_: &dyn Iterator<Item = ()>) {}
     ),
     on(
         _Self = "[]",
-        label = "borrow the array with `&` or call `.iter()` on it to iterate over it",
-        note = "arrays are not iterators, but slices like the following are: `&[1, 2, 3]`"
+        label = "arrays do not yet implement `IntoIterator`; try using `std::array::IntoIter::new(arr)`",
+        note = "see <https://github.com/rust-lang/rust/pull/65819> for more details"
     ),
     on(
         _Self = "{integral}",
diff --git a/src/test/ui/iterators/array-of-ranges.stderr b/src/test/ui/iterators/array-of-ranges.stderr
index 601983a6153fd..7d58eb948ea81 100644
--- a/src/test/ui/iterators/array-of-ranges.stderr
+++ b/src/test/ui/iterators/array-of-ranges.stderr
@@ -13,10 +13,10 @@ error[E0277]: `[RangeInclusive<{integer}>; 1]` is not an iterator
   --> $DIR/array-of-ranges.rs:4:14
    |
 LL |     for _ in [0..=1] {}
-   |              ^^^^^^^ borrow the array with `&` or call `.iter()` on it to iterate over it
+   |              ^^^^^^^ if you meant to iterate between two values, remove the square brackets
    |
    = help: the trait `Iterator` is not implemented for `[RangeInclusive<{integer}>; 1]`
-   = note: arrays are not iterators, but slices like the following are: `&[1, 2, 3]`
+   = note: `[start..=end]` is an array of one `RangeInclusive`; you might have meant to have a `RangeInclusive` without the brackets: `start..=end`
    = note: required because of the requirements on the impl of `IntoIterator` for `[RangeInclusive<{integer}>; 1]`
    = note: required by `into_iter`
 
@@ -24,10 +24,10 @@ error[E0277]: `[RangeFrom<{integer}>; 1]` is not an iterator
   --> $DIR/array-of-ranges.rs:6:14
    |
 LL |     for _ in [0..] {}
-   |              ^^^^^ borrow the array with `&` or call `.iter()` on it to iterate over it
+   |              ^^^^^ if you meant to iterate from a value onwards, remove the square brackets
    |
    = help: the trait `Iterator` is not implemented for `[RangeFrom<{integer}>; 1]`
-   = note: arrays are not iterators, but slices like the following are: `&[1, 2, 3]`
+   = note: `[start..]` is an array of one `RangeFrom`; you might have meant to have a `RangeFrom` without the brackets: `start..`, keeping in mind that iterating over an unbounded iterator will run forever unless you `break` or `return` from within the loop
    = note: required because of the requirements on the impl of `IntoIterator` for `[RangeFrom<{integer}>; 1]`
    = note: required by `into_iter`
 
@@ -35,10 +35,10 @@ error[E0277]: `[RangeTo<{integer}>; 1]` is not an iterator
   --> $DIR/array-of-ranges.rs:8:14
    |
 LL |     for _ in [..1] {}
-   |              ^^^^^ borrow the array with `&` or call `.iter()` on it to iterate over it
+   |              ^^^^^ if you meant to iterate until a value, remove the square brackets and add a starting value
    |
    = help: the trait `Iterator` is not implemented for `[RangeTo<{integer}>; 1]`
-   = note: arrays are not iterators, but slices like the following are: `&[1, 2, 3]`
+   = note: `[..end]` is an array of one `RangeTo`; you might have meant to have a bounded `Range` without the brackets: `0..end`
    = note: required because of the requirements on the impl of `IntoIterator` for `[RangeTo<{integer}>; 1]`
    = note: required by `into_iter`
 
@@ -46,10 +46,10 @@ error[E0277]: `[RangeToInclusive<{integer}>; 1]` is not an iterator
   --> $DIR/array-of-ranges.rs:10:14
    |
 LL |     for _ in [..=1] {}
-   |              ^^^^^^ borrow the array with `&` or call `.iter()` on it to iterate over it
+   |              ^^^^^^ if you meant to iterate until a value (including it), remove the square brackets and add a starting value
    |
    = help: the trait `Iterator` is not implemented for `[RangeToInclusive<{integer}>; 1]`
-   = note: arrays are not iterators, but slices like the following are: `&[1, 2, 3]`
+   = note: `[..=end]` is an array of one `RangeToInclusive`; you might have meant to have a bounded `RangeInclusive` without the brackets: `0..=end`
    = note: required because of the requirements on the impl of `IntoIterator` for `[RangeToInclusive<{integer}>; 1]`
    = note: required by `into_iter`
 
@@ -79,10 +79,10 @@ error[E0277]: `[std::ops::Range<{integer}>; 2]` is not an iterator
   --> $DIR/array-of-ranges.rs:19:14
    |
 LL |     for _ in [0..1, 2..3] {}
-   |              ^^^^^^^^^^^^ borrow the array with `&` or call `.iter()` on it to iterate over it
+   |              ^^^^^^^^^^^^ arrays do not yet implement `IntoIterator`; try using `std::array::IntoIter::new(arr)`
    |
    = help: the trait `Iterator` is not implemented for `[std::ops::Range<{integer}>; 2]`
-   = note: arrays are not iterators, but slices like the following are: `&[1, 2, 3]`
+   = note: see <https://github.com/rust-lang/rust/pull/65819> for more details
    = note: required because of the requirements on the impl of `IntoIterator` for `[std::ops::Range<{integer}>; 2]`
    = note: required by `into_iter`
 
@@ -90,10 +90,10 @@ error[E0277]: `[RangeInclusive<{integer}>; 1]` is not an iterator
   --> $DIR/array-of-ranges.rs:21:14
    |
 LL |     for _ in [0..=1] {}
-   |              ^^^^^^^ borrow the array with `&` or call `.iter()` on it to iterate over it
+   |              ^^^^^^^ if you meant to iterate between two values, remove the square brackets
    |
    = help: the trait `Iterator` is not implemented for `[RangeInclusive<{integer}>; 1]`
-   = note: arrays are not iterators, but slices like the following are: `&[1, 2, 3]`
+   = note: `[start..=end]` is an array of one `RangeInclusive`; you might have meant to have a `RangeInclusive` without the brackets: `start..=end`
    = note: required because of the requirements on the impl of `IntoIterator` for `[RangeInclusive<{integer}>; 1]`
    = note: required by `into_iter`
 
diff --git a/src/test/ui/iterators/array.stderr b/src/test/ui/iterators/array.stderr
index 68c6de5493f13..7e2b600fb7af2 100644
--- a/src/test/ui/iterators/array.stderr
+++ b/src/test/ui/iterators/array.stderr
@@ -2,10 +2,10 @@ error[E0277]: `[{integer}; 2]` is not an iterator
   --> $DIR/array.rs:2:14
    |
 LL |     for _ in [1, 2] {}
-   |              ^^^^^^ borrow the array with `&` or call `.iter()` on it to iterate over it
+   |              ^^^^^^ arrays do not yet implement `IntoIterator`; try using `std::array::IntoIter::new(arr)`
    |
    = help: the trait `Iterator` is not implemented for `[{integer}; 2]`
-   = note: arrays are not iterators, but slices like the following are: `&[1, 2, 3]`
+   = note: see <https://github.com/rust-lang/rust/pull/65819> for more details
    = note: required because of the requirements on the impl of `IntoIterator` for `[{integer}; 2]`
    = note: required by `into_iter`
 
@@ -13,10 +13,10 @@ error[E0277]: `[{integer}; 2]` is not an iterator
   --> $DIR/array.rs:5:14
    |
 LL |     for _ in x {}
-   |              ^ borrow the array with `&` or call `.iter()` on it to iterate over it
+   |              ^ arrays do not yet implement `IntoIterator`; try using `std::array::IntoIter::new(arr)`
    |
    = help: the trait `Iterator` is not implemented for `[{integer}; 2]`
-   = note: arrays are not iterators, but slices like the following are: `&[1, 2, 3]`
+   = note: see <https://github.com/rust-lang/rust/pull/65819> for more details
    = note: required because of the requirements on the impl of `IntoIterator` for `[{integer}; 2]`
    = note: required by `into_iter`
 
@@ -24,10 +24,10 @@ error[E0277]: `[{float}; 2]` is not an iterator
   --> $DIR/array.rs:7:14
    |
 LL |     for _ in [1.0, 2.0] {}
-   |              ^^^^^^^^^^ borrow the array with `&` or call `.iter()` on it to iterate over it
+   |              ^^^^^^^^^^ arrays do not yet implement `IntoIterator`; try using `std::array::IntoIter::new(arr)`
    |
    = help: the trait `Iterator` is not implemented for `[{float}; 2]`
-   = note: arrays are not iterators, but slices like the following are: `&[1, 2, 3]`
+   = note: see <https://github.com/rust-lang/rust/pull/65819> for more details
    = note: required because of the requirements on the impl of `IntoIterator` for `[{float}; 2]`
    = note: required by `into_iter`
 
diff --git a/src/test/ui/iterators/ranges.stderr b/src/test/ui/iterators/ranges.stderr
index 4678bafd196b5..73844329e361d 100644
--- a/src/test/ui/iterators/ranges.stderr
+++ b/src/test/ui/iterators/ranges.stderr
@@ -2,9 +2,10 @@ error[E0277]: `RangeTo<{integer}>` is not an iterator
   --> $DIR/ranges.rs:2:14
    |
 LL |     for _ in ..10 {}
-   |              ^^^^ `RangeTo<{integer}>` is not an iterator
+   |              ^^^^ if you meant to iterate until a value, add a starting value
    |
    = help: the trait `Iterator` is not implemented for `RangeTo<{integer}>`
+   = note: `..end` is a `RangeTo`, which cannot be iterated on; you might have meant to have a bounded `Range`: `0..end`
    = note: required because of the requirements on the impl of `IntoIterator` for `RangeTo<{integer}>`
    = note: required by `into_iter`
 
@@ -12,9 +13,10 @@ error[E0277]: `RangeToInclusive<{integer}>` is not an iterator
   --> $DIR/ranges.rs:4:14
    |
 LL |     for _ in ..=10 {}
-   |              ^^^^^ `RangeToInclusive<{integer}>` is not an iterator
+   |              ^^^^^ if you meant to iterate until a value (including it), add a starting value
    |
    = help: the trait `Iterator` is not implemented for `RangeToInclusive<{integer}>`
+   = note: `..=end` is a `RangeToInclusive`, which cannot be iterated on; you might have meant to have a bounded `RangeInclusive`: `0..=end`
    = note: required because of the requirements on the impl of `IntoIterator` for `RangeToInclusive<{integer}>`
    = note: required by `into_iter`
 
diff --git a/src/test/ui/iterators/string.stderr b/src/test/ui/iterators/string.stderr
index 1653006682427..1d77bcb753630 100644
--- a/src/test/ui/iterators/string.stderr
+++ b/src/test/ui/iterators/string.stderr
@@ -2,7 +2,7 @@ error[E0277]: `String` is not an iterator
   --> $DIR/string.rs:2:14
    |
 LL |     for _ in "".to_owned() {}
-   |              ^^^^^^^^^^^^^ `String` is not an iterator
+   |              ^^^^^^^^^^^^^ `String` is not an iterator; try calling `.chars()` or `.bytes()`
    |
    = help: the trait `Iterator` is not implemented for `String`
    = note: required because of the requirements on the impl of `IntoIterator` for `String`
diff --git a/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr b/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr
index 32961b7f87be0..3786457fb1ae3 100644
--- a/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr
+++ b/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr
@@ -46,6 +46,7 @@ error[E0277]: `dyn Future<Output = i32> + Send` cannot be unpinned
 LL |     Pin::new(x)
    |     ^^^^^^^^ the trait `Unpin` is not implemented for `dyn Future<Output = i32> + Send`
    |
+   = note: consider using `Box::pin`
    = note: required by `Pin::<P>::new`
 
 error[E0277]: `dyn Future<Output = i32> + Send` cannot be unpinned
@@ -54,6 +55,7 @@ error[E0277]: `dyn Future<Output = i32> + Send` cannot be unpinned
 LL |     Pin::new(Box::new(x))
    |     ^^^^^^^^ the trait `Unpin` is not implemented for `dyn Future<Output = i32> + Send`
    |
+   = note: consider using `Box::pin`
    = note: required by `Pin::<P>::new`
 
 error[E0308]: mismatched types
diff --git a/src/test/ui/suggestions/into-str.stderr b/src/test/ui/suggestions/into-str.stderr
index 2854b830ba822..26efd50bb8fd3 100644
--- a/src/test/ui/suggestions/into-str.stderr
+++ b/src/test/ui/suggestions/into-str.stderr
@@ -7,6 +7,7 @@ LL | fn foo<'a, T>(_t: T) where T: Into<&'a str> {}
 LL |     foo(String::new());
    |     ^^^ the trait `From<String>` is not implemented for `&str`
    |
+   = note: to coerce a `String` into a `&str`, use `&*` as a prefix
    = note: required because of the requirements on the impl of `Into<&str>` for `String`
 
 error: aborting due to previous error
diff --git a/src/test/ui/suggestions/path-display.stderr b/src/test/ui/suggestions/path-display.stderr
index b08e22eaab7bb..3ee2860b4ffc7 100644
--- a/src/test/ui/suggestions/path-display.stderr
+++ b/src/test/ui/suggestions/path-display.stderr
@@ -2,10 +2,10 @@ error[E0277]: `Path` doesn't implement `std::fmt::Display`
   --> $DIR/path-display.rs:5:20
    |
 LL |     println!("{}", path);
-   |                    ^^^^ `Path` cannot be formatted with the default formatter
+   |                    ^^^^ `Path` cannot be formatted with the default formatter; call `.display()` on it
    |
    = help: the trait `std::fmt::Display` is not implemented for `Path`
-   = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
+   = note: call `.display()` or `.to_string_lossy()` to safely print paths, as they may contain non-Unicode data
    = note: required because of the requirements on the impl of `std::fmt::Display` for `&Path`
    = note: required by `std::fmt::Display::fmt`
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)