about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_impl_item.rs6
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/pat.rs2
-rw-r--r--library/core/src/lib.rs2
-rw-r--r--library/core/src/range.rs494
-rw-r--r--library/core/src/range/iter.rs340
-rw-r--r--library/core/src/range/legacy.rs10
-rw-r--r--library/core/src/slice/index.rs124
-rw-r--r--library/core/src/str/traits.rs195
-rw-r--r--src/tools/linkchecker/main.rs2
-rw-r--r--src/tools/run-make-support/src/lib.rs11
-rw-r--r--src/tools/tidy/src/allowed_run_make_makefiles.txt1
-rw-r--r--tests/run-make/output-type-permutations/Makefile147
-rw-r--r--tests/run-make/output-type-permutations/rmake.rs543
-rw-r--r--tests/ui/argument-suggestions/basic.stderr10
-rw-r--r--tests/ui/argument-suggestions/exotic-calls.stderr40
-rw-r--r--tests/ui/argument-suggestions/extra_arguments.stderr169
-rw-r--r--tests/ui/argument-suggestions/suggest-better-removing-issue-126246.stderr60
-rw-r--r--tests/ui/associated-types/defaults-specialization.stderr18
-rw-r--r--tests/ui/compare-method/bad-self-type.stderr18
-rw-r--r--tests/ui/compare-method/issue-90444.stderr18
-rw-r--r--tests/ui/compare-method/reordered-type-param.stderr10
-rw-r--r--tests/ui/error-codes/E0057.stderr10
-rw-r--r--tests/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr18
-rw-r--r--tests/ui/impl-trait/impl-generic-mismatch-ab.stderr10
-rw-r--r--tests/ui/impl-trait/in-assoc-type-unconstrained.stderr9
-rw-r--r--tests/ui/impl-trait/in-trait/method-signature-matches.lt.stderr10
-rw-r--r--tests/ui/impl-trait/in-trait/method-signature-matches.mismatch.stderr9
-rw-r--r--tests/ui/impl-trait/in-trait/method-signature-matches.mismatch_async.stderr9
-rw-r--r--tests/ui/impl-trait/in-trait/opaque-and-lifetime-mismatch.stderr9
-rw-r--r--tests/ui/impl-trait/in-trait/specialization-broken.stderr9
-rw-r--r--tests/ui/impl-trait/opaque-used-in-extraneous-argument.stderr20
-rw-r--r--tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr18
-rw-r--r--tests/ui/impl-trait/trait_type.stderr9
-rw-r--r--tests/ui/impl-trait/where-allowed.stderr9
-rw-r--r--tests/ui/inference/ice-ifer-var-leaked-out-of-rollback-122098.stderr10
-rw-r--r--tests/ui/issues/issue-16939.stderr10
-rw-r--r--tests/ui/issues/issue-20225.stderr27
-rw-r--r--tests/ui/issues/issue-21332.stderr9
-rw-r--r--tests/ui/issues/issue-4935.stderr10
-rw-r--r--tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021.rs36
-rw-r--r--tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021_fail.rs37
-rw-r--r--tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021_fail.stderr (renamed from tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021.stderr)20
-rw-r--r--tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs23
-rw-r--r--tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.both.stderr19
-rw-r--r--tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.classic.stderr19
-rw-r--r--tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs16
-rw-r--r--tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.structural.stderr19
-rw-r--r--tests/ui/methods/method-call-err-msg.stderr10
-rw-r--r--tests/ui/mismatched_types/E0053.stderr18
-rw-r--r--tests/ui/mismatched_types/issue-112036.stderr9
-rw-r--r--tests/ui/mismatched_types/issue-13033.stderr9
-rw-r--r--tests/ui/mismatched_types/trait-impl-fn-incompatibility.stderr18
-rw-r--r--tests/ui/range/issue-54505-no-std.stderr6
-rw-r--r--tests/ui/resolve/resolve-primitive-fallback.stderr10
-rw-r--r--tests/ui/span/issue-34264.stderr20
-rw-r--r--tests/ui/traits/issue-35869.stderr36
-rw-r--r--tests/ui/traits/wrong-mul-method-signature.stderr27
-rw-r--r--tests/ui/tuple/wrong_argument_ice-4.stderr13
-rw-r--r--tests/ui/type-alias-impl-trait/unnameable_type.stderr9
-rw-r--r--tests/ui/type/type-ascription-instead-of-initializer.stderr10
-rw-r--r--tests/ui/typeck/mismatched-map-under-self.stderr9
-rw-r--r--tests/ui/typeck/remove-extra-argument.stderr10
-rw-r--r--tests/ui/typeck/struct-enum-wrong-args.stderr30
-rw-r--r--tests/ui/ufcs/ufcs-explicit-self-bad.stderr9
65 files changed, 2332 insertions, 547 deletions
diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
index b5b68471b9d..0dbe64c3ea7 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
@@ -981,7 +981,7 @@ fn report_trait_method_mismatch<'tcx>(
                 .next()
                 .unwrap_or(impl_err_span);
 
-            diag.span_suggestion(
+            diag.span_suggestion_verbose(
                 span,
                 "change the self-receiver type to match the trait",
                 sugg,
@@ -1005,12 +1005,12 @@ fn report_trait_method_mismatch<'tcx>(
                         }
                         hir::FnRetTy::Return(hir_ty) => {
                             let sugg = trait_sig.output();
-                            diag.span_suggestion(hir_ty.span, msg, sugg, ap);
+                            diag.span_suggestion_verbose(hir_ty.span, msg, sugg, ap);
                         }
                     };
                 };
             } else if let Some(trait_ty) = trait_sig.inputs().get(*i) {
-                diag.span_suggestion(
+                diag.span_suggestion_verbose(
                     impl_err_span,
                     "change the parameter type to match the trait",
                     trait_ty,
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
index 56dff080867..047d0850d4c 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -1384,7 +1384,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 Some(format!("provide the argument{}", if plural { "s" } else { "" }))
             }
             SuggestionText::Remove(plural) => {
-                err.multipart_suggestion(
+                err.multipart_suggestion_verbose(
                     format!("remove the extra argument{}", if plural { "s" } else { "" }),
                     suggestions,
                     Applicability::HasPlaceholders,
diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs
index c8db4b97bae..5e0f37ed792 100644
--- a/compiler/rustc_hir_typeck/src/pat.rs
+++ b/compiler/rustc_hir_typeck/src/pat.rs
@@ -2217,7 +2217,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 debug!("check_pat_ref: expected={:?}", expected);
                 match *expected.kind() {
                     ty::Ref(_, r_ty, r_mutbl)
-                        if (new_match_ergonomics && r_mutbl >= pat_mutbl)
+                        if (no_ref_mut_behind_and && r_mutbl >= pat_mutbl)
                             || r_mutbl == pat_mutbl =>
                     {
                         if no_ref_mut_behind_and && r_mutbl == Mutability::Not {
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index c5a1fca667b..0f82f01e57a 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -395,6 +395,8 @@ pub mod panicking;
 #[unstable(feature = "core_pattern_types", issue = "none")]
 pub mod pat;
 pub mod pin;
+#[unstable(feature = "new_range_api", issue = "125687")]
+pub mod range;
 pub mod result;
 pub mod sync;
 
diff --git a/library/core/src/range.rs b/library/core/src/range.rs
new file mode 100644
index 00000000000..bfbbf123b1c
--- /dev/null
+++ b/library/core/src/range.rs
@@ -0,0 +1,494 @@
+//! # Experimental replacement range types
+//!
+//! The types within this module are meant to replace the existing
+//! `Range`, `RangeInclusive`, and `RangeFrom` types in a future edition.
+//!
+//! ```
+//! #![feature(new_range_api)]
+//! use core::range::{Range, RangeFrom, RangeInclusive};
+//!
+//! let arr = [0, 1, 2, 3, 4];
+//! assert_eq!(arr[                      ..   ], [0, 1, 2, 3, 4]);
+//! assert_eq!(arr[                      .. 3 ], [0, 1, 2      ]);
+//! assert_eq!(arr[                      ..=3 ], [0, 1, 2, 3   ]);
+//! assert_eq!(arr[     RangeFrom::from(1..  )], [   1, 2, 3, 4]);
+//! assert_eq!(arr[         Range::from(1..3 )], [   1, 2      ]);
+//! assert_eq!(arr[RangeInclusive::from(1..=3)], [   1, 2, 3   ]);
+//! ```
+
+use crate::fmt;
+use crate::hash::Hash;
+
+mod iter;
+
+#[unstable(feature = "new_range_api", issue = "125687")]
+pub mod legacy;
+
+#[doc(inline)]
+pub use crate::ops::{Bound, OneSidedRange, RangeBounds, RangeFull, RangeTo, RangeToInclusive};
+
+use Bound::{Excluded, Included, Unbounded};
+
+#[doc(inline)]
+pub use crate::iter::Step;
+
+#[doc(inline)]
+pub use iter::{IterRange, IterRangeFrom, IterRangeInclusive};
+
+/// A (half-open) range bounded inclusively below and exclusively above
+/// (`start..end` in a future edition).
+///
+/// The range `start..end` contains all values with `start <= x < end`.
+/// It is empty if `start >= end`.
+///
+/// # Examples
+///
+/// ```
+/// #![feature(new_range_api)]
+/// use core::range::Range;
+///
+/// assert_eq!(Range::from(3..5), Range { start: 3, end: 5 });
+/// assert_eq!(3 + 4 + 5, Range::from(3..6).into_iter().sum());
+/// ```
+#[derive(Clone, Copy, Default, PartialEq, Eq, Hash)]
+#[unstable(feature = "new_range_api", issue = "125687")]
+pub struct Range<Idx> {
+    /// The lower bound of the range (inclusive).
+    #[unstable(feature = "new_range_api", issue = "125687")]
+    pub start: Idx,
+    /// The upper bound of the range (exclusive).
+    #[unstable(feature = "new_range_api", issue = "125687")]
+    pub end: Idx,
+}
+
+#[unstable(feature = "new_range_api", issue = "125687")]
+impl<Idx: fmt::Debug> fmt::Debug for Range<Idx> {
+    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+        self.start.fmt(fmt)?;
+        write!(fmt, "..")?;
+        self.end.fmt(fmt)?;
+        Ok(())
+    }
+}
+
+impl<Idx: Step> Range<Idx> {
+    /// Create an iterator over the elements within this range.
+    ///
+    /// Shorthand for `.clone().into_iter()`
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(new_range_api)]
+    /// use core::range::Range;
+    ///
+    /// let mut i = Range::from(3..9).iter().map(|n| n*n);
+    /// assert_eq!(i.next(), Some(9));
+    /// assert_eq!(i.next(), Some(16));
+    /// assert_eq!(i.next(), Some(25));
+    /// ```
+    #[unstable(feature = "new_range_api", issue = "125687")]
+    #[inline]
+    pub fn iter(&self) -> IterRange<Idx> {
+        self.clone().into_iter()
+    }
+}
+
+impl<Idx: PartialOrd<Idx>> Range<Idx> {
+    /// Returns `true` if `item` is contained in the range.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(new_range_api)]
+    /// use core::range::Range;
+    ///
+    /// assert!(!Range::from(3..5).contains(&2));
+    /// assert!( Range::from(3..5).contains(&3));
+    /// assert!( Range::from(3..5).contains(&4));
+    /// assert!(!Range::from(3..5).contains(&5));
+    ///
+    /// assert!(!Range::from(3..3).contains(&3));
+    /// assert!(!Range::from(3..2).contains(&3));
+    ///
+    /// assert!( Range::from(0.0..1.0).contains(&0.5));
+    /// assert!(!Range::from(0.0..1.0).contains(&f32::NAN));
+    /// assert!(!Range::from(0.0..f32::NAN).contains(&0.5));
+    /// assert!(!Range::from(f32::NAN..1.0).contains(&0.5));
+    /// ```
+    #[inline]
+    #[unstable(feature = "new_range_api", issue = "125687")]
+    pub fn contains<U>(&self, item: &U) -> bool
+    where
+        Idx: PartialOrd<U>,
+        U: ?Sized + PartialOrd<Idx>,
+    {
+        <Self as RangeBounds<Idx>>::contains(self, item)
+    }
+
+    /// Returns `true` if the range contains no items.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(new_range_api)]
+    /// use core::range::Range;
+    ///
+    /// assert!(!Range::from(3..5).is_empty());
+    /// assert!( Range::from(3..3).is_empty());
+    /// assert!( Range::from(3..2).is_empty());
+    /// ```
+    ///
+    /// The range is empty if either side is incomparable:
+    ///
+    /// ```
+    /// #![feature(new_range_api)]
+    /// use core::range::Range;
+    ///
+    /// assert!(!Range::from(3.0..5.0).is_empty());
+    /// assert!( Range::from(3.0..f32::NAN).is_empty());
+    /// assert!( Range::from(f32::NAN..5.0).is_empty());
+    /// ```
+    #[inline]
+    #[unstable(feature = "new_range_api", issue = "125687")]
+    pub fn is_empty(&self) -> bool {
+        !(self.start < self.end)
+    }
+}
+
+#[unstable(feature = "new_range_api", issue = "125687")]
+impl<T> RangeBounds<T> for Range<T> {
+    fn start_bound(&self) -> Bound<&T> {
+        Included(&self.start)
+    }
+    fn end_bound(&self) -> Bound<&T> {
+        Excluded(&self.end)
+    }
+}
+
+#[unstable(feature = "new_range_api", issue = "125687")]
+impl<T> RangeBounds<T> for Range<&T> {
+    fn start_bound(&self) -> Bound<&T> {
+        Included(self.start)
+    }
+    fn end_bound(&self) -> Bound<&T> {
+        Excluded(self.end)
+    }
+}
+
+#[unstable(feature = "new_range_api", issue = "125687")]
+impl<T> From<Range<T>> for legacy::Range<T> {
+    #[inline]
+    fn from(value: Range<T>) -> Self {
+        Self { start: value.start, end: value.end }
+    }
+}
+#[unstable(feature = "new_range_api", issue = "125687")]
+impl<T> From<legacy::Range<T>> for Range<T> {
+    #[inline]
+    fn from(value: legacy::Range<T>) -> Self {
+        Self { start: value.start, end: value.end }
+    }
+}
+
+/// A range bounded inclusively below and above (`start..=end`).
+///
+/// The `RangeInclusive` `start..=end` contains all values with `x >= start`
+/// and `x <= end`. It is empty unless `start <= end`.
+///
+/// # Examples
+///
+/// The `start..=end` syntax is a `RangeInclusive`:
+///
+/// ```
+/// #![feature(new_range_api)]
+/// use core::range::RangeInclusive;
+///
+/// assert_eq!(RangeInclusive::from(3..=5), RangeInclusive { start: 3, end: 5 });
+/// assert_eq!(3 + 4 + 5, RangeInclusive::from(3..=5).into_iter().sum());
+/// ```
+#[derive(Clone, Copy, PartialEq, Eq, Hash)]
+#[unstable(feature = "new_range_api", issue = "125687")]
+pub struct RangeInclusive<Idx> {
+    /// The lower bound of the range (inclusive).
+    #[unstable(feature = "new_range_api", issue = "125687")]
+    pub start: Idx,
+    /// The upper bound of the range (inclusive).
+    #[unstable(feature = "new_range_api", issue = "125687")]
+    pub end: Idx,
+}
+
+#[unstable(feature = "new_range_api", issue = "125687")]
+impl<Idx: fmt::Debug> fmt::Debug for RangeInclusive<Idx> {
+    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+        self.start.fmt(fmt)?;
+        write!(fmt, "..=")?;
+        self.end.fmt(fmt)?;
+        Ok(())
+    }
+}
+
+impl<Idx: PartialOrd<Idx>> RangeInclusive<Idx> {
+    /// Returns `true` if `item` is contained in the range.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(new_range_api)]
+    /// use core::range::RangeInclusive;
+    ///
+    /// assert!(!RangeInclusive::from(3..=5).contains(&2));
+    /// assert!( RangeInclusive::from(3..=5).contains(&3));
+    /// assert!( RangeInclusive::from(3..=5).contains(&4));
+    /// assert!( RangeInclusive::from(3..=5).contains(&5));
+    /// assert!(!RangeInclusive::from(3..=5).contains(&6));
+    ///
+    /// assert!( RangeInclusive::from(3..=3).contains(&3));
+    /// assert!(!RangeInclusive::from(3..=2).contains(&3));
+    ///
+    /// assert!( RangeInclusive::from(0.0..=1.0).contains(&1.0));
+    /// assert!(!RangeInclusive::from(0.0..=1.0).contains(&f32::NAN));
+    /// assert!(!RangeInclusive::from(0.0..=f32::NAN).contains(&0.0));
+    /// assert!(!RangeInclusive::from(f32::NAN..=1.0).contains(&1.0));
+    /// ```
+    #[inline]
+    #[unstable(feature = "new_range_api", issue = "125687")]
+    pub fn contains<U>(&self, item: &U) -> bool
+    where
+        Idx: PartialOrd<U>,
+        U: ?Sized + PartialOrd<Idx>,
+    {
+        <Self as RangeBounds<Idx>>::contains(self, item)
+    }
+
+    /// Returns `true` if the range contains no items.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(new_range_api)]
+    /// use core::range::RangeInclusive;
+    ///
+    /// assert!(!RangeInclusive::from(3..=5).is_empty());
+    /// assert!(!RangeInclusive::from(3..=3).is_empty());
+    /// assert!( RangeInclusive::from(3..=2).is_empty());
+    /// ```
+    ///
+    /// The range is empty if either side is incomparable:
+    ///
+    /// ```
+    /// #![feature(new_range_api)]
+    /// use core::range::RangeInclusive;
+    ///
+    /// assert!(!RangeInclusive::from(3.0..=5.0).is_empty());
+    /// assert!( RangeInclusive::from(3.0..=f32::NAN).is_empty());
+    /// assert!( RangeInclusive::from(f32::NAN..=5.0).is_empty());
+    /// ```
+    #[unstable(feature = "new_range_api", issue = "125687")]
+    #[inline]
+    pub fn is_empty(&self) -> bool {
+        !(self.start <= self.end)
+    }
+}
+
+impl<Idx: Step> RangeInclusive<Idx> {
+    /// Create an iterator over the elements within this range.
+    ///
+    /// Shorthand for `.clone().into_iter()`
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(new_range_api)]
+    /// use core::range::RangeInclusive;
+    ///
+    /// let mut i = RangeInclusive::from(3..=8).iter().map(|n| n*n);
+    /// assert_eq!(i.next(), Some(9));
+    /// assert_eq!(i.next(), Some(16));
+    /// assert_eq!(i.next(), Some(25));
+    /// ```
+    #[unstable(feature = "new_range_api", issue = "125687")]
+    #[inline]
+    pub fn iter(&self) -> IterRangeInclusive<Idx> {
+        self.clone().into_iter()
+    }
+}
+
+impl RangeInclusive<usize> {
+    /// Converts to an exclusive `Range` for `SliceIndex` implementations.
+    /// The caller is responsible for dealing with `end == usize::MAX`.
+    #[inline]
+    pub(crate) const fn into_slice_range(self) -> Range<usize> {
+        Range { start: self.start, end: self.end + 1 }
+    }
+}
+
+#[unstable(feature = "new_range_api", issue = "125687")]
+impl<T> RangeBounds<T> for RangeInclusive<T> {
+    fn start_bound(&self) -> Bound<&T> {
+        Included(&self.start)
+    }
+    fn end_bound(&self) -> Bound<&T> {
+        Included(&self.end)
+    }
+}
+
+#[unstable(feature = "new_range_api", issue = "125687")]
+impl<T> RangeBounds<T> for RangeInclusive<&T> {
+    fn start_bound(&self) -> Bound<&T> {
+        Included(self.start)
+    }
+    fn end_bound(&self) -> Bound<&T> {
+        Included(self.end)
+    }
+}
+
+#[unstable(feature = "new_range_api", issue = "125687")]
+impl<T> From<RangeInclusive<T>> for legacy::RangeInclusive<T> {
+    #[inline]
+    fn from(value: RangeInclusive<T>) -> Self {
+        Self::new(value.start, value.end)
+    }
+}
+#[unstable(feature = "new_range_api", issue = "125687")]
+impl<T> From<legacy::RangeInclusive<T>> for RangeInclusive<T> {
+    #[inline]
+    fn from(value: legacy::RangeInclusive<T>) -> Self {
+        assert!(
+            !value.exhausted,
+            "attempted to convert from an exhausted `legacy::RangeInclusive` (unspecified behavior)"
+        );
+
+        let (start, end) = value.into_inner();
+        RangeInclusive { start, end }
+    }
+}
+
+/// A range only bounded inclusively below (`start..`).
+///
+/// The `RangeFrom` `start..` contains all values with `x >= start`.
+///
+/// *Note*: Overflow in the [`Iterator`] implementation (when the contained
+/// data type reaches its numerical limit) is allowed to panic, wrap, or
+/// saturate. This behavior is defined by the implementation of the [`Step`]
+/// trait. For primitive integers, this follows the normal rules, and respects
+/// the overflow checks profile (panic in debug, wrap in release). Note also
+/// that overflow happens earlier than you might assume: the overflow happens
+/// in the call to `next` that yields the maximum value, as the range must be
+/// set to a state to yield the next value.
+///
+/// [`Step`]: crate::iter::Step
+///
+/// # Examples
+///
+/// The `start..` syntax is a `RangeFrom`:
+///
+/// ```
+/// #![feature(new_range_api)]
+/// use core::range::RangeFrom;
+///
+/// assert_eq!(RangeFrom::from(2..), core::range::RangeFrom { start: 2 });
+/// assert_eq!(2 + 3 + 4, RangeFrom::from(2..).into_iter().take(3).sum());
+/// ```
+#[derive(Clone, Copy, PartialEq, Eq, Hash)]
+#[unstable(feature = "new_range_api", issue = "125687")]
+pub struct RangeFrom<Idx> {
+    /// The lower bound of the range (inclusive).
+    #[unstable(feature = "new_range_api", issue = "125687")]
+    pub start: Idx,
+}
+
+#[unstable(feature = "new_range_api", issue = "125687")]
+impl<Idx: fmt::Debug> fmt::Debug for RangeFrom<Idx> {
+    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+        self.start.fmt(fmt)?;
+        write!(fmt, "..")?;
+        Ok(())
+    }
+}
+
+impl<Idx: Step> RangeFrom<Idx> {
+    /// Create an iterator over the elements within this range.
+    ///
+    /// Shorthand for `.clone().into_iter()`
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(new_range_api)]
+    /// use core::range::RangeFrom;
+    ///
+    /// let mut i = RangeFrom::from(3..).iter().map(|n| n*n);
+    /// assert_eq!(i.next(), Some(9));
+    /// assert_eq!(i.next(), Some(16));
+    /// assert_eq!(i.next(), Some(25));
+    /// ```
+    #[unstable(feature = "new_range_api", issue = "125687")]
+    #[inline]
+    pub fn iter(&self) -> IterRangeFrom<Idx> {
+        self.clone().into_iter()
+    }
+}
+
+impl<Idx: PartialOrd<Idx>> RangeFrom<Idx> {
+    /// Returns `true` if `item` is contained in the range.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(new_range_api)]
+    /// use core::range::RangeFrom;
+    ///
+    /// assert!(!RangeFrom::from(3..).contains(&2));
+    /// assert!( RangeFrom::from(3..).contains(&3));
+    /// assert!( RangeFrom::from(3..).contains(&1_000_000_000));
+    ///
+    /// assert!( RangeFrom::from(0.0..).contains(&0.5));
+    /// assert!(!RangeFrom::from(0.0..).contains(&f32::NAN));
+    /// assert!(!RangeFrom::from(f32::NAN..).contains(&0.5));
+    /// ```
+    #[inline]
+    #[unstable(feature = "new_range_api", issue = "125687")]
+    pub fn contains<U>(&self, item: &U) -> bool
+    where
+        Idx: PartialOrd<U>,
+        U: ?Sized + PartialOrd<Idx>,
+    {
+        <Self as RangeBounds<Idx>>::contains(self, item)
+    }
+}
+
+#[unstable(feature = "new_range_api", issue = "125687")]
+impl<T> RangeBounds<T> for RangeFrom<T> {
+    fn start_bound(&self) -> Bound<&T> {
+        Included(&self.start)
+    }
+    fn end_bound(&self) -> Bound<&T> {
+        Unbounded
+    }
+}
+
+#[unstable(feature = "new_range_api", issue = "125687")]
+impl<T> RangeBounds<T> for RangeFrom<&T> {
+    fn start_bound(&self) -> Bound<&T> {
+        Included(self.start)
+    }
+    fn end_bound(&self) -> Bound<&T> {
+        Unbounded
+    }
+}
+
+#[unstable(feature = "new_range_api", issue = "125687")]
+impl<T> From<RangeFrom<T>> for legacy::RangeFrom<T> {
+    #[inline]
+    fn from(value: RangeFrom<T>) -> Self {
+        Self { start: value.start }
+    }
+}
+#[unstable(feature = "new_range_api", issue = "125687")]
+impl<T> From<legacy::RangeFrom<T>> for RangeFrom<T> {
+    #[inline]
+    fn from(value: legacy::RangeFrom<T>) -> Self {
+        Self { start: value.start }
+    }
+}
diff --git a/library/core/src/range/iter.rs b/library/core/src/range/iter.rs
new file mode 100644
index 00000000000..2b7db475ffb
--- /dev/null
+++ b/library/core/src/range/iter.rs
@@ -0,0 +1,340 @@
+use crate::num::NonZero;
+use crate::range::{legacy, Range, RangeFrom, RangeInclusive};
+
+use crate::iter::{
+    FusedIterator, Step, TrustedLen, TrustedRandomAccess, TrustedRandomAccessNoCoerce, TrustedStep,
+};
+
+/// By-value [`Range`] iterator.
+#[unstable(feature = "new_range_api", issue = "125687")]
+#[derive(Debug, Clone)]
+pub struct IterRange<A>(legacy::Range<A>);
+
+impl<A> IterRange<A> {
+    /// Returns the remainder of the range being iterated over.
+    pub fn remainder(self) -> Range<A> {
+        Range { start: self.0.start, end: self.0.end }
+    }
+}
+
+/// Safety: This macro must only be used on types that are `Copy` and result in ranges
+/// which have an exact `size_hint()` where the upper bound must not be `None`.
+macro_rules! unsafe_range_trusted_random_access_impl {
+    ($($t:ty)*) => ($(
+        #[doc(hidden)]
+        #[unstable(feature = "trusted_random_access", issue = "none")]
+        unsafe impl TrustedRandomAccess for IterRange<$t> {}
+
+        #[doc(hidden)]
+        #[unstable(feature = "trusted_random_access", issue = "none")]
+        unsafe impl TrustedRandomAccessNoCoerce for IterRange<$t> {
+            const MAY_HAVE_SIDE_EFFECT: bool = false;
+        }
+    )*)
+}
+
+unsafe_range_trusted_random_access_impl! {
+    usize u8 u16
+    isize i8 i16
+}
+
+#[cfg(target_pointer_width = "32")]
+unsafe_range_trusted_random_access_impl! {
+    u32 i32
+}
+
+#[cfg(target_pointer_width = "64")]
+unsafe_range_trusted_random_access_impl! {
+    u32 i32
+    u64 i64
+}
+
+#[unstable(feature = "new_range_api", issue = "125687")]
+impl<A: Step> Iterator for IterRange<A> {
+    type Item = A;
+
+    #[inline]
+    fn next(&mut self) -> Option<A> {
+        self.0.next()
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.0.size_hint()
+    }
+
+    #[inline]
+    fn count(self) -> usize {
+        self.0.count()
+    }
+
+    #[inline]
+    fn nth(&mut self, n: usize) -> Option<A> {
+        self.0.nth(n)
+    }
+
+    #[inline]
+    fn last(self) -> Option<A> {
+        self.0.last()
+    }
+
+    #[inline]
+    fn min(self) -> Option<A>
+    where
+        A: Ord,
+    {
+        self.0.min()
+    }
+
+    #[inline]
+    fn max(self) -> Option<A>
+    where
+        A: Ord,
+    {
+        self.0.max()
+    }
+
+    #[inline]
+    fn is_sorted(self) -> bool {
+        true
+    }
+
+    #[inline]
+    fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
+        self.0.advance_by(n)
+    }
+
+    #[inline]
+    unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item
+    where
+        Self: TrustedRandomAccessNoCoerce,
+    {
+        // SAFETY: The TrustedRandomAccess contract requires that callers only pass an index
+        // that is in bounds.
+        // Additionally Self: TrustedRandomAccess is only implemented for Copy types
+        // which means even repeated reads of the same index would be safe.
+        unsafe { Step::forward_unchecked(self.0.start.clone(), idx) }
+    }
+}
+
+#[unstable(feature = "new_range_api", issue = "125687")]
+impl<A: Step> DoubleEndedIterator for IterRange<A> {
+    #[inline]
+    fn next_back(&mut self) -> Option<A> {
+        self.0.next_back()
+    }
+
+    #[inline]
+    fn nth_back(&mut self, n: usize) -> Option<A> {
+        self.0.nth_back(n)
+    }
+
+    #[inline]
+    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
+        self.0.advance_back_by(n)
+    }
+}
+
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<A: TrustedStep> TrustedLen for IterRange<A> {}
+
+#[unstable(feature = "new_range_api", issue = "125687")]
+impl<A: Step> FusedIterator for IterRange<A> {}
+
+#[unstable(feature = "new_range_api", issue = "125687")]
+impl<A: Step> IntoIterator for Range<A> {
+    type Item = A;
+    type IntoIter = IterRange<A>;
+
+    fn into_iter(self) -> Self::IntoIter {
+        IterRange(self.into())
+    }
+}
+
+/// By-value [`RangeInclusive`] iterator.
+#[unstable(feature = "new_range_api", issue = "125687")]
+#[derive(Debug, Clone)]
+pub struct IterRangeInclusive<A>(legacy::RangeInclusive<A>);
+
+impl<A: Step> IterRangeInclusive<A> {
+    /// Returns the remainder of the range being iterated over.
+    ///
+    /// If the iterator is exhausted or empty, returns `None`.
+    pub fn remainder(self) -> Option<RangeInclusive<A>> {
+        if self.0.is_empty() {
+            return None;
+        }
+
+        Some(RangeInclusive { start: self.0.start, end: self.0.end })
+    }
+}
+
+#[unstable(feature = "trusted_random_access", issue = "none")]
+impl<A: Step> Iterator for IterRangeInclusive<A> {
+    type Item = A;
+
+    #[inline]
+    fn next(&mut self) -> Option<A> {
+        self.0.next()
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.0.size_hint()
+    }
+
+    #[inline]
+    fn count(self) -> usize {
+        self.0.count()
+    }
+
+    #[inline]
+    fn nth(&mut self, n: usize) -> Option<A> {
+        self.0.nth(n)
+    }
+
+    #[inline]
+    fn last(self) -> Option<A> {
+        self.0.last()
+    }
+
+    #[inline]
+    fn min(self) -> Option<A>
+    where
+        A: Ord,
+    {
+        self.0.min()
+    }
+
+    #[inline]
+    fn max(self) -> Option<A>
+    where
+        A: Ord,
+    {
+        self.0.max()
+    }
+
+    #[inline]
+    fn is_sorted(self) -> bool {
+        true
+    }
+
+    #[inline]
+    fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
+        self.0.advance_by(n)
+    }
+}
+
+#[unstable(feature = "new_range_api", issue = "125687")]
+impl<A: Step> DoubleEndedIterator for IterRangeInclusive<A> {
+    #[inline]
+    fn next_back(&mut self) -> Option<A> {
+        self.0.next_back()
+    }
+
+    #[inline]
+    fn nth_back(&mut self, n: usize) -> Option<A> {
+        self.0.nth_back(n)
+    }
+
+    #[inline]
+    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
+        self.0.advance_back_by(n)
+    }
+}
+
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<A: TrustedStep> TrustedLen for IterRangeInclusive<A> {}
+
+#[unstable(feature = "new_range_api", issue = "125687")]
+impl<A: Step> FusedIterator for IterRangeInclusive<A> {}
+
+#[unstable(feature = "new_range_api", issue = "125687")]
+impl<A: Step> IntoIterator for RangeInclusive<A> {
+    type Item = A;
+    type IntoIter = IterRangeInclusive<A>;
+
+    fn into_iter(self) -> Self::IntoIter {
+        IterRangeInclusive(self.into())
+    }
+}
+
+// These macros generate `ExactSizeIterator` impls for various range types.
+//
+// * `ExactSizeIterator::len` is required to always return an exact `usize`,
+//   so no range can be longer than `usize::MAX`.
+// * For integer types in `Range<_>` this is the case for types narrower than or as wide as `usize`.
+//   For integer types in `RangeInclusive<_>`
+//   this is the case for types *strictly narrower* than `usize`
+//   since e.g. `(0..=u64::MAX).len()` would be `u64::MAX + 1`.
+macro_rules! range_exact_iter_impl {
+    ($($t:ty)*) => ($(
+        #[unstable(feature = "new_range_api", issue = "125687")]
+        impl ExactSizeIterator for IterRange<$t> { }
+    )*)
+}
+
+macro_rules! range_incl_exact_iter_impl {
+    ($($t:ty)*) => ($(
+        #[unstable(feature = "new_range_api", issue = "125687")]
+        impl ExactSizeIterator for IterRangeInclusive<$t> { }
+    )*)
+}
+
+range_exact_iter_impl! {
+    usize u8 u16
+    isize i8 i16
+}
+
+range_incl_exact_iter_impl! {
+    u8
+    i8
+}
+
+/// By-value [`RangeFrom`] iterator.
+#[unstable(feature = "new_range_api", issue = "125687")]
+#[derive(Debug, Clone)]
+pub struct IterRangeFrom<A>(legacy::RangeFrom<A>);
+
+impl<A> IterRangeFrom<A> {
+    /// Returns the remainder of the range being iterated over.
+    pub fn remainder(self) -> RangeFrom<A> {
+        RangeFrom { start: self.0.start }
+    }
+}
+
+#[unstable(feature = "trusted_random_access", issue = "none")]
+impl<A: Step> Iterator for IterRangeFrom<A> {
+    type Item = A;
+
+    #[inline]
+    fn next(&mut self) -> Option<A> {
+        self.0.next()
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.0.size_hint()
+    }
+
+    #[inline]
+    fn nth(&mut self, n: usize) -> Option<A> {
+        self.0.nth(n)
+    }
+}
+
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<A: TrustedStep> TrustedLen for IterRangeFrom<A> {}
+
+#[unstable(feature = "new_range_api", issue = "125687")]
+impl<A: Step> FusedIterator for IterRangeFrom<A> {}
+
+#[unstable(feature = "new_range_api", issue = "125687")]
+impl<A: Step> IntoIterator for RangeFrom<A> {
+    type Item = A;
+    type IntoIter = IterRangeFrom<A>;
+
+    fn into_iter(self) -> Self::IntoIter {
+        IterRangeFrom(self.into())
+    }
+}
diff --git a/library/core/src/range/legacy.rs b/library/core/src/range/legacy.rs
new file mode 100644
index 00000000000..6723c4903f7
--- /dev/null
+++ b/library/core/src/range/legacy.rs
@@ -0,0 +1,10 @@
+//! # Legacy range types
+//!
+//! The types within this module will be replaced by the types
+//! [`Range`], [`RangeInclusive`], and [`RangeFrom`] in the parent
+//! module, [`core::range`].
+//!
+//! The types here are equivalent to those in [`core::ops`].
+
+#[doc(inline)]
+pub use crate::ops::{Range, RangeFrom, RangeInclusive};
diff --git a/library/core/src/slice/index.rs b/library/core/src/slice/index.rs
index 143dbd8a496..2624a44bb4b 100644
--- a/library/core/src/slice/index.rs
+++ b/library/core/src/slice/index.rs
@@ -2,6 +2,7 @@
 
 use crate::intrinsics::const_eval_select;
 use crate::ops;
+use crate::range;
 use crate::ub_checks::assert_unsafe_precondition;
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -147,7 +148,8 @@ const unsafe fn get_offset_len_mut_noubcheck<T>(
 }
 
 mod private_slice_index {
-    use super::ops;
+    use super::{ops, range};
+
     #[stable(feature = "slice_get_slice", since = "1.28.0")]
     pub trait Sealed {}
 
@@ -168,6 +170,13 @@ mod private_slice_index {
     #[stable(feature = "slice_index_with_ops_bound_pair", since = "1.53.0")]
     impl Sealed for (ops::Bound<usize>, ops::Bound<usize>) {}
 
+    #[unstable(feature = "new_range_api", issue = "125687")]
+    impl Sealed for range::Range<usize> {}
+    #[unstable(feature = "new_range_api", issue = "125687")]
+    impl Sealed for range::RangeInclusive<usize> {}
+    #[unstable(feature = "new_range_api", issue = "125687")]
+    impl Sealed for range::RangeFrom<usize> {}
+
     impl Sealed for ops::IndexRange {}
 }
 
@@ -473,6 +482,43 @@ unsafe impl<T> SliceIndex<[T]> for ops::Range<usize> {
     }
 }
 
+#[unstable(feature = "new_range_api", issue = "125687")]
+unsafe impl<T> SliceIndex<[T]> for range::Range<usize> {
+    type Output = [T];
+
+    #[inline]
+    fn get(self, slice: &[T]) -> Option<&[T]> {
+        ops::Range::from(self).get(slice)
+    }
+
+    #[inline]
+    fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
+        ops::Range::from(self).get_mut(slice)
+    }
+
+    #[inline]
+    unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
+        // SAFETY: the caller has to uphold the safety contract for `get_unchecked`.
+        unsafe { ops::Range::from(self).get_unchecked(slice) }
+    }
+
+    #[inline]
+    unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
+        // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`.
+        unsafe { ops::Range::from(self).get_unchecked_mut(slice) }
+    }
+
+    #[inline(always)]
+    fn index(self, slice: &[T]) -> &[T] {
+        ops::Range::from(self).index(slice)
+    }
+
+    #[inline]
+    fn index_mut(self, slice: &mut [T]) -> &mut [T] {
+        ops::Range::from(self).index_mut(slice)
+    }
+}
+
 /// The methods `index` and `index_mut` panic if the end of the range is out of bounds.
 #[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
 #[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
@@ -559,6 +605,43 @@ unsafe impl<T> SliceIndex<[T]> for ops::RangeFrom<usize> {
     }
 }
 
+#[unstable(feature = "new_range_api", issue = "125687")]
+unsafe impl<T> SliceIndex<[T]> for range::RangeFrom<usize> {
+    type Output = [T];
+
+    #[inline]
+    fn get(self, slice: &[T]) -> Option<&[T]> {
+        ops::RangeFrom::from(self).get(slice)
+    }
+
+    #[inline]
+    fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
+        ops::RangeFrom::from(self).get_mut(slice)
+    }
+
+    #[inline]
+    unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
+        // SAFETY: the caller has to uphold the safety contract for `get_unchecked`.
+        unsafe { ops::RangeFrom::from(self).get_unchecked(slice) }
+    }
+
+    #[inline]
+    unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
+        // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`.
+        unsafe { ops::RangeFrom::from(self).get_unchecked_mut(slice) }
+    }
+
+    #[inline]
+    fn index(self, slice: &[T]) -> &[T] {
+        ops::RangeFrom::from(self).index(slice)
+    }
+
+    #[inline]
+    fn index_mut(self, slice: &mut [T]) -> &mut [T] {
+        ops::RangeFrom::from(self).index_mut(slice)
+    }
+}
+
 #[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
 #[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
 unsafe impl<T> SliceIndex<[T]> for ops::RangeFull {
@@ -643,6 +726,43 @@ unsafe impl<T> SliceIndex<[T]> for ops::RangeInclusive<usize> {
     }
 }
 
+#[unstable(feature = "new_range_api", issue = "125687")]
+unsafe impl<T> SliceIndex<[T]> for range::RangeInclusive<usize> {
+    type Output = [T];
+
+    #[inline]
+    fn get(self, slice: &[T]) -> Option<&[T]> {
+        ops::RangeInclusive::from(self).get(slice)
+    }
+
+    #[inline]
+    fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
+        ops::RangeInclusive::from(self).get_mut(slice)
+    }
+
+    #[inline]
+    unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
+        // SAFETY: the caller has to uphold the safety contract for `get_unchecked`.
+        unsafe { ops::RangeInclusive::from(self).get_unchecked(slice) }
+    }
+
+    #[inline]
+    unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
+        // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`.
+        unsafe { ops::RangeInclusive::from(self).get_unchecked_mut(slice) }
+    }
+
+    #[inline]
+    fn index(self, slice: &[T]) -> &[T] {
+        ops::RangeInclusive::from(self).index(slice)
+    }
+
+    #[inline]
+    fn index_mut(self, slice: &mut [T]) -> &mut [T] {
+        ops::RangeInclusive::from(self).index_mut(slice)
+    }
+}
+
 /// The methods `index` and `index_mut` panic if the end of the range is out of bounds.
 #[stable(feature = "inclusive_range", since = "1.26.0")]
 #[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
@@ -780,7 +900,7 @@ where
 
 /// Performs bounds-checking of a range without panicking.
 ///
-/// This is a version of [`range`] that returns [`None`] instead of panicking.
+/// This is a version of [`range()`] that returns [`None`] instead of panicking.
 ///
 /// # Examples
 ///
diff --git a/library/core/src/str/traits.rs b/library/core/src/str/traits.rs
index ba2d6f64496..3de5546c4d4 100644
--- a/library/core/src/str/traits.rs
+++ b/library/core/src/str/traits.rs
@@ -4,6 +4,7 @@ use crate::cmp::Ordering;
 use crate::intrinsics::unchecked_sub;
 use crate::ops;
 use crate::ptr;
+use crate::range;
 use crate::slice::SliceIndex;
 use crate::ub_checks::assert_unsafe_precondition;
 
@@ -261,6 +262,108 @@ unsafe impl SliceIndex<str> for ops::Range<usize> {
     }
 }
 
+#[unstable(feature = "new_range_api", issue = "125687")]
+unsafe impl SliceIndex<str> for range::Range<usize> {
+    type Output = str;
+    #[inline]
+    fn get(self, slice: &str) -> Option<&Self::Output> {
+        if self.start <= self.end
+            && slice.is_char_boundary(self.start)
+            && slice.is_char_boundary(self.end)
+        {
+            // SAFETY: just checked that `start` and `end` are on a char boundary,
+            // and we are passing in a safe reference, so the return value will also be one.
+            // We also checked char boundaries, so this is valid UTF-8.
+            Some(unsafe { &*self.get_unchecked(slice) })
+        } else {
+            None
+        }
+    }
+    #[inline]
+    fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> {
+        if self.start <= self.end
+            && slice.is_char_boundary(self.start)
+            && slice.is_char_boundary(self.end)
+        {
+            // SAFETY: just checked that `start` and `end` are on a char boundary.
+            // We know the pointer is unique because we got it from `slice`.
+            Some(unsafe { &mut *self.get_unchecked_mut(slice) })
+        } else {
+            None
+        }
+    }
+    #[inline]
+    unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output {
+        let slice = slice as *const [u8];
+
+        assert_unsafe_precondition!(
+            // We'd like to check that the bounds are on char boundaries,
+            // but there's not really a way to do so without reading
+            // behind the pointer, which has aliasing implications.
+            // It's also not possible to move this check up to
+            // `str::get_unchecked` without adding a special function
+            // to `SliceIndex` just for this.
+            check_library_ub,
+            "str::get_unchecked requires that the range is within the string slice",
+            (
+                start: usize = self.start,
+                end: usize = self.end,
+                len: usize = slice.len()
+            ) => end >= start && end <= len,
+        );
+
+        // SAFETY: the caller guarantees that `self` is in bounds of `slice`
+        // which satisfies all the conditions for `add`.
+        unsafe {
+            let new_len = unchecked_sub(self.end, self.start);
+            ptr::slice_from_raw_parts(slice.as_ptr().add(self.start), new_len) as *const str
+        }
+    }
+    #[inline]
+    unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output {
+        let slice = slice as *mut [u8];
+
+        assert_unsafe_precondition!(
+            check_library_ub,
+            "str::get_unchecked_mut requires that the range is within the string slice",
+            (
+                start: usize = self.start,
+                end: usize = self.end,
+                len: usize = slice.len()
+            ) => end >= start && end <= len,
+        );
+
+        // SAFETY: see comments for `get_unchecked`.
+        unsafe {
+            let new_len = unchecked_sub(self.end, self.start);
+            ptr::slice_from_raw_parts_mut(slice.as_mut_ptr().add(self.start), new_len) as *mut str
+        }
+    }
+    #[inline]
+    fn index(self, slice: &str) -> &Self::Output {
+        let (start, end) = (self.start, self.end);
+        match self.get(slice) {
+            Some(s) => s,
+            None => super::slice_error_fail(slice, start, end),
+        }
+    }
+    #[inline]
+    fn index_mut(self, slice: &mut str) -> &mut Self::Output {
+        // is_char_boundary checks that the index is in [0, .len()]
+        // cannot reuse `get` as above, because of NLL trouble
+        if self.start <= self.end
+            && slice.is_char_boundary(self.start)
+            && slice.is_char_boundary(self.end)
+        {
+            // SAFETY: just checked that `start` and `end` are on a char boundary,
+            // and we are passing in a safe reference, so the return value will also be one.
+            unsafe { &mut *self.get_unchecked_mut(slice) }
+        } else {
+            super::slice_error_fail(slice, self.start, self.end)
+        }
+    }
+}
+
 /// Implements substring slicing for arbitrary bounds.
 ///
 /// Returns a slice of the given string bounded by the byte indices
@@ -453,6 +556,61 @@ unsafe impl SliceIndex<str> for ops::RangeFrom<usize> {
     }
 }
 
+#[unstable(feature = "new_range_api", issue = "125687")]
+unsafe impl SliceIndex<str> for range::RangeFrom<usize> {
+    type Output = str;
+    #[inline]
+    fn get(self, slice: &str) -> Option<&Self::Output> {
+        if slice.is_char_boundary(self.start) {
+            // SAFETY: just checked that `start` is on a char boundary,
+            // and we are passing in a safe reference, so the return value will also be one.
+            Some(unsafe { &*self.get_unchecked(slice) })
+        } else {
+            None
+        }
+    }
+    #[inline]
+    fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> {
+        if slice.is_char_boundary(self.start) {
+            // SAFETY: just checked that `start` is on a char boundary,
+            // and we are passing in a safe reference, so the return value will also be one.
+            Some(unsafe { &mut *self.get_unchecked_mut(slice) })
+        } else {
+            None
+        }
+    }
+    #[inline]
+    unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output {
+        let len = (slice as *const [u8]).len();
+        // SAFETY: the caller has to uphold the safety contract for `get_unchecked`.
+        unsafe { (self.start..len).get_unchecked(slice) }
+    }
+    #[inline]
+    unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output {
+        let len = (slice as *mut [u8]).len();
+        // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`.
+        unsafe { (self.start..len).get_unchecked_mut(slice) }
+    }
+    #[inline]
+    fn index(self, slice: &str) -> &Self::Output {
+        let (start, end) = (self.start, slice.len());
+        match self.get(slice) {
+            Some(s) => s,
+            None => super::slice_error_fail(slice, start, end),
+        }
+    }
+    #[inline]
+    fn index_mut(self, slice: &mut str) -> &mut Self::Output {
+        if slice.is_char_boundary(self.start) {
+            // SAFETY: just checked that `start` is on a char boundary,
+            // and we are passing in a safe reference, so the return value will also be one.
+            unsafe { &mut *self.get_unchecked_mut(slice) }
+        } else {
+            super::slice_error_fail(slice, self.start, slice.len())
+        }
+    }
+}
+
 /// Implements substring slicing with syntax `&self[begin ..= end]` or `&mut
 /// self[begin ..= end]`.
 ///
@@ -507,6 +665,43 @@ unsafe impl SliceIndex<str> for ops::RangeInclusive<usize> {
     }
 }
 
+#[unstable(feature = "new_range_api", issue = "125687")]
+unsafe impl SliceIndex<str> for range::RangeInclusive<usize> {
+    type Output = str;
+    #[inline]
+    fn get(self, slice: &str) -> Option<&Self::Output> {
+        if self.end == usize::MAX { None } else { self.into_slice_range().get(slice) }
+    }
+    #[inline]
+    fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> {
+        if self.end == usize::MAX { None } else { self.into_slice_range().get_mut(slice) }
+    }
+    #[inline]
+    unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output {
+        // SAFETY: the caller must uphold the safety contract for `get_unchecked`.
+        unsafe { self.into_slice_range().get_unchecked(slice) }
+    }
+    #[inline]
+    unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output {
+        // SAFETY: the caller must uphold the safety contract for `get_unchecked_mut`.
+        unsafe { self.into_slice_range().get_unchecked_mut(slice) }
+    }
+    #[inline]
+    fn index(self, slice: &str) -> &Self::Output {
+        if self.end == usize::MAX {
+            str_index_overflow_fail();
+        }
+        self.into_slice_range().index(slice)
+    }
+    #[inline]
+    fn index_mut(self, slice: &mut str) -> &mut Self::Output {
+        if self.end == usize::MAX {
+            str_index_overflow_fail();
+        }
+        self.into_slice_range().index_mut(slice)
+    }
+}
+
 /// Implements substring slicing with syntax `&self[..= end]` or `&mut
 /// self[..= end]`.
 ///
diff --git a/src/tools/linkchecker/main.rs b/src/tools/linkchecker/main.rs
index 7321bd1bb52..72ae3ed26e8 100644
--- a/src/tools/linkchecker/main.rs
+++ b/src/tools/linkchecker/main.rs
@@ -59,6 +59,8 @@ const INTRA_DOC_LINK_EXCEPTIONS: &[(&str, &[&str])] = &[
     // This is being used in the sense of 'inclusive range', not a markdown link
     ("core/ops/struct.RangeInclusive.html", &["begin</code>, <code>end"]),
     ("std/ops/struct.RangeInclusive.html", &["begin</code>, <code>end"]),
+    ("core/range/legacy/struct.RangeInclusive.html", &["begin</code>, <code>end"]),
+    ("std/range/legacy/struct.RangeInclusive.html", &["begin</code>, <code>end"]),
     ("core/slice/trait.SliceIndex.html", &["begin</code>, <code>end"]),
     ("alloc/slice/trait.SliceIndex.html", &["begin</code>, <code>end"]),
     ("std/slice/trait.SliceIndex.html", &["begin</code>, <code>end"]),
diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs
index af5ae6a8e60..7bb89106de1 100644
--- a/src/tools/run-make-support/src/lib.rs
+++ b/src/tools/run-make-support/src/lib.rs
@@ -266,14 +266,14 @@ pub fn test_while_readonly<P: AsRef<Path>, F: FnOnce() + std::panic::UnwindSafe>
 #[track_caller]
 pub fn shallow_find_files<P: AsRef<Path>, F: Fn(&PathBuf) -> bool>(
     path: P,
-    closure: F,
+    filter: F,
 ) -> Vec<PathBuf> {
     let mut matching_files = Vec::new();
     for entry in fs_wrapper::read_dir(path) {
         let entry = entry.expect("failed to read directory entry.");
         let path = entry.path();
 
-        if path.is_file() && closure(&path) {
+        if path.is_file() && filter(&path) {
             matching_files.push(path);
         }
     }
@@ -295,6 +295,13 @@ pub fn not_contains<P: AsRef<Path>>(path: P, expected: &str) -> bool {
     !path.as_ref().file_name().is_some_and(|name| name.to_str().unwrap().contains(expected))
 }
 
+/// Returns true if the filename at `path` is not in `expected`.
+pub fn filename_not_in_denylist<P: AsRef<Path>>(path: P, expected: &[String]) -> bool {
+    path.as_ref()
+        .file_name()
+        .is_some_and(|name| !expected.contains(&name.to_str().unwrap().to_owned()))
+}
+
 /// Use `cygpath -w` on a path to get a Windows path string back. This assumes that `cygpath` is
 /// available on the platform!
 #[track_caller]
diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt
index 0cb3275d7e9..ff98bd538db 100644
--- a/src/tools/tidy/src/allowed_run_make_makefiles.txt
+++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt
@@ -100,7 +100,6 @@ run-make/no-alloc-shim/Makefile
 run-make/no-builtins-attribute/Makefile
 run-make/no-duplicate-libs/Makefile
 run-make/obey-crate-type-flag/Makefile
-run-make/output-type-permutations/Makefile
 run-make/panic-abort-eh_frame/Makefile
 run-make/pass-linker-flags-flavor/Makefile
 run-make/pass-linker-flags-from-dep/Makefile
diff --git a/tests/run-make/output-type-permutations/Makefile b/tests/run-make/output-type-permutations/Makefile
deleted file mode 100644
index 035033b9fdd..00000000000
--- a/tests/run-make/output-type-permutations/Makefile
+++ /dev/null
@@ -1,147 +0,0 @@
-# ignore-cross-compile
-include ../tools.mk
-
-all:
-	$(RUSTC) foo.rs --crate-type=rlib,dylib,staticlib
-	$(call REMOVE_RLIBS,bar)
-	$(call REMOVE_DYLIBS,bar)
-	rm $(call STATICLIB,bar)
-	rm -f $(TMPDIR)/{lib,}bar.{dll.exp,dll.lib,pdb,dll.a}
-	# Check that $(TMPDIR) is empty.
-	[ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ]
-
-	$(RUSTC) foo.rs --crate-type=bin
-	rm $(TMPDIR)/$(call BIN,bar)
-	rm -f $(TMPDIR)/bar.pdb
-	[ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ]
-
-	$(RUSTC) foo.rs --emit=asm,llvm-ir,llvm-bc,obj,link
-	rm $(TMPDIR)/bar.ll
-	rm $(TMPDIR)/bar.bc
-	rm $(TMPDIR)/bar.s
-	rm $(TMPDIR)/bar.o
-	rm $(TMPDIR)/$(call BIN,bar)
-	rm -f $(TMPDIR)/bar.pdb
-	[ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ]
-
-	$(RUSTC) foo.rs --emit asm -o $(TMPDIR)/foo
-	rm $(TMPDIR)/foo
-	$(RUSTC) foo.rs --emit asm=$(TMPDIR)/foo
-	rm $(TMPDIR)/foo
-	$(RUSTC) foo.rs --emit=asm=$(TMPDIR)/foo
-	rm $(TMPDIR)/foo
-	[ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ]
-
-	$(RUSTC) foo.rs --emit llvm-bc -o $(TMPDIR)/foo
-	rm $(TMPDIR)/foo
-	$(RUSTC) foo.rs --emit llvm-bc=$(TMPDIR)/foo
-	rm $(TMPDIR)/foo
-	$(RUSTC) foo.rs --emit=llvm-bc=$(TMPDIR)/foo
-	rm $(TMPDIR)/foo
-	[ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ]
-
-	$(RUSTC) foo.rs --emit llvm-ir -o $(TMPDIR)/foo
-	rm $(TMPDIR)/foo
-	$(RUSTC) foo.rs --emit llvm-ir=$(TMPDIR)/foo
-	rm $(TMPDIR)/foo
-	$(RUSTC) foo.rs --emit=llvm-ir=$(TMPDIR)/foo
-	rm $(TMPDIR)/foo
-	[ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ]
-
-	$(RUSTC) foo.rs --emit obj -o $(TMPDIR)/foo
-	rm $(TMPDIR)/foo
-	$(RUSTC) foo.rs --emit obj=$(TMPDIR)/foo
-	rm $(TMPDIR)/foo
-	$(RUSTC) foo.rs --emit=obj=$(TMPDIR)/foo
-	rm $(TMPDIR)/foo
-	[ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ]
-
-	$(RUSTC) foo.rs --emit link -o $(TMPDIR)/$(call BIN,foo)
-	rm $(TMPDIR)/$(call BIN,foo)
-	$(RUSTC) foo.rs --emit link=$(TMPDIR)/$(call BIN,foo)
-	rm $(TMPDIR)/$(call BIN,foo)
-	$(RUSTC) foo.rs --emit=link=$(TMPDIR)/$(call BIN,foo)
-	rm $(TMPDIR)/$(call BIN,foo)
-	rm -f $(TMPDIR)/foo.pdb
-	[ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ]
-
-	$(RUSTC) foo.rs --crate-type=rlib -o $(TMPDIR)/foo
-	rm $(TMPDIR)/foo
-	$(RUSTC) foo.rs --crate-type=rlib --emit link=$(TMPDIR)/foo
-	rm $(TMPDIR)/foo
-	$(RUSTC) foo.rs --crate-type=rlib --emit=link=$(TMPDIR)/foo
-	rm $(TMPDIR)/foo
-	[ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ]
-
-	$(RUSTC) foo.rs --crate-type=dylib -o $(TMPDIR)/$(call BIN,foo)
-	rm $(TMPDIR)/$(call BIN,foo)
-	$(RUSTC) foo.rs --crate-type=dylib --emit link=$(TMPDIR)/$(call BIN,foo)
-	rm $(TMPDIR)/$(call BIN,foo)
-	$(RUSTC) foo.rs --crate-type=dylib --emit=link=$(TMPDIR)/$(call BIN,foo)
-	rm $(TMPDIR)/$(call BIN,foo)
-	rm -f $(TMPDIR)/{lib,}foo.{dll.exp,dll.lib,pdb,dll.a,exe.a}
-	[ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ] || (ls -1 $(TMPDIR) && exit 1)
-
-	$(RUSTC) foo.rs --crate-type=staticlib -o $(TMPDIR)/foo
-	rm $(TMPDIR)/foo
-	$(RUSTC) foo.rs --crate-type=staticlib --emit link=$(TMPDIR)/foo
-	rm $(TMPDIR)/foo
-	$(RUSTC) foo.rs --crate-type=staticlib --emit=link=$(TMPDIR)/foo
-	rm $(TMPDIR)/foo
-	[ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ]
-
-	$(RUSTC) foo.rs --crate-type=bin -o $(TMPDIR)/$(call BIN,foo)
-	rm $(TMPDIR)/$(call BIN,foo)
-	$(RUSTC) foo.rs --crate-type=bin --emit link=$(TMPDIR)/$(call BIN,foo)
-	rm $(TMPDIR)/$(call BIN,foo)
-	$(RUSTC) foo.rs --crate-type=bin --emit=link=$(TMPDIR)/$(call BIN,foo)
-	rm $(TMPDIR)/$(call BIN,foo)
-	rm -f $(TMPDIR)/foo.pdb
-	[ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ]
-
-	$(RUSTC) foo.rs --emit llvm-ir=$(TMPDIR)/ir \
-			--emit link \
-			--crate-type=rlib
-	rm $(TMPDIR)/ir
-	rm $(TMPDIR)/libbar.rlib
-	[ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ]
-
-	$(RUSTC) foo.rs --emit asm=$(TMPDIR)/asm \
-			--emit llvm-ir=$(TMPDIR)/ir \
-			--emit llvm-bc=$(TMPDIR)/bc \
-		        --emit obj=$(TMPDIR)/obj \
-			--emit link=$(TMPDIR)/link \
-			--crate-type=staticlib
-	rm $(TMPDIR)/asm
-	rm $(TMPDIR)/ir
-	rm $(TMPDIR)/bc
-	rm $(TMPDIR)/obj
-	rm $(TMPDIR)/link
-	$(RUSTC) foo.rs --emit=asm=$(TMPDIR)/asm \
-			--emit llvm-ir=$(TMPDIR)/ir \
-			--emit=llvm-bc=$(TMPDIR)/bc \
-		        --emit obj=$(TMPDIR)/obj \
-			--emit=link=$(TMPDIR)/link \
-			--crate-type=staticlib
-	rm $(TMPDIR)/asm
-	rm $(TMPDIR)/ir
-	rm $(TMPDIR)/bc
-	rm $(TMPDIR)/obj
-	rm $(TMPDIR)/link
-	[ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ]
-
-	$(RUSTC) foo.rs --emit=asm,llvm-ir,llvm-bc,obj,link --crate-type=staticlib
-	rm $(TMPDIR)/bar.ll
-	rm $(TMPDIR)/bar.s
-	rm $(TMPDIR)/bar.o
-	rm $(call STATICLIB,bar)
-	mv $(TMPDIR)/bar.bc $(TMPDIR)/foo.bc
-	# Don't check that the $(TMPDIR) is empty - we left `foo.bc` for later
-	# comparison.
-
-	$(RUSTC) foo.rs --emit=llvm-bc,link --crate-type=rlib
-	cmp $(TMPDIR)/foo.bc $(TMPDIR)/bar.bc
-	rm $(TMPDIR)/bar.bc
-	rm $(TMPDIR)/foo.bc
-	$(call REMOVE_RLIBS,bar)
-	[ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ]
diff --git a/tests/run-make/output-type-permutations/rmake.rs b/tests/run-make/output-type-permutations/rmake.rs
new file mode 100644
index 00000000000..30036dc7eea
--- /dev/null
+++ b/tests/run-make/output-type-permutations/rmake.rs
@@ -0,0 +1,543 @@
+// In 2014, rustc's output flags were reworked to be a lot more modular.
+// This test uses these output flags in an expansive variety of combinations
+// and syntax styles, checking that compilation is successful and that output
+// files are exactly what is expected, no more, no less.
+// See https://github.com/rust-lang/rust/pull/12020
+
+use run_make_support::{
+    bin_name, dynamic_lib_name, filename_not_in_denylist, fs_wrapper, rust_lib_name, rustc,
+    shallow_find_files, static_lib_name,
+};
+use std::path::PathBuf;
+
+// Each test takes 4 arguments:
+// `must_exist`: output files which must be found - if any are absent, the test fails
+// `can_exist`: optional output files which will not trigger a failure
+// `dir`: the name of the directory where the test happens
+// `rustc_invocation`: the rustc command being tested
+// Any unexpected output files not listed in `must_exist` or `can_exist` will cause a failure.
+fn assert_expected_output_files(expectations: Expectations, rustc_invocation: impl Fn()) {
+    let must_exist = expectations.expected_files;
+    let can_exist = expectations.allowed_files;
+    let dir = expectations.test_dir;
+
+    fs_wrapper::create_dir(&dir);
+    rustc_invocation();
+    for file in must_exist {
+        fs_wrapper::remove_file(PathBuf::from(&dir).join(&file));
+    }
+    let actual_output_files =
+        shallow_find_files(dir, |path| filename_not_in_denylist(path, &can_exist));
+    if !&actual_output_files.is_empty() {
+        dbg!(&actual_output_files);
+        panic!("unexpected output artifacts detected");
+    }
+}
+
+struct Expectations {
+    /// Output files which must be found. The test fails if any are absent.
+    expected_files: Vec<String>,
+    /// Allowed output files which will not trigger a failure.
+    allowed_files: Vec<String>,
+    /// Name of the directory where the test happens.
+    test_dir: String,
+}
+
+macro_rules! s {
+    ( $( $x:expr ),* ) => {
+        {
+            let mut temp_vec = Vec::new();
+            $(
+                temp_vec.push($x.to_string());
+            )*
+            temp_vec
+        }
+    };
+}
+
+fn main() {
+    let bin_foo = bin_name("foo");
+
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s![
+                static_lib_name("bar"),
+                dynamic_lib_name("bar"),
+                rust_lib_name("bar")
+            ],
+            allowed_files: s![
+                "libbar.dll.exp",
+                "libbar.dll.lib",
+                "libbar.pdb",
+                "libbar.dll.a",
+                "libbar.exe.a",
+                "bar.dll.exp",
+                "bar.dll.lib",
+                "bar.pdb",
+                "bar.dll.a",
+                "bar.exe.a"
+            ],
+            test_dir: "three-crates".to_string(),
+        },
+        || {
+            rustc()
+                .input("foo.rs")
+                .out_dir("three-crates")
+                .crate_type("rlib,dylib,staticlib")
+                .run();
+        },
+    );
+
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s![bin_name("bar")],
+            allowed_files: s!["bar.pdb"],
+            test_dir: "bin-crate".to_string(),
+        },
+        || {
+            rustc().input("foo.rs").crate_type("bin").out_dir("bin-crate").run();
+        },
+    );
+
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s!["bar.ll", "bar.bc", "bar.s", "bar.o", bin_name("bar")],
+            allowed_files: s!["bar.pdb"],
+            test_dir: "all-emit".to_string(),
+        },
+        || {
+            rustc().input("foo.rs").emit("asm,llvm-ir,llvm-bc,obj,link").out_dir("all-emit").run();
+        },
+    );
+
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s!["foo"],
+            allowed_files: s![],
+            test_dir: "asm-emit".to_string(),
+        },
+        || {
+            rustc().input("foo.rs").emit("asm").output("asm-emit/foo").run();
+        },
+    );
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s!["foo"],
+            allowed_files: s![],
+            test_dir: "asm-emit2".to_string(),
+        },
+        || {
+            rustc().input("foo.rs").emit("asm=asm-emit2/foo").run();
+        },
+    );
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s!["foo"],
+            allowed_files: s![],
+            test_dir: "asm-emit3".to_string(),
+        },
+        || {
+            rustc().input("foo.rs").arg("--emit=asm=asm-emit3/foo").run();
+        },
+    );
+
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s!["foo"],
+            allowed_files: s![],
+            test_dir: "llvm-ir-emit".to_string(),
+        },
+        || {
+            rustc().input("foo.rs").emit("llvm-ir").output("llvm-ir-emit/foo").run();
+        },
+    );
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s!["foo"],
+            allowed_files: s![],
+            test_dir: "llvm-ir-emit2".to_string(),
+        },
+        || {
+            rustc().input("foo.rs").emit("llvm-ir=llvm-ir-emit2/foo").run();
+        },
+    );
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s!["foo"],
+            allowed_files: s![],
+            test_dir: "llvm-ir-emit3".to_string(),
+        },
+        || {
+            rustc().input("foo.rs").arg("--emit=llvm-ir=llvm-ir-emit3/foo").run();
+        },
+    );
+
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s!["foo"],
+            allowed_files: s![],
+            test_dir: "llvm-bc-emit".to_string(),
+        },
+        || {
+            rustc().input("foo.rs").emit("llvm-bc").output("llvm-bc-emit/foo").run();
+        },
+    );
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s!["foo"],
+            allowed_files: s![],
+            test_dir: "llvm-bc-emit2".to_string(),
+        },
+        || {
+            rustc().input("foo.rs").emit("llvm-bc=llvm-bc-emit2/foo").run();
+        },
+    );
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s!["foo"],
+            allowed_files: s![],
+            test_dir: "llvm-bc-emit3".to_string(),
+        },
+        || {
+            rustc().input("foo.rs").arg("--emit=llvm-bc=llvm-bc-emit3/foo").run();
+        },
+    );
+
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s!["foo"],
+            allowed_files: s![],
+            test_dir: "obj-emit".to_string(),
+        },
+        || {
+            rustc().input("foo.rs").emit("obj").output("obj-emit/foo").run();
+        },
+    );
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s!["foo"],
+            allowed_files: s![],
+            test_dir: "obj-emit2".to_string(),
+        },
+        || {
+            rustc().input("foo.rs").emit("obj=obj-emit2/foo").run();
+        },
+    );
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s!["foo"],
+            allowed_files: s![],
+            test_dir: "obj-emit3".to_string(),
+        },
+        || {
+            rustc().input("foo.rs").arg("--emit=obj=obj-emit3/foo").run();
+        },
+    );
+
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s![&bin_foo],
+            allowed_files: s!["foo.pdb"],
+            test_dir: "link-emit".to_string(),
+        },
+        || {
+            rustc().input("foo.rs").emit("link").output("link-emit/".to_owned() + &bin_foo).run();
+        },
+    );
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s![&bin_foo],
+            allowed_files: s!["foo.pdb"],
+            test_dir: "link-emit2".to_string(),
+        },
+        || {
+            rustc().input("foo.rs").emit(&format!("link=link-emit2/{bin_foo}")).run();
+        },
+    );
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s![&bin_foo],
+            allowed_files: s!["foo.pdb"],
+            test_dir: "link-emit3".to_string(),
+        },
+        || {
+            rustc().input("foo.rs").arg(&format!("--emit=link=link-emit3/{bin_foo}")).run();
+        },
+    );
+
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s!["foo"],
+            allowed_files: s![],
+            test_dir: "rlib".to_string(),
+        },
+        || {
+            rustc().crate_type("rlib").input("foo.rs").output("rlib/foo").run();
+        },
+    );
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s!["foo"],
+            allowed_files: s![],
+            test_dir: "rlib2".to_string(),
+        },
+        || {
+            rustc().crate_type("rlib").input("foo.rs").emit("link=rlib2/foo").run();
+        },
+    );
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s!["foo"],
+            allowed_files: s![],
+            test_dir: "rlib3".to_string(),
+        },
+        || {
+            rustc().crate_type("rlib").input("foo.rs").arg("--emit=link=rlib3/foo").run();
+        },
+    );
+
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s![bin_foo],
+            allowed_files: s![
+                "libfoo.dll.exp",
+                "libfoo.dll.lib",
+                "libfoo.pdb",
+                "libfoo.dll.a",
+                "libfoo.exe.a",
+                "foo.dll.exp",
+                "foo.dll.lib",
+                "foo.pdb",
+                "foo.dll.a",
+                "foo.exe.a"
+            ],
+            test_dir: "dylib".to_string(),
+        },
+        || {
+            rustc()
+                .crate_type("dylib")
+                .input("foo.rs")
+                .output("dylib/".to_owned() + &bin_foo)
+                .run();
+        },
+    );
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s![bin_foo],
+            allowed_files: s![
+                "libfoo.dll.exp",
+                "libfoo.dll.lib",
+                "libfoo.pdb",
+                "libfoo.dll.a",
+                "libfoo.exe.a",
+                "foo.dll.exp",
+                "foo.dll.lib",
+                "foo.pdb",
+                "foo.dll.a",
+                "foo.exe.a"
+            ],
+            test_dir: "dylib2".to_string(),
+        },
+        || {
+            rustc()
+                .crate_type("dylib")
+                .input("foo.rs")
+                .emit(&format!("link=dylib2/{bin_foo}"))
+                .run();
+        },
+    );
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s![bin_foo],
+            allowed_files: s![
+                "libfoo.dll.exp",
+                "libfoo.dll.lib",
+                "libfoo.pdb",
+                "libfoo.dll.a",
+                "libfoo.exe.a",
+                "foo.dll.exp",
+                "foo.dll.lib",
+                "foo.pdb",
+                "foo.dll.a",
+                "foo.exe.a"
+            ],
+            test_dir: "dylib3".to_string(),
+        },
+        || {
+            rustc()
+                .crate_type("dylib")
+                .input("foo.rs")
+                .arg(&format!("--emit=link=dylib3/{bin_foo}"))
+                .run();
+        },
+    );
+
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s!["foo"],
+            allowed_files: s![],
+            test_dir: "staticlib".to_string(),
+        },
+        || {
+            rustc().crate_type("staticlib").input("foo.rs").output("staticlib/foo").run();
+        },
+    );
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s!["foo"],
+            allowed_files: s![],
+            test_dir: "staticlib2".to_string(),
+        },
+        || {
+            rustc().crate_type("staticlib").input("foo.rs").emit("link=staticlib2/foo").run();
+        },
+    );
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s!["foo"],
+            allowed_files: s![],
+            test_dir: "staticlib3".to_string(),
+        },
+        || {
+            rustc().crate_type("staticlib").input("foo.rs").arg("--emit=link=staticlib3/foo").run();
+        },
+    );
+
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s![bin_foo],
+            allowed_files: s!["foo.pdb"],
+            test_dir: "bincrate".to_string(),
+        },
+        || {
+            rustc()
+                .crate_type("bin")
+                .input("foo.rs")
+                .output("bincrate/".to_owned() + &bin_foo)
+                .run();
+        },
+    );
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s![bin_foo],
+            allowed_files: s!["foo.pdb"],
+            test_dir: "bincrate2".to_string(),
+        },
+        || {
+            rustc()
+                .crate_type("bin")
+                .input("foo.rs")
+                .emit(&format!("link=bincrate2/{bin_foo}"))
+                .run();
+        },
+    );
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s![bin_foo],
+            allowed_files: s!["foo.pdb"],
+            test_dir: "bincrate3".to_string(),
+        },
+        || {
+            rustc()
+                .crate_type("bin")
+                .input("foo.rs")
+                .arg(&format!("--emit=link=bincrate3/{bin_foo}"))
+                .run();
+        },
+    );
+
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s!["ir", rust_lib_name("bar")],
+            allowed_files: s![],
+            test_dir: "rlib-ir".to_string(),
+        },
+        || {
+            rustc()
+                .input("foo.rs")
+                .emit("llvm-ir=rlib-ir/ir")
+                .emit("link")
+                .crate_type("rlib")
+                .out_dir("rlib-ir")
+                .run();
+        },
+    );
+
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s!["ir", "asm", "bc", "obj", "link"],
+            allowed_files: s![],
+            test_dir: "staticlib-all".to_string(),
+        },
+        || {
+            rustc()
+                .input("foo.rs")
+                .emit("asm=staticlib-all/asm")
+                .emit("llvm-ir=staticlib-all/ir")
+                .emit("llvm-bc=staticlib-all/bc")
+                .emit("obj=staticlib-all/obj")
+                .emit("link=staticlib-all/link")
+                .crate_type("staticlib")
+                .run();
+        },
+    );
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s!["ir", "asm", "bc", "obj", "link"],
+            allowed_files: s![],
+            test_dir: "staticlib-all2".to_string(),
+        },
+        || {
+            rustc()
+                .input("foo.rs")
+                .arg("--emit=asm=staticlib-all2/asm")
+                .arg("--emit")
+                .arg("llvm-ir=staticlib-all2/ir")
+                .arg("--emit=llvm-bc=staticlib-all2/bc")
+                .arg("--emit")
+                .arg("obj=staticlib-all2/obj")
+                .arg("--emit=link=staticlib-all2/link")
+                .crate_type("staticlib")
+                .run();
+        },
+    );
+
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s!["bar.ll", "bar.s", "bar.o", static_lib_name("bar")],
+            allowed_files: s!["bar.bc"], // keep this one for the next test
+            test_dir: "staticlib-all3".to_string(),
+        },
+        || {
+            rustc()
+                .input("foo.rs")
+                .emit("asm,llvm-ir,llvm-bc,obj,link")
+                .crate_type("staticlib")
+                .out_dir("staticlib-all3")
+                .run();
+        },
+    );
+
+    // the .bc file from the previous test should be equivalent to this one, despite the difference
+    // in crate type
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s!["bar.bc", rust_lib_name("bar"), "foo.bc"],
+            allowed_files: s![],
+            test_dir: "rlib-emits".to_string(),
+        },
+        || {
+            fs_wrapper::rename("staticlib-all3/bar.bc", "rlib-emits/foo.bc");
+            rustc()
+                .input("foo.rs")
+                .emit("llvm-bc,link")
+                .crate_type("rlib")
+                .out_dir("rlib-emits")
+                .run();
+            assert_eq!(
+                fs_wrapper::read("rlib-emits/foo.bc"),
+                fs_wrapper::read("rlib-emits/bar.bc")
+            );
+        },
+    );
+}
diff --git a/tests/ui/argument-suggestions/basic.stderr b/tests/ui/argument-suggestions/basic.stderr
index c74186285f9..ea58ca97cfa 100644
--- a/tests/ui/argument-suggestions/basic.stderr
+++ b/tests/ui/argument-suggestions/basic.stderr
@@ -16,16 +16,18 @@ error[E0061]: this function takes 0 arguments but 1 argument was supplied
   --> $DIR/basic.rs:21:5
    |
 LL |     extra("");
-   |     ^^^^^ --
-   |           |
-   |           unexpected argument of type `&'static str`
-   |           help: remove the extra argument
+   |     ^^^^^ -- unexpected argument of type `&'static str`
    |
 note: function defined here
   --> $DIR/basic.rs:14:4
    |
 LL | fn extra() {}
    |    ^^^^^
+help: remove the extra argument
+   |
+LL -     extra("");
+LL +     extra();
+   |
 
 error[E0061]: this function takes 1 argument but 0 arguments were supplied
   --> $DIR/basic.rs:22:5
diff --git a/tests/ui/argument-suggestions/exotic-calls.stderr b/tests/ui/argument-suggestions/exotic-calls.stderr
index ff795b507f2..aca3b8a3433 100644
--- a/tests/ui/argument-suggestions/exotic-calls.stderr
+++ b/tests/ui/argument-suggestions/exotic-calls.stderr
@@ -2,61 +2,69 @@ error[E0057]: this function takes 0 arguments but 1 argument was supplied
   --> $DIR/exotic-calls.rs:2:5
    |
 LL |     t(1i32);
-   |     ^ ----
-   |       |
-   |       unexpected argument of type `i32`
-   |       help: remove the extra argument
+   |     ^ ---- unexpected argument of type `i32`
    |
 note: callable defined here
   --> $DIR/exotic-calls.rs:1:11
    |
 LL | fn foo<T: Fn()>(t: T) {
    |           ^^^^
+help: remove the extra argument
+   |
+LL -     t(1i32);
+LL +     t();
+   |
 
 error[E0057]: this function takes 0 arguments but 1 argument was supplied
   --> $DIR/exotic-calls.rs:7:5
    |
 LL |     t(1i32);
-   |     ^ ----
-   |       |
-   |       unexpected argument of type `i32`
-   |       help: remove the extra argument
+   |     ^ ---- unexpected argument of type `i32`
    |
 note: type parameter defined here
   --> $DIR/exotic-calls.rs:6:11
    |
 LL | fn bar(t: impl Fn()) {
    |           ^^^^^^^^^
+help: remove the extra argument
+   |
+LL -     t(1i32);
+LL +     t();
+   |
 
 error[E0057]: this function takes 0 arguments but 1 argument was supplied
   --> $DIR/exotic-calls.rs:16:5
    |
 LL |     baz()(1i32)
-   |     ^^^^^ ----
-   |           |
-   |           unexpected argument of type `i32`
-   |           help: remove the extra argument
+   |     ^^^^^ ---- unexpected argument of type `i32`
    |
 note: opaque type defined here
   --> $DIR/exotic-calls.rs:11:13
    |
 LL | fn baz() -> impl Fn() {
    |             ^^^^^^^^^
+help: remove the extra argument
+   |
+LL -     baz()(1i32)
+LL +     baz()()
+   |
 
 error[E0057]: this function takes 0 arguments but 1 argument was supplied
   --> $DIR/exotic-calls.rs:22:5
    |
 LL |     x(1i32);
-   |     ^ ----
-   |       |
-   |       unexpected argument of type `i32`
-   |       help: remove the extra argument
+   |     ^ ---- unexpected argument of type `i32`
    |
 note: closure defined here
   --> $DIR/exotic-calls.rs:21:13
    |
 LL |     let x = || {};
    |             ^^
+help: remove the extra argument
+   |
+LL -     x(1i32);
+LL +     x();
+   |
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/argument-suggestions/extra_arguments.stderr b/tests/ui/argument-suggestions/extra_arguments.stderr
index 5ad8e35920a..dec3da75186 100644
--- a/tests/ui/argument-suggestions/extra_arguments.stderr
+++ b/tests/ui/argument-suggestions/extra_arguments.stderr
@@ -2,16 +2,18 @@ error[E0061]: this function takes 0 arguments but 1 argument was supplied
   --> $DIR/extra_arguments.rs:19:3
    |
 LL |   empty("");
-   |   ^^^^^ --
-   |         |
-   |         unexpected argument of type `&'static str`
-   |         help: remove the extra argument
+   |   ^^^^^ -- unexpected argument of type `&'static str`
    |
 note: function defined here
   --> $DIR/extra_arguments.rs:1:4
    |
 LL | fn empty() {}
    |    ^^^^^
+help: remove the extra argument
+   |
+LL -   empty("");
+LL +   empty();
+   |
 
 error[E0061]: this function takes 0 arguments but 2 arguments were supplied
   --> $DIR/extra_arguments.rs:20:3
@@ -36,31 +38,35 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied
   --> $DIR/extra_arguments.rs:22:3
    |
 LL |   one_arg(1, 1);
-   |   ^^^^^^^  ---
-   |            | |
-   |            | unexpected argument of type `{integer}`
-   |            help: remove the extra argument
+   |   ^^^^^^^    - unexpected argument of type `{integer}`
    |
 note: function defined here
   --> $DIR/extra_arguments.rs:2:4
    |
 LL | fn one_arg<T>(_a: T) {}
    |    ^^^^^^^    -----
+help: remove the extra argument
+   |
+LL -   one_arg(1, 1);
+LL +   one_arg(1);
+   |
 
 error[E0061]: this function takes 1 argument but 2 arguments were supplied
   --> $DIR/extra_arguments.rs:23:3
    |
 LL |   one_arg(1, "");
-   |   ^^^^^^^  ----
-   |            | |
-   |            | unexpected argument of type `&'static str`
-   |            help: remove the extra argument
+   |   ^^^^^^^    -- unexpected argument of type `&'static str`
    |
 note: function defined here
   --> $DIR/extra_arguments.rs:2:4
    |
 LL | fn one_arg<T>(_a: T) {}
    |    ^^^^^^^    -----
+help: remove the extra argument
+   |
+LL -   one_arg(1, "");
+LL +   one_arg(1);
+   |
 
 error[E0061]: this function takes 1 argument but 3 arguments were supplied
   --> $DIR/extra_arguments.rs:24:3
@@ -85,61 +91,69 @@ error[E0061]: this function takes 2 arguments but 3 arguments were supplied
   --> $DIR/extra_arguments.rs:26:3
    |
 LL |   two_arg_same(1, 1, 1);
-   |   ^^^^^^^^^^^^     ---
-   |                    | |
-   |                    | unexpected argument of type `{integer}`
-   |                    help: remove the extra argument
+   |   ^^^^^^^^^^^^       - unexpected argument of type `{integer}`
    |
 note: function defined here
   --> $DIR/extra_arguments.rs:3:4
    |
 LL | fn two_arg_same(_a: i32, _b: i32) {}
    |    ^^^^^^^^^^^^ -------  -------
+help: remove the extra argument
+   |
+LL -   two_arg_same(1, 1, 1);
+LL +   two_arg_same(1, 1);
+   |
 
 error[E0061]: this function takes 2 arguments but 3 arguments were supplied
   --> $DIR/extra_arguments.rs:27:3
    |
 LL |   two_arg_same(1, 1, 1.0);
-   |   ^^^^^^^^^^^^     -----
-   |                    | |
-   |                    | unexpected argument of type `{float}`
-   |                    help: remove the extra argument
+   |   ^^^^^^^^^^^^       --- unexpected argument of type `{float}`
    |
 note: function defined here
   --> $DIR/extra_arguments.rs:3:4
    |
 LL | fn two_arg_same(_a: i32, _b: i32) {}
    |    ^^^^^^^^^^^^ -------  -------
+help: remove the extra argument
+   |
+LL -   two_arg_same(1, 1, 1.0);
+LL +   two_arg_same(1, 1);
+   |
 
 error[E0061]: this function takes 2 arguments but 3 arguments were supplied
   --> $DIR/extra_arguments.rs:29:3
    |
 LL |   two_arg_diff(1, 1, "");
-   |   ^^^^^^^^^^^^  ---
-   |                 | |
-   |                 | unexpected argument of type `{integer}`
-   |                 help: remove the extra argument
+   |   ^^^^^^^^^^^^    - unexpected argument of type `{integer}`
    |
 note: function defined here
   --> $DIR/extra_arguments.rs:4:4
    |
 LL | fn two_arg_diff(_a: i32, _b: &str) {}
    |    ^^^^^^^^^^^^ -------  --------
+help: remove the extra argument
+   |
+LL -   two_arg_diff(1, 1, "");
+LL +   two_arg_diff(1, "");
+   |
 
 error[E0061]: this function takes 2 arguments but 3 arguments were supplied
   --> $DIR/extra_arguments.rs:30:3
    |
 LL |   two_arg_diff(1, "", "");
-   |   ^^^^^^^^^^^^      ----
-   |                     | |
-   |                     | unexpected argument of type `&'static str`
-   |                     help: remove the extra argument
+   |   ^^^^^^^^^^^^        -- unexpected argument of type `&'static str`
    |
 note: function defined here
   --> $DIR/extra_arguments.rs:4:4
    |
 LL | fn two_arg_diff(_a: i32, _b: &str) {}
    |    ^^^^^^^^^^^^ -------  --------
+help: remove the extra argument
+   |
+LL -   two_arg_diff(1, "", "");
+LL +   two_arg_diff(1, "");
+   |
 
 error[E0061]: this function takes 2 arguments but 4 arguments were supplied
   --> $DIR/extra_arguments.rs:31:3
@@ -183,70 +197,75 @@ error[E0061]: this function takes 2 arguments but 3 arguments were supplied
   --> $DIR/extra_arguments.rs:35:3
    |
 LL |   two_arg_same(1, 1,     "");
-   |   ^^^^^^^^^^^^     --------
-   |                    |     |
-   |                    |     unexpected argument of type `&'static str`
-   |                    help: remove the extra argument
+   |   ^^^^^^^^^^^^           -- unexpected argument of type `&'static str`
    |
 note: function defined here
   --> $DIR/extra_arguments.rs:3:4
    |
 LL | fn two_arg_same(_a: i32, _b: i32) {}
    |    ^^^^^^^^^^^^ -------  -------
+help: remove the extra argument
+   |
+LL -   two_arg_same(1, 1,     "");
+LL +   two_arg_same(1, 1);
+   |
 
 error[E0061]: this function takes 2 arguments but 3 arguments were supplied
   --> $DIR/extra_arguments.rs:36:3
    |
 LL |   two_arg_diff(1, 1,     "");
-   |   ^^^^^^^^^^^^  ---
-   |                 | |
-   |                 | unexpected argument of type `{integer}`
-   |                 help: remove the extra argument
+   |   ^^^^^^^^^^^^    - unexpected argument of type `{integer}`
    |
 note: function defined here
   --> $DIR/extra_arguments.rs:4:4
    |
 LL | fn two_arg_diff(_a: i32, _b: &str) {}
    |    ^^^^^^^^^^^^ -------  --------
+help: remove the extra argument
+   |
+LL -   two_arg_diff(1, 1,     "");
+LL +   two_arg_diff(1,     "");
+   |
 
 error[E0061]: this function takes 2 arguments but 3 arguments were supplied
   --> $DIR/extra_arguments.rs:37:3
    |
-LL |     two_arg_same(
-   |     ^^^^^^^^^^^^
-LL |       1,
-LL |       1,
-   |  ______-
-LL | |     ""
-   | |     --
-   | |_____||
-   |       |help: remove the extra argument
-   |       unexpected argument of type `&'static str`
+LL |   two_arg_same(
+   |   ^^^^^^^^^^^^
+...
+LL |     ""
+   |     -- unexpected argument of type `&'static str`
    |
 note: function defined here
   --> $DIR/extra_arguments.rs:3:4
    |
 LL | fn two_arg_same(_a: i32, _b: i32) {}
    |    ^^^^^^^^^^^^ -------  -------
+help: remove the extra argument
+   |
+LL -     1,
+LL -     ""
+LL +     1
+   |
 
 error[E0061]: this function takes 2 arguments but 3 arguments were supplied
   --> $DIR/extra_arguments.rs:43:3
    |
-LL |     two_arg_diff(
-   |     ^^^^^^^^^^^^
-LL |       1,
-   |  ______-
-LL | |     1,
-   | |     -
-   | |     |
-   | |_____unexpected argument of type `{integer}`
-   |       help: remove the extra argument
+LL |   two_arg_diff(
+   |   ^^^^^^^^^^^^
+LL |     1,
+LL |     1,
+   |     - unexpected argument of type `{integer}`
    |
 note: function defined here
   --> $DIR/extra_arguments.rs:4:4
    |
 LL | fn two_arg_diff(_a: i32, _b: &str) {}
    |    ^^^^^^^^^^^^ -------  --------
+help: remove the extra argument
+   |
+LL -     1,
+   |
 
 error[E0061]: this function takes 0 arguments but 2 arguments were supplied
   --> $DIR/extra_arguments.rs:8:9
@@ -310,61 +329,69 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied
   --> $DIR/extra_arguments.rs:53:3
    |
 LL |   one_arg(1, panic!());
-   |   ^^^^^^^  ----------
-   |            | |
-   |            | unexpected argument
-   |            help: remove the extra argument
+   |   ^^^^^^^    -------- unexpected argument
    |
 note: function defined here
   --> $DIR/extra_arguments.rs:2:4
    |
 LL | fn one_arg<T>(_a: T) {}
    |    ^^^^^^^    -----
+help: remove the extra argument
+   |
+LL -   one_arg(1, panic!());
+LL +   one_arg(1);
+   |
 
 error[E0061]: this function takes 1 argument but 2 arguments were supplied
   --> $DIR/extra_arguments.rs:54:3
    |
 LL |   one_arg(panic!(), 1);
-   |   ^^^^^^^         ---
-   |                   | |
-   |                   | unexpected argument of type `{integer}`
-   |                   help: remove the extra argument
+   |   ^^^^^^^           - unexpected argument of type `{integer}`
    |
 note: function defined here
   --> $DIR/extra_arguments.rs:2:4
    |
 LL | fn one_arg<T>(_a: T) {}
    |    ^^^^^^^    -----
+help: remove the extra argument
+   |
+LL -   one_arg(panic!(), 1);
+LL +   one_arg(panic!());
+   |
 
 error[E0061]: this function takes 1 argument but 2 arguments were supplied
   --> $DIR/extra_arguments.rs:55:3
    |
 LL |   one_arg(stringify!($e), 1);
-   |   ^^^^^^^               ---
-   |                         | |
-   |                         | unexpected argument of type `{integer}`
-   |                         help: remove the extra argument
+   |   ^^^^^^^                 - unexpected argument of type `{integer}`
    |
 note: function defined here
   --> $DIR/extra_arguments.rs:2:4
    |
 LL | fn one_arg<T>(_a: T) {}
    |    ^^^^^^^    -----
+help: remove the extra argument
+   |
+LL -   one_arg(stringify!($e), 1);
+LL +   one_arg(stringify!($e));
+   |
 
 error[E0061]: this function takes 1 argument but 2 arguments were supplied
   --> $DIR/extra_arguments.rs:60:3
    |
 LL |   one_arg(for _ in 1.. {}, 1);
-   |   ^^^^^^^                ---
-   |                          | |
-   |                          | unexpected argument of type `{integer}`
-   |                          help: remove the extra argument
+   |   ^^^^^^^                  - unexpected argument of type `{integer}`
    |
 note: function defined here
   --> $DIR/extra_arguments.rs:2:4
    |
 LL | fn one_arg<T>(_a: T) {}
    |    ^^^^^^^    -----
+help: remove the extra argument
+   |
+LL -   one_arg(for _ in 1.. {}, 1);
+LL +   one_arg(for _ in 1.. {});
+   |
 
 error: aborting due to 22 previous errors
 
diff --git a/tests/ui/argument-suggestions/suggest-better-removing-issue-126246.stderr b/tests/ui/argument-suggestions/suggest-better-removing-issue-126246.stderr
index 7c4daa3ffe9..dc293945eb6 100644
--- a/tests/ui/argument-suggestions/suggest-better-removing-issue-126246.stderr
+++ b/tests/ui/argument-suggestions/suggest-better-removing-issue-126246.stderr
@@ -32,91 +32,103 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied
   --> $DIR/suggest-better-removing-issue-126246.rs:10:5
    |
 LL |     add_one(2, 2);
-   |     ^^^^^^^  ---
-   |              | |
-   |              | unexpected argument of type `{integer}`
-   |              help: remove the extra argument
+   |     ^^^^^^^    - unexpected argument of type `{integer}`
    |
 note: function defined here
   --> $DIR/suggest-better-removing-issue-126246.rs:1:4
    |
 LL | fn add_one(x: i32) -> i32 {
    |    ^^^^^^^ ------
+help: remove the extra argument
+   |
+LL -     add_one(2, 2);
+LL +     add_one(2);
+   |
 
 error[E0061]: this function takes 1 argument but 2 arguments were supplied
   --> $DIR/suggest-better-removing-issue-126246.rs:11:5
    |
 LL |     add_one(no_such_local, 10);
-   |     ^^^^^^^ ---------------
-   |             |
-   |             unexpected argument
-   |             help: remove the extra argument
+   |     ^^^^^^^ ------------- unexpected argument
    |
 note: function defined here
   --> $DIR/suggest-better-removing-issue-126246.rs:1:4
    |
 LL | fn add_one(x: i32) -> i32 {
    |    ^^^^^^^ ------
+help: remove the extra argument
+   |
+LL -     add_one(no_such_local, 10);
+LL +     add_one(10);
+   |
 
 error[E0061]: this function takes 1 argument but 2 arguments were supplied
   --> $DIR/suggest-better-removing-issue-126246.rs:13:5
    |
 LL |     add_one(10, no_such_local);
-   |     ^^^^^^^   ---------------
-   |               | |
-   |               | unexpected argument
-   |               help: remove the extra argument
+   |     ^^^^^^^     ------------- unexpected argument
    |
 note: function defined here
   --> $DIR/suggest-better-removing-issue-126246.rs:1:4
    |
 LL | fn add_one(x: i32) -> i32 {
    |    ^^^^^^^ ------
+help: remove the extra argument
+   |
+LL -     add_one(10, no_such_local);
+LL +     add_one(10);
+   |
 
 error[E0061]: this function takes 2 arguments but 3 arguments were supplied
   --> $DIR/suggest-better-removing-issue-126246.rs:15:5
    |
 LL |     add_two(10, no_such_local, 10);
-   |     ^^^^^^^   ---------------
-   |               | |
-   |               | unexpected argument
-   |               help: remove the extra argument
+   |     ^^^^^^^     ------------- unexpected argument
    |
 note: function defined here
   --> $DIR/suggest-better-removing-issue-126246.rs:5:4
    |
 LL | fn add_two(x: i32, y: i32) -> i32 {
    |    ^^^^^^^ ------  ------
+help: remove the extra argument
+   |
+LL -     add_two(10, no_such_local, 10);
+LL +     add_two(10, 10);
+   |
 
 error[E0061]: this function takes 2 arguments but 3 arguments were supplied
   --> $DIR/suggest-better-removing-issue-126246.rs:17:5
    |
 LL |     add_two(no_such_local, 10, 10);
-   |     ^^^^^^^ ---------------
-   |             |
-   |             unexpected argument
-   |             help: remove the extra argument
+   |     ^^^^^^^ ------------- unexpected argument
    |
 note: function defined here
   --> $DIR/suggest-better-removing-issue-126246.rs:5:4
    |
 LL | fn add_two(x: i32, y: i32) -> i32 {
    |    ^^^^^^^ ------  ------
+help: remove the extra argument
+   |
+LL -     add_two(no_such_local, 10, 10);
+LL +     add_two(10, 10);
+   |
 
 error[E0061]: this function takes 2 arguments but 3 arguments were supplied
   --> $DIR/suggest-better-removing-issue-126246.rs:19:5
    |
 LL |     add_two(10, 10, no_such_local);
-   |     ^^^^^^^       ---------------
-   |                   | |
-   |                   | unexpected argument
-   |                   help: remove the extra argument
+   |     ^^^^^^^         ------------- unexpected argument
    |
 note: function defined here
   --> $DIR/suggest-better-removing-issue-126246.rs:5:4
    |
 LL | fn add_two(x: i32, y: i32) -> i32 {
    |    ^^^^^^^ ------  ------
+help: remove the extra argument
+   |
+LL -     add_two(10, 10, no_such_local);
+LL +     add_two(10, 10);
+   |
 
 error: aborting due to 11 previous errors
 
diff --git a/tests/ui/associated-types/defaults-specialization.stderr b/tests/ui/associated-types/defaults-specialization.stderr
index 7ef433d859f..b4ed99f36f4 100644
--- a/tests/ui/associated-types/defaults-specialization.stderr
+++ b/tests/ui/associated-types/defaults-specialization.stderr
@@ -12,10 +12,7 @@ error[E0053]: method `make` has an incompatible type for trait
   --> $DIR/defaults-specialization.rs:19:18
    |
 LL |     fn make() -> u8 { 0 }
-   |                  ^^
-   |                  |
-   |                  expected associated type, found `u8`
-   |                  help: change the output type to match the trait: `<A<T> as Tr>::Ty`
+   |                  ^^ expected associated type, found `u8`
    |
 note: type in trait
   --> $DIR/defaults-specialization.rs:9:18
@@ -24,6 +21,10 @@ LL |     fn make() -> Self::Ty {
    |                  ^^^^^^^^
    = note: expected signature `fn() -> <A<T> as Tr>::Ty`
               found signature `fn() -> u8`
+help: change the output type to match the trait
+   |
+LL |     fn make() -> <A<T> as Tr>::Ty { 0 }
+   |                  ~~~~~~~~~~~~~~~~
 
 error[E0053]: method `make` has an incompatible type for trait
   --> $DIR/defaults-specialization.rs:35:18
@@ -32,10 +33,7 @@ LL |     default type Ty = bool;
    |     ----------------------- associated type is `default` and may be overridden
 LL |
 LL |     fn make() -> bool { true }
-   |                  ^^^^
-   |                  |
-   |                  expected associated type, found `bool`
-   |                  help: change the output type to match the trait: `<B<T> as Tr>::Ty`
+   |                  ^^^^ expected associated type, found `bool`
    |
 note: type in trait
   --> $DIR/defaults-specialization.rs:9:18
@@ -44,6 +42,10 @@ LL |     fn make() -> Self::Ty {
    |                  ^^^^^^^^
    = note: expected signature `fn() -> <B<T> as Tr>::Ty`
               found signature `fn() -> bool`
+help: change the output type to match the trait
+   |
+LL |     fn make() -> <B<T> as Tr>::Ty { true }
+   |                  ~~~~~~~~~~~~~~~~
 
 error[E0308]: mismatched types
   --> $DIR/defaults-specialization.rs:10:9
diff --git a/tests/ui/compare-method/bad-self-type.stderr b/tests/ui/compare-method/bad-self-type.stderr
index a87b713c2b4..29ebbc5dffb 100644
--- a/tests/ui/compare-method/bad-self-type.stderr
+++ b/tests/ui/compare-method/bad-self-type.stderr
@@ -2,22 +2,20 @@ error[E0053]: method `poll` has an incompatible type for trait
   --> $DIR/bad-self-type.rs:10:13
    |
 LL |     fn poll(self, _: &mut Context<'_>) -> Poll<()> {
-   |             ^^^^
-   |             |
-   |             expected `Pin<&mut MyFuture>`, found `MyFuture`
-   |             help: change the self-receiver type to match the trait: `self: Pin<&mut MyFuture>`
+   |             ^^^^ expected `Pin<&mut MyFuture>`, found `MyFuture`
    |
    = note: expected signature `fn(Pin<&mut MyFuture>, &mut Context<'_>) -> Poll<_>`
               found signature `fn(MyFuture, &mut Context<'_>) -> Poll<_>`
+help: change the self-receiver type to match the trait
+   |
+LL |     fn poll(self: Pin<&mut MyFuture>, _: &mut Context<'_>) -> Poll<()> {
+   |             ~~~~~~~~~~~~~~~~~~~~~~~~
 
 error[E0053]: method `foo` has an incompatible type for trait
   --> $DIR/bad-self-type.rs:22:18
    |
 LL |     fn foo(self: Box<Self>) {}
-   |            ------^^^^^^^^^
-   |            |     |
-   |            |     expected `MyFuture`, found `Box<MyFuture>`
-   |            help: change the self-receiver type to match the trait: `self`
+   |                  ^^^^^^^^^ expected `MyFuture`, found `Box<MyFuture>`
    |
 note: type in trait
   --> $DIR/bad-self-type.rs:17:12
@@ -26,6 +24,10 @@ LL |     fn foo(self);
    |            ^^^^
    = note: expected signature `fn(MyFuture)`
               found signature `fn(Box<MyFuture>)`
+help: change the self-receiver type to match the trait
+   |
+LL |     fn foo(self) {}
+   |            ~~~~
 
 error[E0053]: method `bar` has an incompatible type for trait
   --> $DIR/bad-self-type.rs:24:17
diff --git a/tests/ui/compare-method/issue-90444.stderr b/tests/ui/compare-method/issue-90444.stderr
index 52e23d03b14..f05c9939c00 100644
--- a/tests/ui/compare-method/issue-90444.stderr
+++ b/tests/ui/compare-method/issue-90444.stderr
@@ -2,25 +2,27 @@ error[E0053]: method `from` has an incompatible type for trait
   --> $DIR/issue-90444.rs:3:16
    |
 LL |     fn from(_: fn((), (), &mut ())) -> Self {
-   |                ^^^^^^^^^^^^^^^^^^^
-   |                |
-   |                types differ in mutability
-   |                help: change the parameter type to match the trait: `for<'a> fn((), (), &'a ())`
+   |                ^^^^^^^^^^^^^^^^^^^ types differ in mutability
    |
    = note: expected signature `fn(for<'a> fn((), (), &'a ())) -> A`
               found signature `fn(for<'a> fn((), (), &'a mut ())) -> A`
+help: change the parameter type to match the trait
+   |
+LL |     fn from(_: for<'a> fn((), (), &'a ())) -> Self {
+   |                ~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error[E0053]: method `from` has an incompatible type for trait
   --> $DIR/issue-90444.rs:11:16
    |
 LL |     fn from(_: fn((), (), u64)) -> Self {
-   |                ^^^^^^^^^^^^^^^
-   |                |
-   |                expected `u32`, found `u64`
-   |                help: change the parameter type to match the trait: `fn((), (), u32)`
+   |                ^^^^^^^^^^^^^^^ expected `u32`, found `u64`
    |
    = note: expected signature `fn(fn((), (), u32)) -> B`
               found signature `fn(fn((), (), u64)) -> B`
+help: change the parameter type to match the trait
+   |
+LL |     fn from(_: fn((), (), u32)) -> Self {
+   |                ~~~~~~~~~~~~~~~
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/compare-method/reordered-type-param.stderr b/tests/ui/compare-method/reordered-type-param.stderr
index 8a439acee13..1e8266e213d 100644
--- a/tests/ui/compare-method/reordered-type-param.stderr
+++ b/tests/ui/compare-method/reordered-type-param.stderr
@@ -2,10 +2,8 @@ error[E0053]: method `b` has an incompatible type for trait
   --> $DIR/reordered-type-param.rs:16:30
    |
 LL |   fn b<F:Clone,G>(&self, _x: G) -> G { panic!() }
-   |        -       -             ^
-   |        |       |             |
-   |        |       |             expected type parameter `F`, found type parameter `G`
-   |        |       |             help: change the parameter type to match the trait: `F`
+   |        -       -             ^ expected type parameter `F`, found type parameter `G`
+   |        |       |
    |        |       found type parameter
    |        expected type parameter
    |
@@ -18,6 +16,10 @@ LL |   fn b<C:Clone,D>(&self, x: C) -> C;
               found signature `fn(&E, G) -> G`
    = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
    = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
+help: change the parameter type to match the trait
+   |
+LL |   fn b<F:Clone,G>(&self, _x: F) -> G { panic!() }
+   |                              ~
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/error-codes/E0057.stderr b/tests/ui/error-codes/E0057.stderr
index 9b0cf069824..efd2af6d609 100644
--- a/tests/ui/error-codes/E0057.stderr
+++ b/tests/ui/error-codes/E0057.stderr
@@ -18,16 +18,18 @@ error[E0057]: this function takes 1 argument but 2 arguments were supplied
   --> $DIR/E0057.rs:5:13
    |
 LL |     let c = f(2, 3);
-   |             ^  ---
-   |                | |
-   |                | unexpected argument of type `{integer}`
-   |                help: remove the extra argument
+   |             ^    - unexpected argument of type `{integer}`
    |
 note: closure defined here
   --> $DIR/E0057.rs:2:13
    |
 LL |     let f = |x| x * 3;
    |             ^^^
+help: remove the extra argument
+   |
+LL -     let c = f(2, 3);
+LL +     let c = f(2);
+   |
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr b/tests/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr
index 1b9febd431d..06a606b09dc 100644
--- a/tests/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr
+++ b/tests/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr
@@ -89,13 +89,14 @@ error[E0053]: method `call` has an incompatible type for trait
   --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:13:32
    |
 LL |     extern "rust-call" fn call(self, args: ()) -> () {}
-   |                                ^^^^
-   |                                |
-   |                                expected `&Foo`, found `Foo`
-   |                                help: change the self-receiver type to match the trait: `&self`
+   |                                ^^^^ expected `&Foo`, found `Foo`
    |
    = note: expected signature `extern "rust-call" fn(&Foo, ()) -> _`
               found signature `extern "rust-call" fn(Foo, ())`
+help: change the self-receiver type to match the trait
+   |
+LL |     extern "rust-call" fn call(&self, args: ()) -> () {}
+   |                                ~~~~~
 
 error[E0183]: manual implementations of `FnOnce` are experimental
   --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:18:6
@@ -158,13 +159,14 @@ error[E0053]: method `call_mut` has an incompatible type for trait
   --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:30:36
    |
 LL |     extern "rust-call" fn call_mut(&self, args: ()) -> () {}
-   |                                    ^^^^^
-   |                                    |
-   |                                    types differ in mutability
-   |                                    help: change the self-receiver type to match the trait: `&mut self`
+   |                                    ^^^^^ types differ in mutability
    |
    = note: expected signature `extern "rust-call" fn(&mut Bar, ()) -> _`
               found signature `extern "rust-call" fn(&Bar, ())`
+help: change the self-receiver type to match the trait
+   |
+LL |     extern "rust-call" fn call_mut(&mut self, args: ()) -> () {}
+   |                                    ~~~~~~~~~
 
 error[E0046]: not all trait items implemented, missing: `Output`
   --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:35:1
diff --git a/tests/ui/impl-trait/impl-generic-mismatch-ab.stderr b/tests/ui/impl-trait/impl-generic-mismatch-ab.stderr
index 7046e729e18..90c31c9e3fc 100644
--- a/tests/ui/impl-trait/impl-generic-mismatch-ab.stderr
+++ b/tests/ui/impl-trait/impl-generic-mismatch-ab.stderr
@@ -2,10 +2,8 @@ error[E0053]: method `foo` has an incompatible type for trait
   --> $DIR/impl-generic-mismatch-ab.rs:8:32
    |
 LL |     fn foo<B: Debug>(&self, a: &impl Debug, b: &B) { }
-   |            -                   ^^^^^^^^^^^
-   |            |                   |
-   |            |                   expected type parameter `B`, found type parameter `impl Debug`
-   |            |                   help: change the parameter type to match the trait: `&B`
+   |            -                   ^^^^^^^^^^^ expected type parameter `B`, found type parameter `impl Debug`
+   |            |
    |            expected type parameter
    |
 note: type in trait
@@ -17,6 +15,10 @@ LL |     fn foo<A: Debug>(&self, a: &A, b: &impl Debug);
               found signature `fn(&(), &impl Debug, &B)`
    = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
    = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
+help: change the parameter type to match the trait
+   |
+LL |     fn foo<B: Debug>(&self, a: &B, b: &B) { }
+   |                                ~~
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/impl-trait/in-assoc-type-unconstrained.stderr b/tests/ui/impl-trait/in-assoc-type-unconstrained.stderr
index 8e61a65abe4..e32c59a75c6 100644
--- a/tests/ui/impl-trait/in-assoc-type-unconstrained.stderr
+++ b/tests/ui/impl-trait/in-assoc-type-unconstrained.stderr
@@ -27,10 +27,7 @@ LL |         type Ty = impl Sized;
    |                   ---------- the expected opaque type
 LL |
 LL |         fn method() -> () {}
-   |                        ^^
-   |                        |
-   |                        expected opaque type, found `()`
-   |                        help: change the output type to match the trait: `<() as compare_method::Trait>::Ty`
+   |                        ^^ expected opaque type, found `()`
    |
 note: type in trait
   --> $DIR/in-assoc-type-unconstrained.rs:17:24
@@ -44,6 +41,10 @@ note: this item must have the opaque type in its signature in order to be able t
    |
 LL |         fn method() -> () {}
    |            ^^^^^^
+help: change the output type to match the trait
+   |
+LL |         fn method() -> <() as compare_method::Trait>::Ty {}
+   |                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: unconstrained opaque type
   --> $DIR/in-assoc-type-unconstrained.rs:20:19
diff --git a/tests/ui/impl-trait/in-trait/method-signature-matches.lt.stderr b/tests/ui/impl-trait/in-trait/method-signature-matches.lt.stderr
index 2231205327c..6f6b787b6fe 100644
--- a/tests/ui/impl-trait/in-trait/method-signature-matches.lt.stderr
+++ b/tests/ui/impl-trait/in-trait/method-signature-matches.lt.stderr
@@ -2,10 +2,8 @@ error[E0053]: method `early` has an incompatible type for trait
   --> $DIR/method-signature-matches.rs:55:27
    |
 LL |     fn early<'late, T>(_: &'late ()) {}
-   |                     -     ^^^^^^^^^
-   |                     |     |
-   |                     |     expected type parameter `T`, found `()`
-   |                     |     help: change the parameter type to match the trait: `&T`
+   |                     -     ^^^^^^^^^ expected type parameter `T`, found `()`
+   |                     |
    |                     expected this type parameter
    |
 note: type in trait
@@ -15,6 +13,10 @@ LL |     fn early<'early, T>(x: &'early T) -> impl Sized;
    |                            ^^^^^^^^^
    = note: expected signature `fn(&T)`
               found signature `fn(&'late ())`
+help: change the parameter type to match the trait
+   |
+LL |     fn early<'late, T>(_: &T) {}
+   |                           ~~
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/impl-trait/in-trait/method-signature-matches.mismatch.stderr b/tests/ui/impl-trait/in-trait/method-signature-matches.mismatch.stderr
index ec2a126865d..9e18517e48c 100644
--- a/tests/ui/impl-trait/in-trait/method-signature-matches.mismatch.stderr
+++ b/tests/ui/impl-trait/in-trait/method-signature-matches.mismatch.stderr
@@ -2,10 +2,7 @@ error[E0053]: method `owo` has an incompatible type for trait
   --> $DIR/method-signature-matches.rs:11:15
    |
 LL |     fn owo(_: u8) {}
-   |               ^^
-   |               |
-   |               expected `()`, found `u8`
-   |               help: change the parameter type to match the trait: `()`
+   |               ^^ expected `()`, found `u8`
    |
 note: type in trait
   --> $DIR/method-signature-matches.rs:6:15
@@ -14,6 +11,10 @@ LL |     fn owo(x: ()) -> impl Sized;
    |               ^^
    = note: expected signature `fn(())`
               found signature `fn(u8)`
+help: change the parameter type to match the trait
+   |
+LL |     fn owo(_: ()) {}
+   |               ~~
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/impl-trait/in-trait/method-signature-matches.mismatch_async.stderr b/tests/ui/impl-trait/in-trait/method-signature-matches.mismatch_async.stderr
index 4d3e64e8050..c01d7322d11 100644
--- a/tests/ui/impl-trait/in-trait/method-signature-matches.mismatch_async.stderr
+++ b/tests/ui/impl-trait/in-trait/method-signature-matches.mismatch_async.stderr
@@ -2,10 +2,7 @@ error[E0053]: method `owo` has an incompatible type for trait
   --> $DIR/method-signature-matches.rs:22:21
    |
 LL |     async fn owo(_: u8) {}
-   |                     ^^
-   |                     |
-   |                     expected `()`, found `u8`
-   |                     help: change the parameter type to match the trait: `()`
+   |                     ^^ expected `()`, found `u8`
    |
 note: type in trait
   --> $DIR/method-signature-matches.rs:17:21
@@ -14,6 +11,10 @@ LL |     async fn owo(x: ()) {}
    |                     ^^
    = note: expected signature `fn(()) -> _`
               found signature `fn(u8) -> _`
+help: change the parameter type to match the trait
+   |
+LL |     async fn owo(_: ()) {}
+   |                     ~~
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/impl-trait/in-trait/opaque-and-lifetime-mismatch.stderr b/tests/ui/impl-trait/in-trait/opaque-and-lifetime-mismatch.stderr
index d7fc40fa342..1f8a0d5edd7 100644
--- a/tests/ui/impl-trait/in-trait/opaque-and-lifetime-mismatch.stderr
+++ b/tests/ui/impl-trait/in-trait/opaque-and-lifetime-mismatch.stderr
@@ -75,10 +75,7 @@ error[E0053]: method `bar` has an incompatible type for trait
   --> $DIR/opaque-and-lifetime-mismatch.rs:10:17
    |
 LL |     fn bar() -> i32 {
-   |                 ^^^
-   |                 |
-   |                 expected `Wrapper<'static>`, found `i32`
-   |                 help: change the output type to match the trait: `Wrapper<'static>`
+   |                 ^^^ expected `Wrapper<'static>`, found `i32`
    |
 note: type in trait
   --> $DIR/opaque-and-lifetime-mismatch.rs:4:17
@@ -87,6 +84,10 @@ LL |     fn bar() -> Wrapper<impl Sized>;
    |                 ^^^^^^^^^^^^^^^^^^^
    = note: expected signature `fn() -> Wrapper<'static>`
               found signature `fn() -> i32`
+help: change the output type to match the trait
+   |
+LL |     fn bar() -> Wrapper<'static> {
+   |                 ~~~~~~~~~~~~~~~~
 
 error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/opaque-and-lifetime-mismatch.rs:24:17
diff --git a/tests/ui/impl-trait/in-trait/specialization-broken.stderr b/tests/ui/impl-trait/in-trait/specialization-broken.stderr
index b8a8e2401b2..8c9f2656015 100644
--- a/tests/ui/impl-trait/in-trait/specialization-broken.stderr
+++ b/tests/ui/impl-trait/in-trait/specialization-broken.stderr
@@ -5,10 +5,7 @@ LL | default impl<U> Foo for U
    |              - found this type parameter
 ...
 LL |     fn bar(&self) -> U {
-   |                      ^
-   |                      |
-   |                      expected associated type, found type parameter `U`
-   |                      help: change the output type to match the trait: `impl Sized`
+   |                      ^ expected associated type, found type parameter `U`
    |
 note: type in trait
   --> $DIR/specialization-broken.rs:8:22
@@ -17,6 +14,10 @@ LL |     fn bar(&self) -> impl Sized;
    |                      ^^^^^^^^^^
    = note: expected signature `fn(&_) -> impl Sized`
               found signature `fn(&_) -> U`
+help: change the output type to match the trait
+   |
+LL |     fn bar(&self) -> impl Sized {
+   |                      ~~~~~~~~~~
 
 error: method with return-position `impl Trait` in trait cannot be specialized
   --> $DIR/specialization-broken.rs:15:5
diff --git a/tests/ui/impl-trait/opaque-used-in-extraneous-argument.stderr b/tests/ui/impl-trait/opaque-used-in-extraneous-argument.stderr
index 6d417488533..caaac5434c5 100644
--- a/tests/ui/impl-trait/opaque-used-in-extraneous-argument.stderr
+++ b/tests/ui/impl-trait/opaque-used-in-extraneous-argument.stderr
@@ -57,31 +57,35 @@ error[E0061]: this function takes 0 arguments but 1 argument was supplied
   --> $DIR/opaque-used-in-extraneous-argument.rs:17:20
    |
 LL |     let old_path = frob("hello");
-   |                    ^^^^ -------
-   |                         |
-   |                         unexpected argument of type `&'static str`
-   |                         help: remove the extra argument
+   |                    ^^^^ ------- unexpected argument of type `&'static str`
    |
 note: function defined here
   --> $DIR/opaque-used-in-extraneous-argument.rs:5:4
    |
 LL | fn frob() -> impl Fn<P, Output = T> + '_ {}
    |    ^^^^
+help: remove the extra argument
+   |
+LL -     let old_path = frob("hello");
+LL +     let old_path = frob();
+   |
 
 error[E0061]: this function takes 0 arguments but 1 argument was supplied
   --> $DIR/opaque-used-in-extraneous-argument.rs:20:5
    |
 LL |     open_parent(&old_path)
-   |     ^^^^^^^^^^^ ---------
-   |                 |
-   |                 unexpected argument of type `&impl FnOnce<{type error}, Output = {type error}> + Fn<{type error}> + 'static`
-   |                 help: remove the extra argument
+   |     ^^^^^^^^^^^ --------- unexpected argument of type `&impl FnOnce<{type error}, Output = {type error}> + Fn<{type error}> + 'static`
    |
 note: function defined here
   --> $DIR/opaque-used-in-extraneous-argument.rs:12:4
    |
 LL | fn open_parent<'path>() {
    |    ^^^^^^^^^^^
+help: remove the extra argument
+   |
+LL -     open_parent(&old_path)
+LL +     open_parent()
+   |
 
 error: aborting due to 7 previous errors
 
diff --git a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr
index 4352af1c0df..3692cc77b0f 100644
--- a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr
+++ b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr
@@ -26,13 +26,14 @@ LL |     type Foo = impl PartialEq<(Foo, i32)>;
    |                -------------------------- the found opaque type
 ...
 LL |         fn eq(&self, _other: &(Foo, i32)) -> bool {
-   |                              ^^^^^^^^^^^
-   |                              |
-   |                              expected `a::Bar`, found opaque type
-   |                              help: change the parameter type to match the trait: `&(a::Bar, i32)`
+   |                              ^^^^^^^^^^^ expected `a::Bar`, found opaque type
    |
    = note: expected signature `fn(&a::Bar, &(a::Bar, _)) -> _`
               found signature `fn(&a::Bar, &(a::Foo, _)) -> _`
+help: change the parameter type to match the trait
+   |
+LL |         fn eq(&self, _other: &(a::Bar, i32)) -> bool {
+   |                              ~~~~~~~~~~~~~~
 
 error: unconstrained opaque type
   --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:19:16
@@ -49,10 +50,7 @@ LL |     type Foo = impl PartialEq<(Foo, i32)>;
    |                -------------------------- the expected opaque type
 ...
 LL |         fn eq(&self, _other: &(Bar, i32)) -> bool {
-   |                              ^^^^^^^^^^^
-   |                              |
-   |                              expected opaque type, found `b::Bar`
-   |                              help: change the parameter type to match the trait: `&(b::Foo, i32)`
+   |                              ^^^^^^^^^^^ expected opaque type, found `b::Bar`
    |
    = note: expected signature `fn(&b::Bar, &(b::Foo, _)) -> _`
               found signature `fn(&b::Bar, &(b::Bar, _)) -> _`
@@ -61,6 +59,10 @@ note: this item must have the opaque type in its signature in order to be able t
    |
 LL |         fn eq(&self, _other: &(Bar, i32)) -> bool {
    |            ^^
+help: change the parameter type to match the trait
+   |
+LL |         fn eq(&self, _other: &(b::Foo, i32)) -> bool {
+   |                              ~~~~~~~~~~~~~~
 
 error: aborting due to 5 previous errors
 
diff --git a/tests/ui/impl-trait/trait_type.stderr b/tests/ui/impl-trait/trait_type.stderr
index 81e4c933e53..0eb132c7a19 100644
--- a/tests/ui/impl-trait/trait_type.stderr
+++ b/tests/ui/impl-trait/trait_type.stderr
@@ -2,13 +2,14 @@ error[E0053]: method `fmt` has an incompatible type for trait
   --> $DIR/trait_type.rs:7:21
    |
 LL |    fn fmt(&self, x: &str) -> () { }
-   |                     ^^^^
-   |                     |
-   |                     types differ in mutability
-   |                     help: change the parameter type to match the trait: `&mut Formatter<'_>`
+   |                     ^^^^ types differ in mutability
    |
    = note: expected signature `fn(&MyType, &mut Formatter<'_>) -> Result<(), std::fmt::Error>`
               found signature `fn(&MyType, &str)`
+help: change the parameter type to match the trait
+   |
+LL |    fn fmt(&self, x: &mut Formatter<'_>) -> () { }
+   |                     ~~~~~~~~~~~~~~~~~~
 
 error[E0050]: method `fmt` has 1 parameter but the declaration in trait `std::fmt::Display::fmt` has 2
   --> $DIR/trait_type.rs:12:11
diff --git a/tests/ui/impl-trait/where-allowed.stderr b/tests/ui/impl-trait/where-allowed.stderr
index bffe0447f8b..f0d259d01de 100644
--- a/tests/ui/impl-trait/where-allowed.stderr
+++ b/tests/ui/impl-trait/where-allowed.stderr
@@ -397,10 +397,7 @@ LL |     type Out = impl Debug;
    |                ---------- the expected opaque type
 ...
 LL |     fn in_trait_impl_return() -> impl Debug { () }
-   |                                  ^^^^^^^^^^
-   |                                  |
-   |                                  expected opaque type, found a different opaque type
-   |                                  help: change the output type to match the trait: `<() as DummyTrait>::Out`
+   |                                  ^^^^^^^^^^ expected opaque type, found a different opaque type
    |
 note: type in trait
   --> $DIR/where-allowed.rs:119:34
@@ -410,6 +407,10 @@ LL |     fn in_trait_impl_return() -> Self::Out;
    = note: expected signature `fn() -> <() as DummyTrait>::Out`
               found signature `fn() -> impl Debug`
    = note: distinct uses of `impl Trait` result in different opaque types
+help: change the output type to match the trait
+   |
+LL |     fn in_trait_impl_return() -> <() as DummyTrait>::Out { () }
+   |                                  ~~~~~~~~~~~~~~~~~~~~~~~
 
 error: unconstrained opaque type
   --> $DIR/where-allowed.rs:122:16
diff --git a/tests/ui/inference/ice-ifer-var-leaked-out-of-rollback-122098.stderr b/tests/ui/inference/ice-ifer-var-leaked-out-of-rollback-122098.stderr
index e2ddf474c4a..a5cd057e284 100644
--- a/tests/ui/inference/ice-ifer-var-leaked-out-of-rollback-122098.stderr
+++ b/tests/ui/inference/ice-ifer-var-leaked-out-of-rollback-122098.stderr
@@ -55,16 +55,18 @@ error[E0061]: this function takes 0 arguments but 1 argument was supplied
   --> $DIR/ice-ifer-var-leaked-out-of-rollback-122098.rs:21:31
    |
 LL |     LendingIterator::for_each(Query::new(&data), Box::new);
-   |                               ^^^^^^^^^^ -----
-   |                                          |
-   |                                          unexpected argument of type `&fn() {data}`
-   |                                          help: remove the extra argument
+   |                               ^^^^^^^^^^ ----- unexpected argument of type `&fn() {data}`
    |
 note: associated function defined here
   --> $DIR/ice-ifer-var-leaked-out-of-rollback-122098.rs:17:12
    |
 LL |     pub fn new() -> Self {}
    |            ^^^
+help: remove the extra argument
+   |
+LL -     LendingIterator::for_each(Query::new(&data), Box::new);
+LL +     LendingIterator::for_each(Query::new(), Box::new);
+   |
 
 error: aborting due to 6 previous errors
 
diff --git a/tests/ui/issues/issue-16939.stderr b/tests/ui/issues/issue-16939.stderr
index 229ff9f1817..6e0889b8963 100644
--- a/tests/ui/issues/issue-16939.stderr
+++ b/tests/ui/issues/issue-16939.stderr
@@ -2,16 +2,18 @@ error[E0057]: this function takes 0 arguments but 1 argument was supplied
   --> $DIR/issue-16939.rs:5:9
    |
 LL |     |t| f(t);
-   |         ^ -
-   |           |
-   |           unexpected argument
-   |           help: remove the extra argument
+   |         ^ - unexpected argument
    |
 note: callable defined here
   --> $DIR/issue-16939.rs:4:12
    |
 LL | fn _foo<F: Fn()> (f: F) {
    |            ^^^^
+help: remove the extra argument
+   |
+LL -     |t| f(t);
+LL +     |t| f();
+   |
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/issues/issue-20225.stderr b/tests/ui/issues/issue-20225.stderr
index 2d24a5bbd50..7d6b09cf7f8 100644
--- a/tests/ui/issues/issue-20225.stderr
+++ b/tests/ui/issues/issue-20225.stderr
@@ -4,13 +4,14 @@ error[E0053]: method `call` has an incompatible type for trait
 LL | impl<'a, T> Fn<(&'a T,)> for Foo {
    |          - found this type parameter
 LL |   extern "rust-call" fn call(&self, (_,): (T,)) {}
-   |                                           ^^^^
-   |                                           |
-   |                                           expected `&'a T`, found type parameter `T`
-   |                                           help: change the parameter type to match the trait: `(&'a T,)`
+   |                                           ^^^^ expected `&'a T`, found type parameter `T`
    |
    = note: expected signature `extern "rust-call" fn(&Foo, (&'a _,))`
               found signature `extern "rust-call" fn(&Foo, (_,))`
+help: change the parameter type to match the trait
+   |
+LL |   extern "rust-call" fn call(&self, (_,): (&'a T,)) {}
+   |                                           ~~~~~~~~
 
 error[E0053]: method `call_mut` has an incompatible type for trait
   --> $DIR/issue-20225.rs:11:51
@@ -18,13 +19,14 @@ error[E0053]: method `call_mut` has an incompatible type for trait
 LL | impl<'a, T> FnMut<(&'a T,)> for Foo {
    |          - found this type parameter
 LL |   extern "rust-call" fn call_mut(&mut self, (_,): (T,)) {}
-   |                                                   ^^^^
-   |                                                   |
-   |                                                   expected `&'a T`, found type parameter `T`
-   |                                                   help: change the parameter type to match the trait: `(&'a T,)`
+   |                                                   ^^^^ expected `&'a T`, found type parameter `T`
    |
    = note: expected signature `extern "rust-call" fn(&mut Foo, (&'a _,))`
               found signature `extern "rust-call" fn(&mut Foo, (_,))`
+help: change the parameter type to match the trait
+   |
+LL |   extern "rust-call" fn call_mut(&mut self, (_,): (&'a T,)) {}
+   |                                                   ~~~~~~~~
 
 error[E0053]: method `call_once` has an incompatible type for trait
   --> $DIR/issue-20225.rs:18:47
@@ -33,13 +35,14 @@ LL | impl<'a, T> FnOnce<(&'a T,)> for Foo {
    |          - found this type parameter
 ...
 LL |   extern "rust-call" fn call_once(self, (_,): (T,)) {}
-   |                                               ^^^^
-   |                                               |
-   |                                               expected `&'a T`, found type parameter `T`
-   |                                               help: change the parameter type to match the trait: `(&'a T,)`
+   |                                               ^^^^ expected `&'a T`, found type parameter `T`
    |
    = note: expected signature `extern "rust-call" fn(Foo, (&'a _,))`
               found signature `extern "rust-call" fn(Foo, (_,))`
+help: change the parameter type to match the trait
+   |
+LL |   extern "rust-call" fn call_once(self, (_,): (&'a T,)) {}
+   |                                               ~~~~~~~~
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/issues/issue-21332.stderr b/tests/ui/issues/issue-21332.stderr
index 96e0f5fdb31..7c960f7646d 100644
--- a/tests/ui/issues/issue-21332.stderr
+++ b/tests/ui/issues/issue-21332.stderr
@@ -2,13 +2,14 @@ error[E0053]: method `next` has an incompatible type for trait
   --> $DIR/issue-21332.rs:5:27
    |
 LL |     fn next(&mut self) -> Result<i32, i32> { Ok(7) }
-   |                           ^^^^^^^^^^^^^^^^
-   |                           |
-   |                           expected `Option<i32>`, found `Result<i32, i32>`
-   |                           help: change the output type to match the trait: `Option<i32>`
+   |                           ^^^^^^^^^^^^^^^^ expected `Option<i32>`, found `Result<i32, i32>`
    |
    = note: expected signature `fn(&mut S) -> Option<i32>`
               found signature `fn(&mut S) -> Result<i32, i32>`
+help: change the output type to match the trait
+   |
+LL |     fn next(&mut self) -> Option<i32> { Ok(7) }
+   |                           ~~~~~~~~~~~
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/issues/issue-4935.stderr b/tests/ui/issues/issue-4935.stderr
index 25f299ae5f3..f18cf66f14d 100644
--- a/tests/ui/issues/issue-4935.stderr
+++ b/tests/ui/issues/issue-4935.stderr
@@ -2,16 +2,18 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied
   --> $DIR/issue-4935.rs:5:13
    |
 LL | fn main() { foo(5, 6) }
-   |             ^^^  ---
-   |                  | |
-   |                  | unexpected argument of type `{integer}`
-   |                  help: remove the extra argument
+   |             ^^^    - unexpected argument of type `{integer}`
    |
 note: function defined here
   --> $DIR/issue-4935.rs:3:4
    |
 LL | fn foo(a: usize) {}
    |    ^^^ --------
+help: remove the extra argument
+   |
+LL - fn main() { foo(5, 6) }
+LL + fn main() { foo(5) }
+   |
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021.rs b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021.rs
index d28567f2859..afea249ffef 100644
--- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021.rs
+++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021.rs
@@ -1,37 +1,15 @@
+//@ run-pass
 //@ edition: 2021
+//@ revisions: classic structural both
 #![allow(incomplete_features)]
-#![feature(ref_pat_eat_one_layer_2024)]
+#![cfg_attr(any(classic, both), feature(ref_pat_eat_one_layer_2024))]
+#![cfg_attr(any(structural, both), feature(ref_pat_eat_one_layer_2024_structural))]
+
 pub fn main() {
-    if let Some(Some(&x)) = &Some(&Some(0)) {
-        //~^ ERROR: mismatched types
-        let _: u32 = x;
-    }
-    if let Some(Some(&x)) = &Some(Some(&0)) {
+    if let &Some(Some(x)) = &Some(&mut Some(0)) {
         let _: &u32 = x;
-        //~^ ERROR: mismatched types
-    }
-    if let Some(Some(&&x)) = &Some(Some(&0)) {
-        //~^ ERROR: mismatched types
-        let _: u32 = x;
-    }
-    if let Some(&Some(x)) = &Some(Some(0)) {
-        //~^ ERROR: mismatched types
-        let _: u32 = x;
-    }
-    if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
-        //~^ ERROR: mismatched types
-        let _: u32 = x;
-    }
-    if let Some(Some(&x)) = &Some(&Some(0)) {
-        //~^ ERROR: mismatched types
-        let _: u32 = x;
-    }
-    if let Some(&mut Some(&x)) = &Some(&mut Some(0)) {
-        //~^ ERROR: mismatched types
-        let _: u32 = x;
     }
-    if let Some(&Some(&mut x)) = &mut Some(&Some(0)) {
-        //~^ ERROR: mismatched types
+    if let Some(&x) = Some(&mut 0) {
         let _: u32 = x;
     }
 }
diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021_fail.rs b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021_fail.rs
new file mode 100644
index 00000000000..d28567f2859
--- /dev/null
+++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021_fail.rs
@@ -0,0 +1,37 @@
+//@ edition: 2021
+#![allow(incomplete_features)]
+#![feature(ref_pat_eat_one_layer_2024)]
+pub fn main() {
+    if let Some(Some(&x)) = &Some(&Some(0)) {
+        //~^ ERROR: mismatched types
+        let _: u32 = x;
+    }
+    if let Some(Some(&x)) = &Some(Some(&0)) {
+        let _: &u32 = x;
+        //~^ ERROR: mismatched types
+    }
+    if let Some(Some(&&x)) = &Some(Some(&0)) {
+        //~^ ERROR: mismatched types
+        let _: u32 = x;
+    }
+    if let Some(&Some(x)) = &Some(Some(0)) {
+        //~^ ERROR: mismatched types
+        let _: u32 = x;
+    }
+    if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
+        //~^ ERROR: mismatched types
+        let _: u32 = x;
+    }
+    if let Some(Some(&x)) = &Some(&Some(0)) {
+        //~^ ERROR: mismatched types
+        let _: u32 = x;
+    }
+    if let Some(&mut Some(&x)) = &Some(&mut Some(0)) {
+        //~^ ERROR: mismatched types
+        let _: u32 = x;
+    }
+    if let Some(&Some(&mut x)) = &mut Some(&Some(0)) {
+        //~^ ERROR: mismatched types
+        let _: u32 = x;
+    }
+}
diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021.stderr b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021_fail.stderr
index 28706f89c06..1a921234ea0 100644
--- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021.stderr
+++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021_fail.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2021.rs:5:22
+  --> $DIR/ref_pat_eat_one_layer_2021_fail.rs:5:22
    |
 LL |     if let Some(Some(&x)) = &Some(&Some(0)) {
    |                      ^^     --------------- this expression has type `&Option<&Option<{integer}>>`
@@ -14,7 +14,7 @@ LL |     if let Some(Some(x)) = &Some(&Some(0)) {
    |                      ~
 
 error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2021.rs:10:23
+  --> $DIR/ref_pat_eat_one_layer_2021_fail.rs:10:23
    |
 LL |         let _: &u32 = x;
    |                ----   ^ expected `&u32`, found integer
@@ -27,7 +27,7 @@ LL |         let _: &u32 = &x;
    |                       +
 
 error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2021.rs:13:23
+  --> $DIR/ref_pat_eat_one_layer_2021_fail.rs:13:23
    |
 LL |     if let Some(Some(&&x)) = &Some(Some(&0)) {
    |                       ^^     --------------- this expression has type `&Option<Option<&{integer}>>`
@@ -43,7 +43,7 @@ LL +     if let Some(Some(&x)) = &Some(Some(&0)) {
    |
 
 error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2021.rs:17:17
+  --> $DIR/ref_pat_eat_one_layer_2021_fail.rs:17:17
    |
 LL |     if let Some(&Some(x)) = &Some(Some(0)) {
    |                 ^^^^^^^^    -------------- this expression has type `&Option<Option<{integer}>>`
@@ -54,7 +54,7 @@ LL |     if let Some(&Some(x)) = &Some(Some(0)) {
            found reference `&_`
 
 error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2021.rs:21:22
+  --> $DIR/ref_pat_eat_one_layer_2021_fail.rs:21:22
    |
 LL |     if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
    |                      ^^^^^^     ----------------------- this expression has type `&mut Option<&mut Option<{integer}>>`
@@ -64,7 +64,7 @@ LL |     if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
    = note:           expected type `{integer}`
            found mutable reference `&mut _`
 note: to declare a mutable binding use: `mut x`
-  --> $DIR/ref_pat_eat_one_layer_2021.rs:21:22
+  --> $DIR/ref_pat_eat_one_layer_2021_fail.rs:21:22
    |
 LL |     if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
    |                      ^^^^^^
@@ -74,7 +74,7 @@ LL |     if let Some(Some(x)) = &mut Some(&mut Some(0)) {
    |                      ~
 
 error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2021.rs:25:22
+  --> $DIR/ref_pat_eat_one_layer_2021_fail.rs:25:22
    |
 LL |     if let Some(Some(&x)) = &Some(&Some(0)) {
    |                      ^^     --------------- this expression has type `&Option<&Option<{integer}>>`
@@ -89,7 +89,7 @@ LL |     if let Some(Some(x)) = &Some(&Some(0)) {
    |                      ~
 
 error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2021.rs:29:27
+  --> $DIR/ref_pat_eat_one_layer_2021_fail.rs:29:27
    |
 LL |     if let Some(&mut Some(&x)) = &Some(&mut Some(0)) {
    |                           ^^     ------------------- this expression has type `&Option<&mut Option<{integer}>>`
@@ -104,7 +104,7 @@ LL |     if let Some(&mut Some(x)) = &Some(&mut Some(0)) {
    |                           ~
 
 error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2021.rs:33:23
+  --> $DIR/ref_pat_eat_one_layer_2021_fail.rs:33:23
    |
 LL |     if let Some(&Some(&mut x)) = &mut Some(&Some(0)) {
    |                       ^^^^^^     ------------------- this expression has type `&mut Option<&Option<{integer}>>`
@@ -114,7 +114,7 @@ LL |     if let Some(&Some(&mut x)) = &mut Some(&Some(0)) {
    = note:           expected type `{integer}`
            found mutable reference `&mut _`
 note: to declare a mutable binding use: `mut x`
-  --> $DIR/ref_pat_eat_one_layer_2021.rs:33:23
+  --> $DIR/ref_pat_eat_one_layer_2021_fail.rs:33:23
    |
 LL |     if let Some(&Some(&mut x)) = &mut Some(&Some(0)) {
    |                       ^^^^^^
diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs
index 0130189b874..c6a699d2ff8 100644
--- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs
+++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs
@@ -63,4 +63,27 @@ pub fn main() {
     if let Some(&mut x) = &Some(&mut 0) {
         let _: &u32 = x;
     }
+
+    fn generic<R: Ref>() -> (R, bool) {
+        R::meow()
+    }
+
+    trait Ref: Sized {
+        fn meow() -> (Self, bool);
+    }
+
+    impl Ref for &'static [(); 0] {
+        fn meow() -> (Self, bool) {
+            (&[], false)
+        }
+    }
+
+    impl Ref for &'static mut [(); 0] {
+        fn meow() -> (Self, bool) {
+            (&mut [], true)
+        }
+    }
+
+    let (&_, b) = generic();
+    assert!(!b);
 }
diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.both.stderr b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.both.stderr
index f8931403774..0215df98ea1 100644
--- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.both.stderr
+++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.both.stderr
@@ -150,7 +150,20 @@ LL |     let Foo(mut a) = &mut Foo(0);
    = help: add `#![feature(mut_ref)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-error: aborting due to 14 previous errors
+error[E0277]: the trait bound `&_: main::Ref` is not satisfied
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:83:14
+   |
+LL |     let &_ = generic();
+   |              ^^^^^^^^^ the trait `main::Ref` is not implemented for `&_`
+   |
+   = help: the trait `main::Ref` is implemented for `&'static mut [(); 0]`
+note: required by a bound in `generic`
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:69:19
+   |
+LL |     fn generic<R: Ref>() -> R {
+   |                   ^^^ required by this bound in `generic`
+
+error: aborting due to 15 previous errors
 
-Some errors have detailed explanations: E0308, E0658.
-For more information about an error, try `rustc --explain E0308`.
+Some errors have detailed explanations: E0277, E0308, E0658.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.classic.stderr b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.classic.stderr
index 0010a612c30..9428b32c4af 100644
--- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.classic.stderr
+++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.classic.stderr
@@ -180,7 +180,20 @@ LL |     let Foo(mut a) = &mut Foo(0);
    = help: add `#![feature(mut_ref)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-error: aborting due to 16 previous errors
+error[E0277]: the trait bound `&_: main::Ref` is not satisfied
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:83:14
+   |
+LL |     let &_ = generic();
+   |              ^^^^^^^^^ the trait `main::Ref` is not implemented for `&_`
+   |
+   = help: the trait `main::Ref` is implemented for `&'static mut [(); 0]`
+note: required by a bound in `generic`
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:69:19
+   |
+LL |     fn generic<R: Ref>() -> R {
+   |                   ^^^ required by this bound in `generic`
+
+error: aborting due to 17 previous errors
 
-Some errors have detailed explanations: E0308, E0658.
-For more information about an error, try `rustc --explain E0308`.
+Some errors have detailed explanations: E0277, E0308, E0658.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs
index 4a40060b2ea..d23e9c8083d 100644
--- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs
+++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs
@@ -65,4 +65,20 @@ pub fn main() {
     let Foo(mut a) = &mut Foo(0);
     //~^ ERROR: binding cannot be both mutable and by-reference
     a = &mut 42;
+
+    fn generic<R: Ref>() -> R {
+        R::meow()
+    }
+
+    trait Ref: Sized {
+        fn meow() -> Self;
+    }
+
+    impl Ref for &'static mut [(); 0] {
+        fn meow() -> Self {
+            &mut []
+        }
+    }
+
+    let &_ = generic(); //~ERROR: the trait bound `&_: main::Ref` is not satisfied [E0277]
 }
diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.structural.stderr b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.structural.stderr
index 379bb6f4eaa..56dad605030 100644
--- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.structural.stderr
+++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.structural.stderr
@@ -161,7 +161,20 @@ LL |     let Foo(mut a) = &mut Foo(0);
    = help: add `#![feature(mut_ref)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-error: aborting due to 15 previous errors
+error[E0277]: the trait bound `&_: main::Ref` is not satisfied
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:83:14
+   |
+LL |     let &_ = generic();
+   |              ^^^^^^^^^ the trait `main::Ref` is not implemented for `&_`
+   |
+   = help: the trait `main::Ref` is implemented for `&'static mut [(); 0]`
+note: required by a bound in `generic`
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:69:19
+   |
+LL |     fn generic<R: Ref>() -> R {
+   |                   ^^^ required by this bound in `generic`
+
+error: aborting due to 16 previous errors
 
-Some errors have detailed explanations: E0308, E0658.
-For more information about an error, try `rustc --explain E0308`.
+Some errors have detailed explanations: E0277, E0308, E0658.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/methods/method-call-err-msg.stderr b/tests/ui/methods/method-call-err-msg.stderr
index 5a76449e9f9..0855a17b333 100644
--- a/tests/ui/methods/method-call-err-msg.stderr
+++ b/tests/ui/methods/method-call-err-msg.stderr
@@ -2,16 +2,18 @@ error[E0061]: this method takes 0 arguments but 1 argument was supplied
   --> $DIR/method-call-err-msg.rs:13:7
    |
 LL |     x.zero(0)
-   |       ^^^^ -
-   |            |
-   |            unexpected argument of type `{integer}`
-   |            help: remove the extra argument
+   |       ^^^^ - unexpected argument of type `{integer}`
    |
 note: method defined here
   --> $DIR/method-call-err-msg.rs:5:8
    |
 LL |     fn zero(self) -> Foo { self }
    |        ^^^^
+help: remove the extra argument
+   |
+LL -     x.zero(0)
+LL +     x.zero()
+   |
 
 error[E0061]: this method takes 1 argument but 0 arguments were supplied
   --> $DIR/method-call-err-msg.rs:14:7
diff --git a/tests/ui/mismatched_types/E0053.stderr b/tests/ui/mismatched_types/E0053.stderr
index d0bd5b46cf5..2559d448749 100644
--- a/tests/ui/mismatched_types/E0053.stderr
+++ b/tests/ui/mismatched_types/E0053.stderr
@@ -2,10 +2,7 @@ error[E0053]: method `foo` has an incompatible type for trait
   --> $DIR/E0053.rs:9:15
    |
 LL |     fn foo(x: i16) { }
-   |               ^^^
-   |               |
-   |               expected `u16`, found `i16`
-   |               help: change the parameter type to match the trait: `u16`
+   |               ^^^ expected `u16`, found `i16`
    |
 note: type in trait
   --> $DIR/E0053.rs:2:15
@@ -14,15 +11,16 @@ LL |     fn foo(x: u16);
    |               ^^^
    = note: expected signature `fn(u16)`
               found signature `fn(i16)`
+help: change the parameter type to match the trait
+   |
+LL |     fn foo(x: u16) { }
+   |               ~~~
 
 error[E0053]: method `bar` has an incompatible type for trait
   --> $DIR/E0053.rs:11:12
    |
 LL |     fn bar(&mut self) { }
-   |            ^^^^^^^^^
-   |            |
-   |            types differ in mutability
-   |            help: change the self-receiver type to match the trait: `&self`
+   |            ^^^^^^^^^ types differ in mutability
    |
 note: type in trait
   --> $DIR/E0053.rs:3:12
@@ -31,6 +29,10 @@ LL |     fn bar(&self);
    |            ^^^^^
    = note: expected signature `fn(&Bar)`
               found signature `fn(&mut Bar)`
+help: change the self-receiver type to match the trait
+   |
+LL |     fn bar(&self) { }
+   |            ~~~~~
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/mismatched_types/issue-112036.stderr b/tests/ui/mismatched_types/issue-112036.stderr
index b93ce4a8674..bd446b3d78c 100644
--- a/tests/ui/mismatched_types/issue-112036.stderr
+++ b/tests/ui/mismatched_types/issue-112036.stderr
@@ -2,13 +2,14 @@ error[E0053]: method `drop` has an incompatible type for trait
   --> $DIR/issue-112036.rs:4:13
    |
 LL |     fn drop(self) {}
-   |             ^^^^
-   |             |
-   |             expected `&mut Foo`, found `Foo`
-   |             help: change the self-receiver type to match the trait: `&mut self`
+   |             ^^^^ expected `&mut Foo`, found `Foo`
    |
    = note: expected signature `fn(&mut Foo)`
               found signature `fn(Foo)`
+help: change the self-receiver type to match the trait
+   |
+LL |     fn drop(&mut self) {}
+   |             ~~~~~~~~~
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/mismatched_types/issue-13033.stderr b/tests/ui/mismatched_types/issue-13033.stderr
index 4886fa30e89..2a266d40e77 100644
--- a/tests/ui/mismatched_types/issue-13033.stderr
+++ b/tests/ui/mismatched_types/issue-13033.stderr
@@ -2,10 +2,7 @@ error[E0053]: method `bar` has an incompatible type for trait
   --> $DIR/issue-13033.rs:8:30
    |
 LL |     fn bar(&mut self, other: &dyn Foo) {}
-   |                              ^^^^^^^^
-   |                              |
-   |                              types differ in mutability
-   |                              help: change the parameter type to match the trait: `&mut dyn Foo`
+   |                              ^^^^^^^^ types differ in mutability
    |
 note: type in trait
   --> $DIR/issue-13033.rs:2:30
@@ -14,6 +11,10 @@ LL |     fn bar(&mut self, other: &mut dyn Foo);
    |                              ^^^^^^^^^^^^
    = note: expected signature `fn(&mut Baz, &mut dyn Foo)`
               found signature `fn(&mut Baz, &dyn Foo)`
+help: change the parameter type to match the trait
+   |
+LL |     fn bar(&mut self, other: &mut dyn Foo) {}
+   |                              ~~~~~~~~~~~~
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/mismatched_types/trait-impl-fn-incompatibility.stderr b/tests/ui/mismatched_types/trait-impl-fn-incompatibility.stderr
index 6e7bf5eb46d..2e544a62223 100644
--- a/tests/ui/mismatched_types/trait-impl-fn-incompatibility.stderr
+++ b/tests/ui/mismatched_types/trait-impl-fn-incompatibility.stderr
@@ -2,10 +2,7 @@ error[E0053]: method `foo` has an incompatible type for trait
   --> $DIR/trait-impl-fn-incompatibility.rs:9:15
    |
 LL |     fn foo(x: i16) { }
-   |               ^^^
-   |               |
-   |               expected `u16`, found `i16`
-   |               help: change the parameter type to match the trait: `u16`
+   |               ^^^ expected `u16`, found `i16`
    |
 note: type in trait
   --> $DIR/trait-impl-fn-incompatibility.rs:2:15
@@ -14,15 +11,16 @@ LL |     fn foo(x: u16);
    |               ^^^
    = note: expected signature `fn(u16)`
               found signature `fn(i16)`
+help: change the parameter type to match the trait
+   |
+LL |     fn foo(x: u16) { }
+   |               ~~~
 
 error[E0053]: method `bar` has an incompatible type for trait
   --> $DIR/trait-impl-fn-incompatibility.rs:10:28
    |
 LL |     fn bar(&mut self, bar: &Bar) { }
-   |                            ^^^^
-   |                            |
-   |                            types differ in mutability
-   |                            help: change the parameter type to match the trait: `&mut Bar`
+   |                            ^^^^ types differ in mutability
    |
 note: type in trait
   --> $DIR/trait-impl-fn-incompatibility.rs:3:28
@@ -31,6 +29,10 @@ LL |     fn bar(&mut self, bar: &mut Bar);
    |                            ^^^^^^^^
    = note: expected signature `fn(&mut Bar, &mut Bar)`
               found signature `fn(&mut Bar, &Bar)`
+help: change the parameter type to match the trait
+   |
+LL |     fn bar(&mut self, bar: &mut Bar) { }
+   |                            ~~~~~~~~
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/range/issue-54505-no-std.stderr b/tests/ui/range/issue-54505-no-std.stderr
index 1694d514f42..f15a0ae6138 100644
--- a/tests/ui/range/issue-54505-no-std.stderr
+++ b/tests/ui/range/issue-54505-no-std.stderr
@@ -7,7 +7,7 @@ LL |     take_range(0..1);
    |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
-                 found struct `Range<{integer}>`
+                 found struct `core::ops::Range<{integer}>`
 note: function defined here
   --> $DIR/issue-54505-no-std.rs:25:4
    |
@@ -27,7 +27,7 @@ LL |     take_range(1..);
    |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
-                 found struct `RangeFrom<{integer}>`
+                 found struct `core::ops::RangeFrom<{integer}>`
 note: function defined here
   --> $DIR/issue-54505-no-std.rs:25:4
    |
@@ -67,7 +67,7 @@ LL |     take_range(0..=1);
    |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
-                 found struct `RangeInclusive<{integer}>`
+                 found struct `core::ops::RangeInclusive<{integer}>`
 note: function defined here
   --> $DIR/issue-54505-no-std.rs:25:4
    |
diff --git a/tests/ui/resolve/resolve-primitive-fallback.stderr b/tests/ui/resolve/resolve-primitive-fallback.stderr
index e3a5d4edcf1..d0583966459 100644
--- a/tests/ui/resolve/resolve-primitive-fallback.stderr
+++ b/tests/ui/resolve/resolve-primitive-fallback.stderr
@@ -24,13 +24,15 @@ error[E0061]: this function takes 0 arguments but 1 argument was supplied
   --> $DIR/resolve-primitive-fallback.rs:3:5
    |
 LL |     std::mem::size_of(u16);
-   |     ^^^^^^^^^^^^^^^^^ ---
-   |                       |
-   |                       unexpected argument
-   |                       help: remove the extra argument
+   |     ^^^^^^^^^^^^^^^^^ --- unexpected argument
    |
 note: function defined here
   --> $SRC_DIR/core/src/mem/mod.rs:LL:COL
+help: remove the extra argument
+   |
+LL -     std::mem::size_of(u16);
+LL +     std::mem::size_of();
+   |
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/span/issue-34264.stderr b/tests/ui/span/issue-34264.stderr
index f0dea66f612..89c67719b5a 100644
--- a/tests/ui/span/issue-34264.stderr
+++ b/tests/ui/span/issue-34264.stderr
@@ -54,16 +54,18 @@ error[E0061]: this function takes 2 arguments but 3 arguments were supplied
   --> $DIR/issue-34264.rs:7:5
    |
 LL |     foo(Some(42), 2, "");
-   |     ^^^            ----
-   |                    | |
-   |                    | unexpected argument of type `&'static str`
-   |                    help: remove the extra argument
+   |     ^^^              -- unexpected argument of type `&'static str`
    |
 note: function defined here
   --> $DIR/issue-34264.rs:1:4
    |
 LL | fn foo(Option<i32>, String) {}
    |    ^^^ -----------  ------
+help: remove the extra argument
+   |
+LL -     foo(Some(42), 2, "");
+LL +     foo(Some(42), 2);
+   |
 
 error[E0308]: mismatched types
   --> $DIR/issue-34264.rs:8:13
@@ -83,16 +85,18 @@ error[E0061]: this function takes 2 arguments but 3 arguments were supplied
   --> $DIR/issue-34264.rs:10:5
    |
 LL |     bar(1, 2, 3);
-   |     ^^^     ---
-   |             | |
-   |             | unexpected argument of type `{integer}`
-   |             help: remove the extra argument
+   |     ^^^       - unexpected argument of type `{integer}`
    |
 note: function defined here
   --> $DIR/issue-34264.rs:3:4
    |
 LL | fn bar(x, y: usize) {}
    |    ^^^ -  --------
+help: remove the extra argument
+   |
+LL -     bar(1, 2, 3);
+LL +     bar(1, 2);
+   |
 
 error: aborting due to 6 previous errors
 
diff --git a/tests/ui/traits/issue-35869.stderr b/tests/ui/traits/issue-35869.stderr
index 6d985bdeaf8..503f9cee246 100644
--- a/tests/ui/traits/issue-35869.stderr
+++ b/tests/ui/traits/issue-35869.stderr
@@ -2,10 +2,7 @@ error[E0053]: method `foo` has an incompatible type for trait
   --> $DIR/issue-35869.rs:11:15
    |
 LL |     fn foo(_: fn(u16) -> ()) {}
-   |               ^^^^^^^^^^^^^
-   |               |
-   |               expected `u8`, found `u16`
-   |               help: change the parameter type to match the trait: `fn(u8)`
+   |               ^^^^^^^^^^^^^ expected `u8`, found `u16`
    |
 note: type in trait
   --> $DIR/issue-35869.rs:2:15
@@ -14,15 +11,16 @@ LL |     fn foo(_: fn(u8) -> ());
    |               ^^^^^^^^^^^^
    = note: expected signature `fn(fn(u8))`
               found signature `fn(fn(u16))`
+help: change the parameter type to match the trait
+   |
+LL |     fn foo(_: fn(u8)) {}
+   |               ~~~~~~
 
 error[E0053]: method `bar` has an incompatible type for trait
   --> $DIR/issue-35869.rs:13:15
    |
 LL |     fn bar(_: Option<u16>) {}
-   |               ^^^^^^^^^^^
-   |               |
-   |               expected `u8`, found `u16`
-   |               help: change the parameter type to match the trait: `Option<u8>`
+   |               ^^^^^^^^^^^ expected `u8`, found `u16`
    |
 note: type in trait
   --> $DIR/issue-35869.rs:3:15
@@ -31,15 +29,16 @@ LL |     fn bar(_: Option<u8>);
    |               ^^^^^^^^^^
    = note: expected signature `fn(Option<u8>)`
               found signature `fn(Option<u16>)`
+help: change the parameter type to match the trait
+   |
+LL |     fn bar(_: Option<u8>) {}
+   |               ~~~~~~~~~~
 
 error[E0053]: method `baz` has an incompatible type for trait
   --> $DIR/issue-35869.rs:15:15
    |
 LL |     fn baz(_: (u16, u16)) {}
-   |               ^^^^^^^^^^
-   |               |
-   |               expected `u8`, found `u16`
-   |               help: change the parameter type to match the trait: `(u8, u16)`
+   |               ^^^^^^^^^^ expected `u8`, found `u16`
    |
 note: type in trait
   --> $DIR/issue-35869.rs:4:15
@@ -48,15 +47,16 @@ LL |     fn baz(_: (u8, u16));
    |               ^^^^^^^^^
    = note: expected signature `fn((u8, _))`
               found signature `fn((u16, _))`
+help: change the parameter type to match the trait
+   |
+LL |     fn baz(_: (u8, u16)) {}
+   |               ~~~~~~~~~
 
 error[E0053]: method `qux` has an incompatible type for trait
   --> $DIR/issue-35869.rs:17:17
    |
 LL |     fn qux() -> u16 { 5u16 }
-   |                 ^^^
-   |                 |
-   |                 expected `u8`, found `u16`
-   |                 help: change the output type to match the trait: `u8`
+   |                 ^^^ expected `u8`, found `u16`
    |
 note: type in trait
   --> $DIR/issue-35869.rs:5:17
@@ -65,6 +65,10 @@ LL |     fn qux() -> u8;
    |                 ^^
    = note: expected signature `fn() -> u8`
               found signature `fn() -> u16`
+help: change the output type to match the trait
+   |
+LL |     fn qux() -> u8 { 5u16 }
+   |                 ~~
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/traits/wrong-mul-method-signature.stderr b/tests/ui/traits/wrong-mul-method-signature.stderr
index 91162cbc123..e30b61622ae 100644
--- a/tests/ui/traits/wrong-mul-method-signature.stderr
+++ b/tests/ui/traits/wrong-mul-method-signature.stderr
@@ -2,37 +2,40 @@ error[E0053]: method `mul` has an incompatible type for trait
   --> $DIR/wrong-mul-method-signature.rs:16:21
    |
 LL |     fn mul(self, s: &f64) -> Vec1 {
-   |                     ^^^^
-   |                     |
-   |                     expected `f64`, found `&f64`
-   |                     help: change the parameter type to match the trait: `f64`
+   |                     ^^^^ expected `f64`, found `&f64`
    |
    = note: expected signature `fn(Vec1, _) -> Vec1`
               found signature `fn(Vec1, &_) -> Vec1`
+help: change the parameter type to match the trait
+   |
+LL |     fn mul(self, s: f64) -> Vec1 {
+   |                     ~~~
 
 error[E0053]: method `mul` has an incompatible type for trait
   --> $DIR/wrong-mul-method-signature.rs:33:21
    |
 LL |     fn mul(self, s: f64) -> Vec2 {
-   |                     ^^^
-   |                     |
-   |                     expected `Vec2`, found `f64`
-   |                     help: change the parameter type to match the trait: `Vec2`
+   |                     ^^^ expected `Vec2`, found `f64`
    |
    = note: expected signature `fn(Vec2, Vec2) -> f64`
               found signature `fn(Vec2, f64) -> Vec2`
+help: change the parameter type to match the trait
+   |
+LL |     fn mul(self, s: Vec2) -> Vec2 {
+   |                     ~~~~
 
 error[E0053]: method `mul` has an incompatible type for trait
   --> $DIR/wrong-mul-method-signature.rs:52:29
    |
 LL |     fn mul(self, s: f64) -> f64 {
-   |                             ^^^
-   |                             |
-   |                             expected `i32`, found `f64`
-   |                             help: change the output type to match the trait: `i32`
+   |                             ^^^ expected `i32`, found `f64`
    |
    = note: expected signature `fn(Vec3, _) -> i32`
               found signature `fn(Vec3, _) -> f64`
+help: change the output type to match the trait
+   |
+LL |     fn mul(self, s: f64) -> i32 {
+   |                             ~~~
 
 error[E0308]: mismatched types
   --> $DIR/wrong-mul-method-signature.rs:63:45
diff --git a/tests/ui/tuple/wrong_argument_ice-4.stderr b/tests/ui/tuple/wrong_argument_ice-4.stderr
index 3c7d6699be2..10191faf7bf 100644
--- a/tests/ui/tuple/wrong_argument_ice-4.stderr
+++ b/tests/ui/tuple/wrong_argument_ice-4.stderr
@@ -6,16 +6,21 @@ LL |       (|| {})(|| {
 LL | |
 LL | |         let b = 1;
 LL | |     });
-   | |     -
-   | |     |
-   | |_____unexpected argument of type `{closure@$DIR/wrong_argument_ice-4.rs:2:13: 2:15}`
-   |       help: remove the extra argument
+   | |_____- unexpected argument of type `{closure@$DIR/wrong_argument_ice-4.rs:2:13: 2:15}`
    |
 note: closure defined here
   --> $DIR/wrong_argument_ice-4.rs:2:6
    |
 LL |     (|| {})(|| {
    |      ^^
+help: remove the extra argument
+   |
+LL -     (|| {})(|| {
+LL -
+LL -         let b = 1;
+LL -     });
+LL +     (|| {})();
+   |
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/type-alias-impl-trait/unnameable_type.stderr b/tests/ui/type-alias-impl-trait/unnameable_type.stderr
index f567b01d29a..5b331c5660d 100644
--- a/tests/ui/type-alias-impl-trait/unnameable_type.stderr
+++ b/tests/ui/type-alias-impl-trait/unnameable_type.stderr
@@ -5,10 +5,7 @@ LL | type MyPrivate = impl Sized;
    |                  ---------- the found opaque type
 LL | impl Trait for u32 {
 LL |     fn dont_define_this(private: MyPrivate) {
-   |                                  ^^^^^^^^^
-   |                                  |
-   |                                  expected `Private`, found opaque type
-   |                                  help: change the parameter type to match the trait: `Private`
+   |                                  ^^^^^^^^^ expected `Private`, found opaque type
    |
 note: type in trait
   --> $DIR/unnameable_type.rs:10:39
@@ -17,6 +14,10 @@ LL |         fn dont_define_this(_private: Private) {}
    |                                       ^^^^^^^
    = note: expected signature `fn(Private)`
               found signature `fn(MyPrivate)`
+help: change the parameter type to match the trait
+   |
+LL |     fn dont_define_this(private: Private) {
+   |                                  ~~~~~~~
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/type/type-ascription-instead-of-initializer.stderr b/tests/ui/type/type-ascription-instead-of-initializer.stderr
index efa917334bf..224ff6e7404 100644
--- a/tests/ui/type/type-ascription-instead-of-initializer.stderr
+++ b/tests/ui/type/type-ascription-instead-of-initializer.stderr
@@ -11,13 +11,15 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied
   --> $DIR/type-ascription-instead-of-initializer.rs:2:12
    |
 LL |     let x: Vec::with_capacity(10, 20);
-   |            ^^^^^^^^^^^^^^^^^^   ----
-   |                                 | |
-   |                                 | unexpected argument of type `{integer}`
-   |                                 help: remove the extra argument
+   |            ^^^^^^^^^^^^^^^^^^     -- unexpected argument of type `{integer}`
    |
 note: associated function defined here
   --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
+help: remove the extra argument
+   |
+LL -     let x: Vec::with_capacity(10, 20);
+LL +     let x: Vec::with_capacity(10);
+   |
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/typeck/mismatched-map-under-self.stderr b/tests/ui/typeck/mismatched-map-under-self.stderr
index 322bf349f92..59de00a58bb 100644
--- a/tests/ui/typeck/mismatched-map-under-self.stderr
+++ b/tests/ui/typeck/mismatched-map-under-self.stderr
@@ -2,10 +2,7 @@ error[E0053]: method `values` has an incompatible type for trait
   --> $DIR/mismatched-map-under-self.rs:10:15
    |
 LL |     fn values(self) -> Self::Values {
-   |               ^^^^
-   |               |
-   |               expected `&Option<T>`, found `Option<T>`
-   |               help: change the self-receiver type to match the trait: `&self`
+   |               ^^^^ expected `&Option<T>`, found `Option<T>`
    |
 note: type in trait
   --> $DIR/mismatched-map-under-self.rs:4:15
@@ -14,6 +11,10 @@ LL |     fn values(&self) -> Self::Values;
    |               ^^^^^
    = note: expected signature `fn(&Option<_>)`
               found signature `fn(Option<_>)`
+help: change the self-receiver type to match the trait
+   |
+LL |     fn values(&self) -> Self::Values {
+   |               ~~~~~
 
 error[E0631]: type mismatch in function arguments
   --> $DIR/mismatched-map-under-self.rs:12:18
diff --git a/tests/ui/typeck/remove-extra-argument.stderr b/tests/ui/typeck/remove-extra-argument.stderr
index 9557c41457d..4bab2959651 100644
--- a/tests/ui/typeck/remove-extra-argument.stderr
+++ b/tests/ui/typeck/remove-extra-argument.stderr
@@ -2,16 +2,18 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied
   --> $DIR/remove-extra-argument.rs:6:5
    |
 LL |     l(vec![], vec![])
-   |     ^       --------
-   |             | |
-   |             | unexpected argument of type `Vec<_>`
-   |             help: remove the extra argument
+   |     ^         ------ unexpected argument of type `Vec<_>`
    |
 note: function defined here
   --> $DIR/remove-extra-argument.rs:3:4
    |
 LL | fn l(_a: Vec<u8>) {}
    |    ^ -----------
+help: remove the extra argument
+   |
+LL -     l(vec![], vec![])
+LL +     l(vec![])
+   |
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/typeck/struct-enum-wrong-args.stderr b/tests/ui/typeck/struct-enum-wrong-args.stderr
index 57cbd1d2005..d005eca841e 100644
--- a/tests/ui/typeck/struct-enum-wrong-args.stderr
+++ b/tests/ui/typeck/struct-enum-wrong-args.stderr
@@ -2,13 +2,15 @@ error[E0061]: this enum variant takes 1 argument but 2 arguments were supplied
   --> $DIR/struct-enum-wrong-args.rs:6:13
    |
 LL |     let _ = Some(3, 2);
-   |             ^^^^  ---
-   |                   | |
-   |                   | unexpected argument of type `{integer}`
-   |                   help: remove the extra argument
+   |             ^^^^    - unexpected argument of type `{integer}`
    |
 note: tuple variant defined here
   --> $SRC_DIR/core/src/option.rs:LL:COL
+help: remove the extra argument
+   |
+LL -     let _ = Some(3, 2);
+LL +     let _ = Some(3);
+   |
 
 error[E0061]: this enum variant takes 1 argument but 3 arguments were supplied
   --> $DIR/struct-enum-wrong-args.rs:7:13
@@ -59,16 +61,18 @@ error[E0061]: this struct takes 1 argument but 2 arguments were supplied
   --> $DIR/struct-enum-wrong-args.rs:10:13
    |
 LL |     let _ = Wrapper(5, 2);
-   |             ^^^^^^^  ---
-   |                      | |
-   |                      | unexpected argument of type `{integer}`
-   |                      help: remove the extra argument
+   |             ^^^^^^^    - unexpected argument of type `{integer}`
    |
 note: tuple struct defined here
   --> $DIR/struct-enum-wrong-args.rs:2:8
    |
 LL | struct Wrapper(i32);
    |        ^^^^^^^
+help: remove the extra argument
+   |
+LL -     let _ = Wrapper(5, 2);
+LL +     let _ = Wrapper(5);
+   |
 
 error[E0061]: this struct takes 2 arguments but 0 arguments were supplied
   --> $DIR/struct-enum-wrong-args.rs:11:13
@@ -106,16 +110,18 @@ error[E0061]: this struct takes 2 arguments but 3 arguments were supplied
   --> $DIR/struct-enum-wrong-args.rs:13:13
    |
 LL |     let _ = DoubleWrapper(5, 2, 7);
-   |             ^^^^^^^^^^^^^     ---
-   |                               | |
-   |                               | unexpected argument of type `{integer}`
-   |                               help: remove the extra argument
+   |             ^^^^^^^^^^^^^       - unexpected argument of type `{integer}`
    |
 note: tuple struct defined here
   --> $DIR/struct-enum-wrong-args.rs:3:8
    |
 LL | struct DoubleWrapper(i32, i32);
    |        ^^^^^^^^^^^^^
+help: remove the extra argument
+   |
+LL -     let _ = DoubleWrapper(5, 2, 7);
+LL +     let _ = DoubleWrapper(5, 2);
+   |
 
 error: aborting due to 8 previous errors
 
diff --git a/tests/ui/ufcs/ufcs-explicit-self-bad.stderr b/tests/ui/ufcs/ufcs-explicit-self-bad.stderr
index c48d094daea..2a8c4edbdb5 100644
--- a/tests/ui/ufcs/ufcs-explicit-self-bad.stderr
+++ b/tests/ui/ufcs/ufcs-explicit-self-bad.stderr
@@ -2,10 +2,7 @@ error[E0053]: method `dummy2` has an incompatible type for trait
   --> $DIR/ufcs-explicit-self-bad.rs:37:21
    |
 LL |     fn dummy2(self: &Bar<T>) {}
-   |               ------^^^^^^^
-   |               |     |
-   |               |     expected `&'a Bar<T>`, found `Bar<T>`
-   |               help: change the self-receiver type to match the trait: `&self`
+   |                     ^^^^^^^ expected `&'a Bar<T>`, found `Bar<T>`
    |
 note: type in trait
   --> $DIR/ufcs-explicit-self-bad.rs:31:15
@@ -14,6 +11,10 @@ LL |     fn dummy2(&self);
    |               ^^^^^
    = note: expected signature `fn(&&'a Bar<_>)`
               found signature `fn(&Bar<_>)`
+help: change the self-receiver type to match the trait
+   |
+LL |     fn dummy2(&self) {}
+   |               ~~~~~
 
 error[E0307]: invalid `self` parameter type: `isize`
   --> $DIR/ufcs-explicit-self-bad.rs:8:18