about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-08-10 15:13:38 +0000
committerbors <bors@rust-lang.org>2024-08-10 15:13:38 +0000
commit04ba50e8233042f810206c2cd18aace50961e247 (patch)
treeda45e06668255291d2c89c1bc30a84247e75c0fc
parent8291d68d926cedcdc77973e4c68f0828156d5bd8 (diff)
parent893b9f3a5ad65e568556bb539be475640ddbf501 (diff)
downloadrust-04ba50e8233042f810206c2cd18aace50961e247.tar.gz
rust-04ba50e8233042f810206c2cd18aace50961e247.zip
Auto merge of #128927 - GuillaumeGomez:rollup-ei2lr0f, r=GuillaumeGomez
Rollup of 8 pull requests

Successful merges:

 - #128273 (Improve `Ord` violation help)
 - #128807 (run-make: explaing why fmt-write-bloat is ignore-windows)
 - #128903 (rustdoc-json-types `Discriminant`: fix typo)
 - #128905 (gitignore: Add Zed and Helix editors)
 - #128908 (diagnostics: do not warn when a lifetime bound infers itself)
 - #128909 (Fix dump-ice-to-disk for RUSTC_ICE=0 users)
 - #128910 (Differentiate between methods and associated functions in diagnostics)
 - #128923 ([rustdoc] Stop showing impl items for negative impls)

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--.gitignore2
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_impl_item.rs14
-rw-r--r--compiler/rustc_lint/src/builtin.rs21
-rw-r--r--compiler/rustc_middle/src/hir/map/mod.rs18
-rw-r--r--compiler/rustc_middle/src/ty/assoc.rs9
-rw-r--r--library/alloc/src/slice.rs96
-rw-r--r--library/core/src/slice/mod.rs98
-rw-r--r--library/core/src/slice/sort/shared/smallsort.rs22
-rw-r--r--library/core/src/slice/sort/unstable/mod.rs2
-rw-r--r--src/librustdoc/clean/types.rs4
-rw-r--r--src/librustdoc/html/format.rs5
-rw-r--r--src/librustdoc/html/render/mod.rs37
-rw-r--r--src/rustdoc-json-types/lib.rs2
-rw-r--r--tests/run-make/dump-ice-to-disk/rmake.rs2
-rw-r--r--tests/run-make/fmt-write-bloat/main.rs2
-rw-r--r--tests/run-make/fmt-write-bloat/rmake.rs7
-rw-r--r--tests/rustdoc/negative-impl-no-items.rs26
-rw-r--r--tests/ui/async-await/in-trait/generics-mismatch.rs2
-rw-r--r--tests/ui/async-await/in-trait/generics-mismatch.stderr2
-rw-r--r--tests/ui/const-generics/defaults/mismatched_ty_const_in_trait_impl.rs10
-rw-r--r--tests/ui/const-generics/defaults/mismatched_ty_const_in_trait_impl.stderr10
-rw-r--r--tests/ui/delegation/not-supported.rs2
-rw-r--r--tests/ui/delegation/not-supported.stderr6
-rw-r--r--tests/ui/error-codes/E0049.stderr4
-rw-r--r--tests/ui/error-codes/E0195.rs4
-rw-r--r--tests/ui/error-codes/E0195.stderr6
-rw-r--r--tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.rs2
-rw-r--r--tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.stderr2
-rw-r--r--tests/ui/impl-trait/in-trait/trait-more-generics-than-impl.rs2
-rw-r--r--tests/ui/impl-trait/in-trait/trait-more-generics-than-impl.stderr2
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.precise.stderr4
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.stock.stderr4
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.stderr6
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-const-specialized.stderr4
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/default-keyword.stderr2
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.stderr8
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.stderr8
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.stderr4
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness-2.stderr4
-rw-r--r--tests/ui/rust-2018/edition-lint-inter-outlives/auxiliary/edition-lint-infer-outlives-macro.rs (renamed from tests/ui/rust-2018/auxiliary/edition-lint-infer-outlives-macro.rs)0
-rw-r--r--tests/ui/rust-2018/edition-lint-inter-outlives/edition-lint-infer-outlives-macro.fixed (renamed from tests/ui/rust-2018/edition-lint-infer-outlives-macro.fixed)0
-rw-r--r--tests/ui/rust-2018/edition-lint-inter-outlives/edition-lint-infer-outlives-macro.rs (renamed from tests/ui/rust-2018/edition-lint-infer-outlives-macro.rs)0
-rw-r--r--tests/ui/rust-2018/edition-lint-inter-outlives/edition-lint-infer-outlives-macro.stderr (renamed from tests/ui/rust-2018/edition-lint-infer-outlives-macro.stderr)0
-rw-r--r--tests/ui/rust-2018/edition-lint-inter-outlives/edition-lint-infer-outlives-multispan.rs (renamed from tests/ui/rust-2018/edition-lint-infer-outlives-multispan.rs)0
-rw-r--r--tests/ui/rust-2018/edition-lint-inter-outlives/edition-lint-infer-outlives-multispan.stderr (renamed from tests/ui/rust-2018/edition-lint-infer-outlives-multispan.stderr)0
-rw-r--r--tests/ui/rust-2018/edition-lint-inter-outlives/edition-lint-infer-outlives.fixed (renamed from tests/ui/rust-2018/edition-lint-infer-outlives.fixed)0
-rw-r--r--tests/ui/rust-2018/edition-lint-inter-outlives/edition-lint-infer-outlives.rs (renamed from tests/ui/rust-2018/edition-lint-infer-outlives.rs)0
-rw-r--r--tests/ui/rust-2018/edition-lint-inter-outlives/edition-lint-infer-outlives.stderr (renamed from tests/ui/rust-2018/edition-lint-infer-outlives.stderr)0
-rw-r--r--tests/ui/rust-2018/edition-lint-inter-outlives/explicit-outlives-recursive-119228.fixed41
-rw-r--r--tests/ui/rust-2018/edition-lint-inter-outlives/explicit-outlives-recursive-119228.rs41
-rw-r--r--tests/ui/specialization/const_trait_impl.stderr10
-rw-r--r--tests/ui/typeck/issue-36708.stderr2
52 files changed, 368 insertions, 191 deletions
diff --git a/.gitignore b/.gitignore
index f2cdd8762f2..a36cb51de33 100644
--- a/.gitignore
+++ b/.gitignore
@@ -20,6 +20,8 @@ Session.vim
 .vscode
 .project
 .vim/
+.helix/
+.zed/
 .favorites.json
 .settings/
 .vs/
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 53cde14f337..35577613800 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
@@ -1117,7 +1117,7 @@ fn check_region_bounds_on_impl_item<'tcx>(
             .dcx()
             .create_err(LifetimesOrBoundsMismatchOnTrait {
                 span,
-                item_kind: assoc_item_kind_str(&impl_m),
+                item_kind: impl_m.descr(),
                 ident: impl_m.ident(tcx),
                 generics_span,
                 bounds_span,
@@ -1294,7 +1294,7 @@ fn compare_number_of_generics<'tcx>(
         ("const", trait_own_counts.consts, impl_own_counts.consts),
     ];
 
-    let item_kind = assoc_item_kind_str(&impl_);
+    let item_kind = impl_.descr();
 
     let mut err_occurred = None;
     for (kind, trait_count, impl_count) in matchings {
@@ -1676,7 +1676,7 @@ fn compare_generic_param_kinds<'tcx>(
                 param_impl_span,
                 E0053,
                 "{} `{}` has an incompatible generic parameter for trait `{}`",
-                assoc_item_kind_str(&impl_item),
+                impl_item.descr(),
                 trait_item.name,
                 &tcx.def_path_str(tcx.parent(trait_item.def_id))
             );
@@ -2249,14 +2249,6 @@ fn param_env_with_gat_bounds<'tcx>(
     ty::ParamEnv::new(tcx.mk_clauses(&predicates), Reveal::UserFacing)
 }
 
-fn assoc_item_kind_str(impl_item: &ty::AssocItem) -> &'static str {
-    match impl_item.kind {
-        ty::AssocKind::Const => "const",
-        ty::AssocKind::Fn => "method",
-        ty::AssocKind::Type => "type",
-    }
-}
-
 /// Manually check here that `async fn foo()` wasn't matched against `fn foo()`,
 /// and extract a better error if so.
 fn try_report_async_mismatch<'tcx>(
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index d8674817cb5..6b36944b208 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -1924,14 +1924,13 @@ declare_lint_pass!(ExplicitOutlivesRequirements => [EXPLICIT_OUTLIVES_REQUIREMEN
 impl ExplicitOutlivesRequirements {
     fn lifetimes_outliving_lifetime<'tcx>(
         tcx: TyCtxt<'tcx>,
-        inferred_outlives: &'tcx [(ty::Clause<'tcx>, Span)],
+        inferred_outlives: impl Iterator<Item = &'tcx (ty::Clause<'tcx>, Span)>,
         item: DefId,
         lifetime: DefId,
     ) -> Vec<ty::Region<'tcx>> {
         let item_generics = tcx.generics_of(item);
 
         inferred_outlives
-            .iter()
             .filter_map(|(clause, _)| match clause.kind().skip_binder() {
                 ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(a, b)) => match *a {
                     ty::ReEarlyParam(ebr)
@@ -1947,11 +1946,10 @@ impl ExplicitOutlivesRequirements {
     }
 
     fn lifetimes_outliving_type<'tcx>(
-        inferred_outlives: &'tcx [(ty::Clause<'tcx>, Span)],
+        inferred_outlives: impl Iterator<Item = &'tcx (ty::Clause<'tcx>, Span)>,
         index: u32,
     ) -> Vec<ty::Region<'tcx>> {
         inferred_outlives
-            .iter()
             .filter_map(|(clause, _)| match clause.kind().skip_binder() {
                 ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(a, b)) => {
                     a.is_param(index).then_some(b)
@@ -2094,7 +2092,11 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements {
                                 (
                                     Self::lifetimes_outliving_lifetime(
                                         cx.tcx,
-                                        inferred_outlives,
+                                        // don't warn if the inferred span actually came from the predicate we're looking at
+                                        // this happens if the type is recursively defined
+                                        inferred_outlives
+                                            .iter()
+                                            .filter(|(_, span)| !predicate.span.contains(*span)),
                                         item.owner_id.to_def_id(),
                                         region_def_id,
                                     ),
@@ -2116,7 +2118,14 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements {
                                     };
                                     let index = ty_generics.param_def_id_to_index[&def_id];
                                     (
-                                        Self::lifetimes_outliving_type(inferred_outlives, index),
+                                        Self::lifetimes_outliving_type(
+                                            // don't warn if the inferred span actually came from the predicate we're looking at
+                                            // this happens if the type is recursively defined
+                                            inferred_outlives.iter().filter(|(_, span)| {
+                                                !predicate.span.contains(*span)
+                                            }),
+                                            index,
+                                        ),
                                         &predicate.bounds,
                                         predicate.span,
                                         predicate.origin == PredicateOrigin::WhereClause,
diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs
index 4c243e6330b..edab6b5ebde 100644
--- a/compiler/rustc_middle/src/hir/map/mod.rs
+++ b/compiler/rustc_middle/src/hir/map/mod.rs
@@ -1165,17 +1165,23 @@ fn hir_id_to_string(map: Map<'_>, id: HirId) -> String {
         }
         Node::ImplItem(ii) => {
             let kind = match ii.kind {
-                ImplItemKind::Const(..) => "assoc const",
-                ImplItemKind::Fn(..) => "method",
-                ImplItemKind::Type(_) => "assoc type",
+                ImplItemKind::Const(..) => "associated constant",
+                ImplItemKind::Fn(fn_sig, _) => match fn_sig.decl.implicit_self {
+                    ImplicitSelfKind::None => "associated function",
+                    _ => "method",
+                },
+                ImplItemKind::Type(_) => "associated type",
             };
             format!("{id} ({kind} `{}` in {})", ii.ident, path_str(ii.owner_id.def_id))
         }
         Node::TraitItem(ti) => {
             let kind = match ti.kind {
-                TraitItemKind::Const(..) => "assoc constant",
-                TraitItemKind::Fn(..) => "trait method",
-                TraitItemKind::Type(..) => "assoc type",
+                TraitItemKind::Const(..) => "associated constant",
+                TraitItemKind::Fn(fn_sig, _) => match fn_sig.decl.implicit_self {
+                    ImplicitSelfKind::None => "associated function",
+                    _ => "trait method",
+                },
+                TraitItemKind::Type(..) => "associated type",
             };
 
             format!("{id} ({kind} `{}` in {})", ti.ident, path_str(ti.owner_id.def_id))
diff --git a/compiler/rustc_middle/src/ty/assoc.rs b/compiler/rustc_middle/src/ty/assoc.rs
index 0ce5c613c4c..db56e0016a2 100644
--- a/compiler/rustc_middle/src/ty/assoc.rs
+++ b/compiler/rustc_middle/src/ty/assoc.rs
@@ -98,6 +98,15 @@ impl AssocItem {
         }
     }
 
+    pub fn descr(&self) -> &'static str {
+        match self.kind {
+            ty::AssocKind::Const => "const",
+            ty::AssocKind::Fn if self.fn_has_self_parameter => "method",
+            ty::AssocKind::Fn => "associated function",
+            ty::AssocKind::Type => "type",
+        }
+    }
+
     pub fn is_impl_trait_in_trait(&self) -> bool {
         self.opt_rpitit_info.is_some()
     }
diff --git a/library/alloc/src/slice.rs b/library/alloc/src/slice.rs
index 7dcf344cdc5..9d704870326 100644
--- a/library/alloc/src/slice.rs
+++ b/library/alloc/src/slice.rs
@@ -178,15 +178,25 @@ impl<T> [T] {
     /// This sort is stable (i.e., does not reorder equal elements) and *O*(*n* \* log(*n*))
     /// worst-case.
     ///
-    /// If `T: Ord` does not implement a total order the resulting order is unspecified. All
-    /// original elements will remain in the slice and any possible modifications via interior
-    /// mutability are observed in the input. Same is true if `T: Ord` panics.
+    /// If the implementation of [`Ord`] for `T` does not implement a [total order] the resulting
+    /// order of elements in the slice is unspecified. All original elements will remain in the
+    /// slice and any possible modifications via interior mutability are observed in the input. Same
+    /// is true if the implementation of [`Ord`] for `T` panics.
     ///
     /// When applicable, unstable sorting is preferred because it is generally faster than stable
     /// sorting and it doesn't allocate auxiliary memory. See
     /// [`sort_unstable`](slice::sort_unstable). The exception are partially sorted slices, which
     /// may be better served with `slice::sort`.
     ///
+    /// Sorting types that only implement [`PartialOrd`] such as [`f32`] and [`f64`] require
+    /// additional precautions. For example, `f32::NAN != f32::NAN`, which doesn't fulfill the
+    /// reflexivity requirement of [`Ord`]. By using an alternative comparison function with
+    /// `slice::sort_by` such as [`f32::total_cmp`] or [`f64::total_cmp`] that defines a [total
+    /// order] users can sort slices containing floating-point values. Alternatively, if all values
+    /// in the slice are guaranteed to be in a subset for which [`PartialOrd::partial_cmp`] forms a
+    /// [total order], it's possible to sort the slice with `sort_by(|a, b|
+    /// a.partial_cmp(b).unwrap())`.
+    ///
     /// # Current implementation
     ///
     /// The current implementation is based on [driftsort] by Orson Peters and Lukas Bergdoll, which
@@ -198,18 +208,21 @@ impl<T> [T] {
     /// handled without allocation, medium sized slices allocate `self.len()` and beyond that it
     /// clamps at `self.len() / 2`.
     ///
-    /// If `T: Ord` does not implement a total order, the implementation may panic.
+    /// # Panics
+    ///
+    /// May panic if the implementation of [`Ord`] for `T` does not implement a [total order].
     ///
     /// # Examples
     ///
     /// ```
-    /// let mut v = [-5, 4, 1, -3, 2];
+    /// let mut v = [4, -5, 1, -3, 2];
     ///
     /// v.sort();
-    /// assert!(v == [-5, -3, 1, 2, 4]);
+    /// assert_eq!(v, [-5, -3, 1, 2, 4]);
     /// ```
     ///
     /// [driftsort]: https://github.com/Voultapher/driftsort
+    /// [total order]: https://en.wikipedia.org/wiki/Total_order
     #[cfg(not(no_global_oom_handling))]
     #[rustc_allow_incoherent_impl]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -221,30 +234,19 @@ impl<T> [T] {
         stable_sort(self, T::lt);
     }
 
-    /// Sorts the slice with a comparator function, preserving initial order of equal elements.
+    /// Sorts the slice with a comparison function, preserving initial order of equal elements.
     ///
     /// This sort is stable (i.e., does not reorder equal elements) and *O*(*n* \* log(*n*))
     /// worst-case.
     ///
-    /// The comparator function should define a total ordering for the elements in the slice. If the
-    /// ordering is not total, the order of the elements is unspecified.
-    ///
-    /// If the comparator function does not implement a total order the resulting order is
-    /// unspecified. All original elements will remain in the slice and any possible modifications
-    /// via interior mutability are observed in the input. Same is true if the comparator function
-    /// panics. A total order (for all `a`, `b` and `c`):
+    /// If the comparison function `compare` does not implement a [total order] the resulting order
+    /// of elements in the slice is unspecified. All original elements will remain in the slice and
+    /// any possible modifications via interior mutability are observed in the input. Same is true
+    /// if `compare` panics.
     ///
-    /// * total and antisymmetric: exactly one of `a < b`, `a == b` or `a > b` is true, and
-    /// * transitive, `a < b` and `b < c` implies `a < c`. The same must hold for both `==` and `>`.
-    ///
-    /// For example, while [`f64`] doesn't implement [`Ord`] because `NaN != NaN`, we can use
-    /// `partial_cmp` as our sort function when we know the slice doesn't contain a `NaN`.
-    ///
-    /// ```
-    /// let mut floats = [5f64, 4.0, 1.0, 3.0, 2.0];
-    /// floats.sort_unstable_by(|a, b| a.partial_cmp(b).unwrap());
-    /// assert_eq!(floats, [1.0, 2.0, 3.0, 4.0, 5.0]);
-    /// ```
+    /// For example `|a, b| (a - b).cmp(a)` is a comparison function that is neither transitive nor
+    /// reflexive nor total, `a < b < c < a` with `a = 1, b = 2, c = 3`. For more information and
+    /// examples see the [`Ord`] documentation.
     ///
     /// # Current implementation
     ///
@@ -257,21 +259,24 @@ impl<T> [T] {
     /// handled without allocation, medium sized slices allocate `self.len()` and beyond that it
     /// clamps at `self.len() / 2`.
     ///
-    /// If `T: Ord` does not implement a total order, the implementation may panic.
+    /// # Panics
+    ///
+    /// May panic if `compare` does not implement a [total order].
     ///
     /// # Examples
     ///
     /// ```
-    /// let mut v = [5, 4, 1, 3, 2];
+    /// let mut v = [4, -5, 1, -3, 2];
     /// v.sort_by(|a, b| a.cmp(b));
-    /// assert!(v == [1, 2, 3, 4, 5]);
+    /// assert_eq!(v, [-5, -3, 1, 2, 4]);
     ///
     /// // reverse sorting
     /// v.sort_by(|a, b| b.cmp(a));
-    /// assert!(v == [5, 4, 3, 2, 1]);
+    /// assert_eq!(v, [4, 2, 1, -3, -5]);
     /// ```
     ///
     /// [driftsort]: https://github.com/Voultapher/driftsort
+    /// [total order]: https://en.wikipedia.org/wiki/Total_order
     #[cfg(not(no_global_oom_handling))]
     #[rustc_allow_incoherent_impl]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -288,9 +293,10 @@ impl<T> [T] {
     /// This sort is stable (i.e., does not reorder equal elements) and *O*(*m* \* *n* \* log(*n*))
     /// worst-case, where the key function is *O*(*m*).
     ///
-    /// If `K: Ord` does not implement a total order the resulting order is unspecified.
-    /// All original elements will remain in the slice and any possible modifications via interior
-    /// mutability are observed in the input. Same is true if `K: Ord` panics.
+    /// If the implementation of [`Ord`] for `K` does not implement a [total order] the resulting
+    /// order of elements in the slice is unspecified. All original elements will remain in the
+    /// slice and any possible modifications via interior mutability are observed in the input. Same
+    /// is true if the implementation of [`Ord`] for `K` panics.
     ///
     /// # Current implementation
     ///
@@ -303,18 +309,21 @@ impl<T> [T] {
     /// handled without allocation, medium sized slices allocate `self.len()` and beyond that it
     /// clamps at `self.len() / 2`.
     ///
-    /// If `K: Ord` does not implement a total order, the implementation may panic.
+    /// # Panics
+    ///
+    /// May panic if the implementation of [`Ord`] for `K` does not implement a [total order].
     ///
     /// # Examples
     ///
     /// ```
-    /// let mut v = [-5i32, 4, 1, -3, 2];
+    /// let mut v = [4i32, -5, 1, -3, 2];
     ///
     /// v.sort_by_key(|k| k.abs());
-    /// assert!(v == [1, 2, -3, 4, -5]);
+    /// assert_eq!(v, [1, 2, -3, 4, -5]);
     /// ```
     ///
     /// [driftsort]: https://github.com/Voultapher/driftsort
+    /// [total order]: https://en.wikipedia.org/wiki/Total_order
     #[cfg(not(no_global_oom_handling))]
     #[rustc_allow_incoherent_impl]
     #[stable(feature = "slice_sort_by_key", since = "1.7.0")]
@@ -336,9 +345,10 @@ impl<T> [T] {
     /// storage to remember the results of key evaluation. The order of calls to the key function is
     /// unspecified and may change in future versions of the standard library.
     ///
-    /// If `K: Ord` does not implement a total order the resulting order is unspecified.
-    /// All original elements will remain in the slice and any possible modifications via interior
-    /// mutability are observed in the input. Same is true if `K: Ord` panics.
+    /// If the implementation of [`Ord`] for `K` does not implement a [total order] the resulting
+    /// order of elements in the slice is unspecified. All original elements will remain in the
+    /// slice and any possible modifications via interior mutability are observed in the input. Same
+    /// is true if the implementation of [`Ord`] for `K` panics.
     ///
     /// For simple key functions (e.g., functions that are property accesses or basic operations),
     /// [`sort_by_key`](slice::sort_by_key) is likely to be faster.
@@ -355,16 +365,22 @@ impl<T> [T] {
     /// In the worst case, the algorithm allocates temporary storage in a `Vec<(K, usize)>` the
     /// length of the slice.
     ///
+    /// # Panics
+    ///
+    /// May panic if the implementation of [`Ord`] for `K` does not implement a [total order].
+    ///
     /// # Examples
     ///
     /// ```
-    /// let mut v = [-5i32, 4, 32, -3, 2];
+    /// let mut v = [4i32, -5, 1, -3, 2, 10];
     ///
+    /// // Strings are sorted by lexicographical order.
     /// v.sort_by_cached_key(|k| k.to_string());
-    /// assert!(v == [-3, -5, 2, 32, 4]);
+    /// assert_eq!(v, [-3, -5, 1, 10, 2, 4]);
     /// ```
     ///
     /// [ipnsort]: https://github.com/Voultapher/sort-research-rs/tree/main/ipnsort
+    /// [total order]: https://en.wikipedia.org/wiki/Total_order
     #[cfg(not(no_global_oom_handling))]
     #[rustc_allow_incoherent_impl]
     #[stable(feature = "slice_sort_by_cached_key", since = "1.34.0")]
diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs
index b1440214d79..c76157720b7 100644
--- a/library/core/src/slice/mod.rs
+++ b/library/core/src/slice/mod.rs
@@ -28,6 +28,7 @@ pub mod memchr;
     issue = "none",
     reason = "exposed from core to be reused in std;"
 )]
+#[doc(hidden)]
 pub mod sort;
 
 mod ascii;
@@ -2880,9 +2881,19 @@ impl<T> [T] {
     /// This sort is unstable (i.e., may reorder equal elements), in-place (i.e., does not
     /// allocate), and *O*(*n* \* log(*n*)) worst-case.
     ///
-    /// If `T: Ord` does not implement a total order the resulting order is unspecified. All
-    /// original elements will remain in the slice and any possible modifications via interior
-    /// mutability are observed in the input. Same is true if `T: Ord` panics.
+    /// If the implementation of [`Ord`] for `T` does not implement a [total order] the resulting
+    /// order of elements in the slice is unspecified. All original elements will remain in the
+    /// slice and any possible modifications via interior mutability are observed in the input. Same
+    /// is true if the implementation of [`Ord`] for `T` panics.
+    ///
+    /// Sorting types that only implement [`PartialOrd`] such as [`f32`] and [`f64`] require
+    /// additional precautions. For example, `f32::NAN != f32::NAN`, which doesn't fulfill the
+    /// reflexivity requirement of [`Ord`]. By using an alternative comparison function with
+    /// `slice::sort_unstable_by` such as [`f32::total_cmp`] or [`f64::total_cmp`] that defines a
+    /// [total order] users can sort slices containing floating-point values. Alternatively, if all
+    /// values in the slice are guaranteed to be in a subset for which [`PartialOrd::partial_cmp`]
+    /// forms a [total order], it's possible to sort the slice with `sort_unstable_by(|a, b|
+    /// a.partial_cmp(b).unwrap())`.
     ///
     /// # Current implementation
     ///
@@ -2894,18 +2905,21 @@ impl<T> [T] {
     /// It is typically faster than stable sorting, except in a few special cases, e.g., when the
     /// slice is partially sorted.
     ///
-    /// If `T: Ord` does not implement a total order, the implementation may panic.
+    /// # Panics
+    ///
+    /// May panic if the implementation of [`Ord`] for `T` does not implement a [total order].
     ///
     /// # Examples
     ///
     /// ```
-    /// let mut v = [-5, 4, 1, -3, 2];
+    /// let mut v = [4, -5, 1, -3, 2];
     ///
     /// v.sort_unstable();
-    /// assert!(v == [-5, -3, 1, 2, 4]);
+    /// assert_eq!(v, [-5, -3, 1, 2, 4]);
     /// ```
     ///
     /// [ipnsort]: https://github.com/Voultapher/sort-research-rs/tree/main/ipnsort
+    /// [total order]: https://en.wikipedia.org/wiki/Total_order
     #[stable(feature = "sort_unstable", since = "1.20.0")]
     #[inline]
     pub fn sort_unstable(&mut self)
@@ -2915,31 +2929,20 @@ impl<T> [T] {
         sort::unstable::sort(self, &mut T::lt);
     }
 
-    /// Sorts the slice with a comparator function, **without** preserving the initial order of
+    /// Sorts the slice with a comparison function, **without** preserving the initial order of
     /// equal elements.
     ///
     /// This sort is unstable (i.e., may reorder equal elements), in-place (i.e., does not
     /// allocate), and *O*(*n* \* log(*n*)) worst-case.
     ///
-    /// The comparator function should define a total ordering for the elements in the slice. If the
-    /// ordering is not total, the order of the elements is unspecified.
-    ///
-    /// If the comparator function does not implement a total order the resulting order is
-    /// unspecified. All original elements will remain in the slice and any possible modifications
-    /// via interior mutability are observed in the input. Same is true if the comparator function
-    /// panics. A total order (for all `a`, `b` and `c`):
-    ///
-    /// * total and antisymmetric: exactly one of `a < b`, `a == b` or `a > b` is true, and
-    /// * transitive, `a < b` and `b < c` implies `a < c`. The same must hold for both `==` and `>`.
+    /// If the comparison function `compare` does not implement a [total order] the resulting order
+    /// of elements in the slice is unspecified. All original elements will remain in the slice and
+    /// any possible modifications via interior mutability are observed in the input. Same is true
+    /// if `compare` panics.
     ///
-    /// For example, while [`f64`] doesn't implement [`Ord`] because `NaN != NaN`, we can use
-    /// `partial_cmp` as our sort function when we know the slice doesn't contain a `NaN`.
-    ///
-    /// ```
-    /// let mut floats = [5f64, 4.0, 1.0, 3.0, 2.0];
-    /// floats.sort_unstable_by(|a, b| a.partial_cmp(b).unwrap());
-    /// assert_eq!(floats, [1.0, 2.0, 3.0, 4.0, 5.0]);
-    /// ```
+    /// For example `|a, b| (a - b).cmp(a)` is a comparison function that is neither transitive nor
+    /// reflexive nor total, `a < b < c < a` with `a = 1, b = 2, c = 3`. For more information and
+    /// examples see the [`Ord`] documentation.
     ///
     /// # Current implementation
     ///
@@ -2951,21 +2954,24 @@ impl<T> [T] {
     /// It is typically faster than stable sorting, except in a few special cases, e.g., when the
     /// slice is partially sorted.
     ///
-    /// If `T: Ord` does not implement a total order, the implementation may panic.
+    /// # Panics
+    ///
+    /// May panic if `compare` does not implement a [total order].
     ///
     /// # Examples
     ///
     /// ```
-    /// let mut v = [5, 4, 1, 3, 2];
+    /// let mut v = [4, -5, 1, -3, 2];
     /// v.sort_unstable_by(|a, b| a.cmp(b));
-    /// assert!(v == [1, 2, 3, 4, 5]);
+    /// assert_eq!(v, [-5, -3, 1, 2, 4]);
     ///
     /// // reverse sorting
     /// v.sort_unstable_by(|a, b| b.cmp(a));
-    /// assert!(v == [5, 4, 3, 2, 1]);
+    /// assert_eq!(v, [4, 2, 1, -3, -5]);
     /// ```
     ///
     /// [ipnsort]: https://github.com/Voultapher/sort-research-rs/tree/main/ipnsort
+    /// [total order]: https://en.wikipedia.org/wiki/Total_order
     #[stable(feature = "sort_unstable", since = "1.20.0")]
     #[inline]
     pub fn sort_unstable_by<F>(&mut self, mut compare: F)
@@ -2981,9 +2987,10 @@ impl<T> [T] {
     /// This sort is unstable (i.e., may reorder equal elements), in-place (i.e., does not
     /// allocate), and *O*(*n* \* log(*n*)) worst-case.
     ///
-    /// If `K: Ord` does not implement a total order the resulting order is unspecified.
-    /// All original elements will remain in the slice and any possible modifications via interior
-    /// mutability are observed in the input. Same is true if `K: Ord` panics.
+    /// If the implementation of [`Ord`] for `K` does not implement a [total order] the resulting
+    /// order of elements in the slice is unspecified. All original elements will remain in the
+    /// slice and any possible modifications via interior mutability are observed in the input. Same
+    /// is true if the implementation of [`Ord`] for `K` panics.
     ///
     /// # Current implementation
     ///
@@ -2995,18 +3002,21 @@ impl<T> [T] {
     /// It is typically faster than stable sorting, except in a few special cases, e.g., when the
     /// slice is partially sorted.
     ///
-    /// If `K: Ord` does not implement a total order, the implementation may panic.
+    /// # Panics
+    ///
+    /// May panic if the implementation of [`Ord`] for `K` does not implement a [total order].
     ///
     /// # Examples
     ///
     /// ```
-    /// let mut v = [-5i32, 4, 1, -3, 2];
+    /// let mut v = [4i32, -5, 1, -3, 2];
     ///
     /// v.sort_unstable_by_key(|k| k.abs());
-    /// assert!(v == [1, 2, -3, 4, -5]);
+    /// assert_eq!(v, [1, 2, -3, 4, -5]);
     /// ```
     ///
     /// [ipnsort]: https://github.com/Voultapher/sort-research-rs/tree/main/ipnsort
+    /// [total order]: https://en.wikipedia.org/wiki/Total_order
     #[stable(feature = "sort_unstable", since = "1.20.0")]
     #[inline]
     pub fn sort_unstable_by_key<K, F>(&mut self, mut f: F)
@@ -3038,15 +3048,14 @@ impl<T> [T] {
     /// Median of Medians using Tukey's Ninther for pivot selection, which guarantees linear runtime
     /// for all inputs.
     ///
-    /// It is typically faster than stable sorting, except in a few special cases, e.g., when the
-    /// slice is nearly fully sorted, where `slice::sort` may be faster.
-    ///
     /// [`sort_unstable`]: slice::sort_unstable
     ///
     /// # Panics
     ///
     /// Panics when `index >= len()`, meaning it always panics on empty slices.
     ///
+    /// May panic if the implementation of [`Ord`] for `T` does not implement a [total order].
+    ///
     /// # Examples
     ///
     /// ```
@@ -3069,6 +3078,7 @@ impl<T> [T] {
     /// ```
     ///
     /// [ipnsort]: https://github.com/Voultapher/sort-research-rs/tree/main/ipnsort
+    /// [total order]: https://en.wikipedia.org/wiki/Total_order
     #[stable(feature = "slice_select_nth_unstable", since = "1.49.0")]
     #[inline]
     pub fn select_nth_unstable(&mut self, index: usize) -> (&mut [T], &mut T, &mut [T])
@@ -3099,15 +3109,14 @@ impl<T> [T] {
     /// Median of Medians using Tukey's Ninther for pivot selection, which guarantees linear runtime
     /// for all inputs.
     ///
-    /// It is typically faster than stable sorting, except in a few special cases, e.g., when the
-    /// slice is nearly fully sorted, where `slice::sort` may be faster.
-    ///
     /// [`sort_unstable`]: slice::sort_unstable
     ///
     /// # Panics
     ///
     /// Panics when `index >= len()`, meaning it always panics on empty slices.
     ///
+    /// May panic if `compare` does not implement a [total order].
+    ///
     /// # Examples
     ///
     /// ```
@@ -3130,6 +3139,7 @@ impl<T> [T] {
     /// ```
     ///
     /// [ipnsort]: https://github.com/Voultapher/sort-research-rs/tree/main/ipnsort
+    /// [total order]: https://en.wikipedia.org/wiki/Total_order
     #[stable(feature = "slice_select_nth_unstable", since = "1.49.0")]
     #[inline]
     pub fn select_nth_unstable_by<F>(
@@ -3164,15 +3174,14 @@ impl<T> [T] {
     /// Median of Medians using Tukey's Ninther for pivot selection, which guarantees linear runtime
     /// for all inputs.
     ///
-    /// It is typically faster than stable sorting, except in a few special cases, e.g., when the
-    /// slice is nearly fully sorted, where `slice::sort` may be faster.
-    ///
     /// [`sort_unstable`]: slice::sort_unstable
     ///
     /// # Panics
     ///
     /// Panics when `index >= len()`, meaning it always panics on empty slices.
     ///
+    /// May panic if `K: Ord` does not implement a total order.
+    ///
     /// # Examples
     ///
     /// ```
@@ -3195,6 +3204,7 @@ impl<T> [T] {
     /// ```
     ///
     /// [ipnsort]: https://github.com/Voultapher/sort-research-rs/tree/main/ipnsort
+    /// [total order]: https://en.wikipedia.org/wiki/Total_order
     #[stable(feature = "slice_select_nth_unstable", since = "1.49.0")]
     #[inline]
     pub fn select_nth_unstable_by_key<K, F>(
diff --git a/library/core/src/slice/sort/shared/smallsort.rs b/library/core/src/slice/sort/shared/smallsort.rs
index 5064c5a0ae5..db0c5c72822 100644
--- a/library/core/src/slice/sort/shared/smallsort.rs
+++ b/library/core/src/slice/sort/shared/smallsort.rs
@@ -831,9 +831,9 @@ unsafe fn bidirectional_merge<T: FreezeMarker, F: FnMut(&T, &T) -> bool>(
             right = right.add((!left_nonempty) as usize);
         }
 
-        // We now should have consumed the full input exactly once. This can
-        // only fail if the comparison operator fails to be Ord, in which case
-        // we will panic and never access the inconsistent state in dst.
+        // We now should have consumed the full input exactly once. This can only fail if the
+        // user-provided comparison function fails to implement a strict weak ordering. In that case
+        // we panic and never access the inconsistent state in dst.
         if left != left_end || right != right_end {
             panic_on_ord_violation();
         }
@@ -842,7 +842,21 @@ unsafe fn bidirectional_merge<T: FreezeMarker, F: FnMut(&T, &T) -> bool>(
 
 #[inline(never)]
 fn panic_on_ord_violation() -> ! {
-    panic!("Ord violation");
+    // This is indicative of a logic bug in the user-provided comparison function or Ord
+    // implementation. They are expected to implement a total order as explained in the Ord
+    // documentation.
+    //
+    // By panicking we inform the user, that they have a logic bug in their program. If a strict
+    // weak ordering is not given, the concept of comparison based sorting cannot yield a sorted
+    // result. E.g.: a < b < c < a
+    //
+    // The Ord documentation requires users to implement a total order. Arguably that's
+    // unnecessarily strict in the context of sorting. Issues only arise if the weaker requirement
+    // of a strict weak ordering is violated.
+    //
+    // The panic message talks about a total order because that's what the Ord documentation talks
+    // about and requires, so as to not confuse users.
+    panic!("user-provided comparison function does not correctly implement a total order");
 }
 
 #[must_use]
diff --git a/library/core/src/slice/sort/unstable/mod.rs b/library/core/src/slice/sort/unstable/mod.rs
index ed735e1ebfb..932e01f4401 100644
--- a/library/core/src/slice/sort/unstable/mod.rs
+++ b/library/core/src/slice/sort/unstable/mod.rs
@@ -8,7 +8,7 @@ use crate::slice::sort::shared::smallsort::insertion_sort_shift_left;
 pub(crate) mod heapsort;
 pub(crate) mod quicksort;
 
-/// Unstable sort called ipnsort by Lukas Bergdoll.
+/// Unstable sort called ipnsort by Lukas Bergdoll and Orson Peters.
 /// Design document:
 /// <https://github.com/Voultapher/sort-research-rs/blob/main/writeup/ipnsort_introduction/text.md>
 ///
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 4850500a1bf..ff5c16f2b3e 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -2446,6 +2446,10 @@ impl Impl {
             .map(|did| tcx.provided_trait_methods(did).map(|meth| meth.name).collect())
             .unwrap_or_default()
     }
+
+    pub(crate) fn is_negative_trait_impl(&self) -> bool {
+        matches!(self.polarity, ty::ImplPolarity::Negative)
+    }
 }
 
 #[derive(Clone, Debug)]
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index b5ab6a35fdb..6357cfee141 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -1285,9 +1285,8 @@ impl clean::Impl {
             f.write_str(" ")?;
 
             if let Some(ref ty) = self.trait_ {
-                match self.polarity {
-                    ty::ImplPolarity::Positive | ty::ImplPolarity::Reservation => {}
-                    ty::ImplPolarity::Negative => write!(f, "!")?,
+                if self.is_negative_trait_impl() {
+                    write!(f, "!")?;
                 }
                 ty.print(cx).fmt(f)?;
                 write!(f, " for ")?;
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index 9074e40a536..7ce637d3ab4 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -1780,20 +1780,23 @@ fn render_impl(
 
     let mut impl_items = Buffer::empty_from(w);
     let mut default_impl_items = Buffer::empty_from(w);
+    let impl_ = i.inner_impl();
 
-    for trait_item in &i.inner_impl().items {
-        doc_impl_item(
-            &mut default_impl_items,
-            &mut impl_items,
-            cx,
-            trait_item,
-            if trait_.is_some() { &i.impl_item } else { parent },
-            link,
-            render_mode,
-            false,
-            trait_,
-            rendering_params,
-        );
+    if !impl_.is_negative_trait_impl() {
+        for trait_item in &impl_.items {
+            doc_impl_item(
+                &mut default_impl_items,
+                &mut impl_items,
+                cx,
+                trait_item,
+                if trait_.is_some() { &i.impl_item } else { parent },
+                link,
+                render_mode,
+                false,
+                trait_,
+                rendering_params,
+            );
+        }
     }
 
     fn render_default_items(
@@ -1844,13 +1847,15 @@ fn render_impl(
     // We don't emit documentation for default items if they appear in the
     // Implementations on Foreign Types or Implementors sections.
     if rendering_params.show_default_items {
-        if let Some(t) = trait_ {
+        if let Some(t) = trait_
+            && !impl_.is_negative_trait_impl()
+        {
             render_default_items(
                 &mut default_impl_items,
                 &mut impl_items,
                 cx,
                 t,
-                i.inner_impl(),
+                impl_,
                 &i.impl_item,
                 render_mode,
                 rendering_params,
@@ -1882,7 +1887,7 @@ fn render_impl(
         }
 
         if let Some(ref dox) = i.impl_item.opt_doc_value() {
-            if trait_.is_none() && i.inner_impl().items.is_empty() {
+            if trait_.is_none() && impl_.items.is_empty() {
                 w.write_str(
                     "<div class=\"item-info\">\
                          <div class=\"stab empty-impl\">This impl block contains no items.</div>\
diff --git a/src/rustdoc-json-types/lib.rs b/src/rustdoc-json-types/lib.rs
index a93ac6ccaf1..999134a4090 100644
--- a/src/rustdoc-json-types/lib.rs
+++ b/src/rustdoc-json-types/lib.rs
@@ -634,7 +634,7 @@ pub struct Discriminant {
     /// hexadecimal, and underscores), making it unsuitable to be machine
     /// interpreted.
     ///
-    /// In some cases, when the value is to complex, this may be `"{ _ }"`.
+    /// In some cases, when the value is too complex, this may be `"{ _ }"`.
     /// When this occurs is unstable, and may change without notice.
     pub expr: String,
     /// The numerical value of the discriminant. Stored as a string due to
diff --git a/tests/run-make/dump-ice-to-disk/rmake.rs b/tests/run-make/dump-ice-to-disk/rmake.rs
index a64103fa516..260abf3aa6f 100644
--- a/tests/run-make/dump-ice-to-disk/rmake.rs
+++ b/tests/run-make/dump-ice-to-disk/rmake.rs
@@ -13,7 +13,7 @@
 use run_make_support::{cwd, has_extension, has_prefix, rfs, rustc, shallow_find_files};
 
 fn main() {
-    rustc().input("lib.rs").arg("-Ztreat-err-as-bug=1").run_fail();
+    rustc().env("RUSTC_ICE", cwd()).input("lib.rs").arg("-Ztreat-err-as-bug=1").run_fail();
     let default = get_text_from_ice(".").lines().count();
 
     clear_ice_files();
diff --git a/tests/run-make/fmt-write-bloat/main.rs b/tests/run-make/fmt-write-bloat/main.rs
index e86c48014c3..6f206d6515a 100644
--- a/tests/run-make/fmt-write-bloat/main.rs
+++ b/tests/run-make/fmt-write-bloat/main.rs
@@ -5,7 +5,7 @@
 use core::fmt;
 use core::fmt::Write;
 
-#[link(name = "c")]
+#[cfg_attr(not(windows), link(name = "c"))]
 extern "C" {}
 
 struct Dummy;
diff --git a/tests/run-make/fmt-write-bloat/rmake.rs b/tests/run-make/fmt-write-bloat/rmake.rs
index 4ae226ec0e2..6875ef9ddc0 100644
--- a/tests/run-make/fmt-write-bloat/rmake.rs
+++ b/tests/run-make/fmt-write-bloat/rmake.rs
@@ -15,9 +15,12 @@
 //! `NO_DEBUG_ASSERTIONS=1`). If debug assertions are disabled, then we can check for the absence of
 //! additional `usize` formatting and padding related symbols.
 
-// Reason: This test is `ignore-windows` because the `no_std` test (using `#[link(name = "c")])`
-// doesn't link on windows.
 //@ ignore-windows
+// Reason:
+// - MSVC targets really need to parse the .pdb file (aka the debug information).
+//   On Windows there's an API for that (dbghelp) which maybe we can use
+// - MinGW targets have a lot of symbols included in their runtime which we can't avoid.
+//   We would need to make the symbols we're looking for more specific for this test to work.
 //@ ignore-cross-compile
 
 use run_make_support::env::no_debug_assertions;
diff --git a/tests/rustdoc/negative-impl-no-items.rs b/tests/rustdoc/negative-impl-no-items.rs
new file mode 100644
index 00000000000..c628e542033
--- /dev/null
+++ b/tests/rustdoc/negative-impl-no-items.rs
@@ -0,0 +1,26 @@
+// This test ensures that negative impls don't have items listed inside them.
+
+#![feature(negative_impls)]
+#![crate_name = "foo"]
+
+pub struct Thing;
+
+//@ has 'foo/struct.Thing.html'
+// We check the full path to ensure there is no `<details>` element.
+//@ has - '//div[@id="trait-implementations-list"]/section[@id="impl-Iterator-for-Thing"]/h3' \
+// 'impl !Iterator for Thing'
+impl !Iterator for Thing {}
+
+// This struct will allow us to compare both paths.
+pub struct Witness;
+
+//@ has 'foo/struct.Witness.html'
+//@ has - '//div[@id="trait-implementations-list"]/details//section[@id="impl-Iterator-for-Witness"]/h3' \
+// 'impl Iterator for Witness'
+impl Iterator for Witness {
+    type Item = u8;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        None
+    }
+}
diff --git a/tests/ui/async-await/in-trait/generics-mismatch.rs b/tests/ui/async-await/in-trait/generics-mismatch.rs
index d3d1284982a..a5c81a92998 100644
--- a/tests/ui/async-await/in-trait/generics-mismatch.rs
+++ b/tests/ui/async-await/in-trait/generics-mismatch.rs
@@ -6,7 +6,7 @@ trait Foo {
 
 impl Foo for () {
     async fn foo<const N: usize>() {}
-    //~^ ERROR: method `foo` has an incompatible generic parameter for trait `Foo` [E0053]
+    //~^ ERROR: associated function `foo` has an incompatible generic parameter for trait `Foo` [E0053]
 }
 
 fn main() {}
diff --git a/tests/ui/async-await/in-trait/generics-mismatch.stderr b/tests/ui/async-await/in-trait/generics-mismatch.stderr
index c0357dc7f3e..cb0f95e8d09 100644
--- a/tests/ui/async-await/in-trait/generics-mismatch.stderr
+++ b/tests/ui/async-await/in-trait/generics-mismatch.stderr
@@ -1,4 +1,4 @@
-error[E0053]: method `foo` has an incompatible generic parameter for trait `Foo`
+error[E0053]: associated function `foo` has an incompatible generic parameter for trait `Foo`
   --> $DIR/generics-mismatch.rs:8:18
    |
 LL | trait Foo {
diff --git a/tests/ui/const-generics/defaults/mismatched_ty_const_in_trait_impl.rs b/tests/ui/const-generics/defaults/mismatched_ty_const_in_trait_impl.rs
index 5c9323261a9..9eb33acbb24 100644
--- a/tests/ui/const-generics/defaults/mismatched_ty_const_in_trait_impl.rs
+++ b/tests/ui/const-generics/defaults/mismatched_ty_const_in_trait_impl.rs
@@ -3,7 +3,7 @@ trait Trait {
 }
 impl Trait for () {
     fn foo<const M: u64>() {}
-    //~^ error: method `foo` has an incompatible generic parameter for trait
+    //~^ error: associated function `foo` has an incompatible generic parameter for trait
 }
 
 trait Other {
@@ -11,7 +11,7 @@ trait Other {
 }
 impl Other for () {
     fn bar<T>() {}
-    //~^ error: method `bar` has an incompatible generic parameter for trait
+    //~^ error: associated function `bar` has an incompatible generic parameter for trait
 }
 
 trait Uwu {
@@ -19,7 +19,7 @@ trait Uwu {
 }
 impl Uwu for () {
     fn baz<const N: i32>() {}
-    //~^ error: method `baz` has an incompatible generic parameter for trait
+    //~^ error: associated function `baz` has an incompatible generic parameter for trait
 }
 
 trait Aaaaaa {
@@ -27,7 +27,7 @@ trait Aaaaaa {
 }
 impl Aaaaaa for () {
     fn bbbb<T, const N: u32>() {}
-    //~^ error: method `bbbb` has an incompatible generic parameter for trait
+    //~^ error: associated function `bbbb` has an incompatible generic parameter for trait
 }
 
 trait Names {
@@ -35,7 +35,7 @@ trait Names {
 }
 impl Names for () {
     fn abcd<const N: u32, T>() {}
-    //~^ error: method `abcd` has an incompatible generic parameter for trait
+    //~^ error: associated function `abcd` has an incompatible generic parameter for trait
 }
 
 fn main() {}
diff --git a/tests/ui/const-generics/defaults/mismatched_ty_const_in_trait_impl.stderr b/tests/ui/const-generics/defaults/mismatched_ty_const_in_trait_impl.stderr
index 3455f2c8ea9..7ec162e1c29 100644
--- a/tests/ui/const-generics/defaults/mismatched_ty_const_in_trait_impl.stderr
+++ b/tests/ui/const-generics/defaults/mismatched_ty_const_in_trait_impl.stderr
@@ -1,4 +1,4 @@
-error[E0053]: method `foo` has an incompatible generic parameter for trait `Trait`
+error[E0053]: associated function `foo` has an incompatible generic parameter for trait `Trait`
   --> $DIR/mismatched_ty_const_in_trait_impl.rs:5:12
    |
 LL | trait Trait {
@@ -11,7 +11,7 @@ LL | impl Trait for () {
 LL |     fn foo<const M: u64>() {}
    |            ^^^^^^^^^^^^ found const parameter of type `u64`
 
-error[E0053]: method `bar` has an incompatible generic parameter for trait `Other`
+error[E0053]: associated function `bar` has an incompatible generic parameter for trait `Other`
   --> $DIR/mismatched_ty_const_in_trait_impl.rs:13:12
    |
 LL | trait Other {
@@ -24,7 +24,7 @@ LL | impl Other for () {
 LL |     fn bar<T>() {}
    |            ^ found type parameter
 
-error[E0053]: method `baz` has an incompatible generic parameter for trait `Uwu`
+error[E0053]: associated function `baz` has an incompatible generic parameter for trait `Uwu`
   --> $DIR/mismatched_ty_const_in_trait_impl.rs:21:12
    |
 LL | trait Uwu {
@@ -37,7 +37,7 @@ LL | impl Uwu for () {
 LL |     fn baz<const N: i32>() {}
    |            ^^^^^^^^^^^^ found const parameter of type `i32`
 
-error[E0053]: method `bbbb` has an incompatible generic parameter for trait `Aaaaaa`
+error[E0053]: associated function `bbbb` has an incompatible generic parameter for trait `Aaaaaa`
   --> $DIR/mismatched_ty_const_in_trait_impl.rs:29:13
    |
 LL | trait Aaaaaa {
@@ -50,7 +50,7 @@ LL | impl Aaaaaa for () {
 LL |     fn bbbb<T, const N: u32>() {}
    |             ^ found type parameter
 
-error[E0053]: method `abcd` has an incompatible generic parameter for trait `Names`
+error[E0053]: associated function `abcd` has an incompatible generic parameter for trait `Names`
   --> $DIR/mismatched_ty_const_in_trait_impl.rs:37:13
    |
 LL | trait Names {
diff --git a/tests/ui/delegation/not-supported.rs b/tests/ui/delegation/not-supported.rs
index 5701cc6055d..d5ac68ecf1b 100644
--- a/tests/ui/delegation/not-supported.rs
+++ b/tests/ui/delegation/not-supported.rs
@@ -53,7 +53,7 @@ mod generics {
         //~| ERROR method `foo2` has 0 type parameters but its trait declaration has 1 type parameter
         reuse <F as Trait>::foo3;
         //~^ ERROR early bound generics are not supported for associated delegation items
-        //~| ERROR lifetime parameters or bounds on method `foo3` do not match the trait declaration
+        //~| ERROR lifetime parameters or bounds on associated function `foo3` do not match the trait declaration
     }
 
     struct GenericS<T>(T);
diff --git a/tests/ui/delegation/not-supported.stderr b/tests/ui/delegation/not-supported.stderr
index e7ba9fc6719..14d6b374bd2 100644
--- a/tests/ui/delegation/not-supported.stderr
+++ b/tests/ui/delegation/not-supported.stderr
@@ -84,14 +84,14 @@ LL |         fn foo3<'a: 'a>(_: &'a u32) {}
 LL |         reuse <F as Trait>::foo3;
    |                             ^^^^
 
-error[E0195]: lifetime parameters or bounds on method `foo3` do not match the trait declaration
+error[E0195]: lifetime parameters or bounds on associated function `foo3` do not match the trait declaration
   --> $DIR/not-supported.rs:54:29
    |
 LL |         fn foo3<'a: 'a>(_: &'a u32) {}
-   |                -------- lifetimes in impl do not match this method in trait
+   |                -------- lifetimes in impl do not match this associated function in trait
 ...
 LL |         reuse <F as Trait>::foo3;
-   |                             ^^^^ lifetimes do not match method in trait
+   |                             ^^^^ lifetimes do not match associated function in trait
 
 error: delegation to a function with effect parameter is not supported yet
   --> $DIR/not-supported.rs:112:18
diff --git a/tests/ui/error-codes/E0049.stderr b/tests/ui/error-codes/E0049.stderr
index c0cd31faa90..83a30aa0a78 100644
--- a/tests/ui/error-codes/E0049.stderr
+++ b/tests/ui/error-codes/E0049.stderr
@@ -1,4 +1,4 @@
-error[E0049]: method `foo` has 0 type parameters but its trait declaration has 1 type parameter
+error[E0049]: associated function `foo` has 0 type parameters but its trait declaration has 1 type parameter
   --> $DIR/E0049.rs:8:11
    |
 LL |     fn foo<T: Default>(x: T) -> Self;
@@ -7,7 +7,7 @@ LL |     fn foo<T: Default>(x: T) -> Self;
 LL |     fn foo(x: bool) -> Self { Bar }
    |           ^ found 0 type parameters
 
-error[E0049]: method `fuzz` has 0 type parameters but its trait declaration has 2 type parameters
+error[E0049]: associated function `fuzz` has 0 type parameters but its trait declaration has 2 type parameters
   --> $DIR/E0049.rs:18:12
    |
 LL |     fn fuzz<A: Default, B>(x: A, y: B) -> Self;
diff --git a/tests/ui/error-codes/E0195.rs b/tests/ui/error-codes/E0195.rs
index f712ee42b8c..a7e51dff2f3 100644
--- a/tests/ui/error-codes/E0195.rs
+++ b/tests/ui/error-codes/E0195.rs
@@ -1,13 +1,13 @@
 trait Trait {
     fn bar<'a,'b:'a>(x: &'a str, y: &'b str);
-    //~^ NOTE lifetimes in impl do not match this method in trait
+    //~^ NOTE lifetimes in impl do not match this associated function in trait
 }
 
 struct Foo;
 
 impl Trait for Foo {
     fn bar<'a,'b>(x: &'a str, y: &'b str) { //~ ERROR E0195
-    //~^ NOTE lifetimes do not match method in trait
+    //~^ NOTE lifetimes do not match associated function in trait
     }
 }
 
diff --git a/tests/ui/error-codes/E0195.stderr b/tests/ui/error-codes/E0195.stderr
index b88064b7f90..9767dee9aec 100644
--- a/tests/ui/error-codes/E0195.stderr
+++ b/tests/ui/error-codes/E0195.stderr
@@ -1,11 +1,11 @@
-error[E0195]: lifetime parameters or bounds on method `bar` do not match the trait declaration
+error[E0195]: lifetime parameters or bounds on associated function `bar` do not match the trait declaration
   --> $DIR/E0195.rs:9:11
    |
 LL |     fn bar<'a,'b:'a>(x: &'a str, y: &'b str);
-   |           ---------- lifetimes in impl do not match this method in trait
+   |           ---------- lifetimes in impl do not match this associated function in trait
 ...
 LL |     fn bar<'a,'b>(x: &'a str, y: &'b str) {
-   |           ^^^^^^^ lifetimes do not match method in trait
+   |           ^^^^^^^ lifetimes do not match associated function in trait
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.rs b/tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.rs
index 285493132b6..946cb1a62b7 100644
--- a/tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.rs
+++ b/tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.rs
@@ -8,7 +8,7 @@ impl<T> X for T { //~ ERROR: not all trait items implemented
   fn foo<'a, T1: X<Y = T1>>(t : T1) -> T1::Y<'a> {
     //~^ ERROR missing generics for associated type
     //~^^ ERROR missing generics for associated type
-    //~| ERROR method `foo` has 1 type parameter but its trait declaration has 0 type parameters
+    //~| ERROR associated function `foo` has 1 type parameter but its trait declaration has 0 type parameters
     t
   }
 }
diff --git a/tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.stderr b/tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.stderr
index 6a600aee11f..72c2bdc72a2 100644
--- a/tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.stderr
+++ b/tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.stderr
@@ -1,4 +1,4 @@
-error[E0049]: method `foo` has 1 type parameter but its trait declaration has 0 type parameters
+error[E0049]: associated function `foo` has 1 type parameter but its trait declaration has 0 type parameters
   --> $DIR/gat-trait-path-missing-lifetime.rs:8:10
    |
 LL |   fn foo<'a>(t : Self::Y<'a>) -> Self::Y<'a> { t }
diff --git a/tests/ui/impl-trait/in-trait/trait-more-generics-than-impl.rs b/tests/ui/impl-trait/in-trait/trait-more-generics-than-impl.rs
index d9fac0238e1..0477de3315a 100644
--- a/tests/ui/impl-trait/in-trait/trait-more-generics-than-impl.rs
+++ b/tests/ui/impl-trait/in-trait/trait-more-generics-than-impl.rs
@@ -6,7 +6,7 @@ trait Foo {
 
 impl Foo for S {
     fn bar() -> impl Sized {}
-    //~^ ERROR method `bar` has 0 type parameters but its trait declaration has 1 type parameter
+    //~^ ERROR associated function `bar` has 0 type parameters but its trait declaration has 1 type parameter
 }
 
 fn main() {
diff --git a/tests/ui/impl-trait/in-trait/trait-more-generics-than-impl.stderr b/tests/ui/impl-trait/in-trait/trait-more-generics-than-impl.stderr
index eed4c07710e..ca67db40362 100644
--- a/tests/ui/impl-trait/in-trait/trait-more-generics-than-impl.stderr
+++ b/tests/ui/impl-trait/in-trait/trait-more-generics-than-impl.stderr
@@ -1,4 +1,4 @@
-error[E0049]: method `bar` has 0 type parameters but its trait declaration has 1 type parameter
+error[E0049]: associated function `bar` has 0 type parameters but its trait declaration has 1 type parameter
   --> $DIR/trait-more-generics-than-impl.rs:8:11
    |
 LL |     fn bar<T>() -> impl Sized;
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.precise.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.precise.stderr
index 9d1ca5dbf2c..b451555ec3c 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.precise.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.precise.stderr
@@ -40,7 +40,7 @@ error: `~const` can only be applied to `#[const_trait]` traits
 LL | const fn a<T: ~const Destruct>(_: T) {}
    |                      ^^^^^^^^
 
-error[E0049]: method `foo` has 1 const parameter but its trait declaration has 0 const parameters
+error[E0049]: associated function `foo` has 1 const parameter but its trait declaration has 0 const parameters
   --> $DIR/const-drop.rs:54:5
    |
 LL |     #[const_trait]
@@ -49,7 +49,7 @@ LL |     pub trait SomeTrait {
 LL |         fn foo();
    |               - expected 0 const parameters
 
-error[E0049]: method `foo` has 1 const parameter but its trait declaration has 0 const parameters
+error[E0049]: associated function `foo` has 1 const parameter but its trait declaration has 0 const parameters
   --> $DIR/const-drop.rs:54:5
    |
 LL |     #[const_trait]
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.stock.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.stock.stderr
index 2f93f9a6743..296614f7fd0 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.stock.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.stock.stderr
@@ -40,7 +40,7 @@ error: `~const` can only be applied to `#[const_trait]` traits
 LL | const fn a<T: ~const Destruct>(_: T) {}
    |                      ^^^^^^^^
 
-error[E0049]: method `foo` has 1 const parameter but its trait declaration has 0 const parameters
+error[E0049]: associated function `foo` has 1 const parameter but its trait declaration has 0 const parameters
   --> $DIR/const-drop.rs:54:5
    |
 LL |     #[const_trait]
@@ -49,7 +49,7 @@ LL |     pub trait SomeTrait {
 LL |         fn foo();
    |               - expected 0 const parameters
 
-error[E0049]: method `foo` has 1 const parameter but its trait declaration has 0 const parameters
+error[E0049]: associated function `foo` has 1 const parameter but its trait declaration has 0 const parameters
   --> $DIR/const-drop.rs:54:5
    |
 LL |     #[const_trait]
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.stderr
index b4c4cf0a890..7643697874f 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.stderr
@@ -1,4 +1,4 @@
-error[E0049]: method `bar` has 1 const parameter but its trait declaration has 0 const parameters
+error[E0049]: associated function `bar` has 1 const parameter but its trait declaration has 0 const parameters
   --> $DIR/const-default-bound-non-const-specialized-bound.rs:16:1
    |
 LL | #[const_trait]
@@ -16,7 +16,7 @@ LL | |     T: Foo, //FIXME ~ ERROR missing `~const` qualifier
 LL | |     T: Specialize,
    | |__________________^
 
-error[E0049]: method `baz` has 1 const parameter but its trait declaration has 0 const parameters
+error[E0049]: associated function `baz` has 1 const parameter but its trait declaration has 0 const parameters
   --> $DIR/const-default-bound-non-const-specialized-bound.rs:36:1
    |
 LL | #[const_trait]
@@ -25,7 +25,7 @@ LL | trait Baz {
 LL |     fn baz();
    |           - expected 0 const parameters
 
-error[E0049]: method `baz` has 1 const parameter but its trait declaration has 0 const parameters
+error[E0049]: associated function `baz` has 1 const parameter but its trait declaration has 0 const parameters
   --> $DIR/const-default-bound-non-const-specialized-bound.rs:36:1
    |
 LL | #[const_trait]
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-const-specialized.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-const-specialized.stderr
index cabf201405f..9b2ae8d739c 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-const-specialized.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-const-specialized.stderr
@@ -1,4 +1,4 @@
-error[E0049]: method `value` has 1 const parameter but its trait declaration has 0 const parameters
+error[E0049]: associated function `value` has 1 const parameter but its trait declaration has 0 const parameters
   --> $DIR/const-default-const-specialized.rs:10:1
    |
 LL | #[const_trait]
@@ -7,7 +7,7 @@ LL | trait Value {
 LL |     fn value() -> u32;
    |             - expected 0 const parameters
 
-error[E0049]: method `value` has 1 const parameter but its trait declaration has 0 const parameters
+error[E0049]: associated function `value` has 1 const parameter but its trait declaration has 0 const parameters
   --> $DIR/const-default-const-specialized.rs:10:1
    |
 LL | #[const_trait]
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/default-keyword.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/default-keyword.stderr
index 52c8708f2c8..18a25045f4b 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/default-keyword.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/default-keyword.stderr
@@ -1,4 +1,4 @@
-error[E0049]: method `foo` has 1 const parameter but its trait declaration has 0 const parameters
+error[E0049]: associated function `foo` has 1 const parameter but its trait declaration has 0 const parameters
   --> $DIR/default-keyword.rs:7:1
    |
 LL | #[const_trait]
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.stderr
index 1aa34637ca4..ecdc7b930e6 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.stderr
@@ -1,4 +1,4 @@
-error[E0049]: method `foo` has 1 const parameter but its trait declaration has 0 const parameters
+error[E0049]: associated function `foo` has 1 const parameter but its trait declaration has 0 const parameters
   --> $DIR/issue-95186-specialize-on-tilde-const.rs:14:1
    |
 LL | #[const_trait]
@@ -7,7 +7,7 @@ LL | trait Foo {
 LL |     fn foo();
    |           - expected 0 const parameters
 
-error[E0049]: method `foo` has 1 const parameter but its trait declaration has 0 const parameters
+error[E0049]: associated function `foo` has 1 const parameter but its trait declaration has 0 const parameters
   --> $DIR/issue-95186-specialize-on-tilde-const.rs:14:1
    |
 LL | #[const_trait]
@@ -18,7 +18,7 @@ LL |     fn foo();
    |
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
-error[E0049]: method `bar` has 1 const parameter but its trait declaration has 0 const parameters
+error[E0049]: associated function `bar` has 1 const parameter but its trait declaration has 0 const parameters
   --> $DIR/issue-95186-specialize-on-tilde-const.rs:30:1
    |
 LL | #[const_trait]
@@ -27,7 +27,7 @@ LL | trait Bar {
 LL |     fn bar() {}
    |           - expected 0 const parameters
 
-error[E0049]: method `bar` has 1 const parameter but its trait declaration has 0 const parameters
+error[E0049]: associated function `bar` has 1 const parameter but its trait declaration has 0 const parameters
   --> $DIR/issue-95186-specialize-on-tilde-const.rs:30:1
    |
 LL | #[const_trait]
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.stderr
index 0e0f391b086..6679bb46537 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.stderr
@@ -1,4 +1,4 @@
-error[E0049]: method `bar` has 1 const parameter but its trait declaration has 0 const parameters
+error[E0049]: associated function `bar` has 1 const parameter but its trait declaration has 0 const parameters
   --> $DIR/issue-95187-same-trait-bound-different-constness.rs:18:1
    |
 LL | #[const_trait]
@@ -7,7 +7,7 @@ LL | trait Bar {
 LL |     fn bar();
    |           - expected 0 const parameters
 
-error[E0049]: method `bar` has 1 const parameter but its trait declaration has 0 const parameters
+error[E0049]: associated function `bar` has 1 const parameter but its trait declaration has 0 const parameters
   --> $DIR/issue-95187-same-trait-bound-different-constness.rs:18:1
    |
 LL | #[const_trait]
@@ -18,7 +18,7 @@ LL |     fn bar();
    |
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
-error[E0049]: method `baz` has 1 const parameter but its trait declaration has 0 const parameters
+error[E0049]: associated function `baz` has 1 const parameter but its trait declaration has 0 const parameters
   --> $DIR/issue-95187-same-trait-bound-different-constness.rs:38:1
    |
 LL | #[const_trait]
@@ -27,7 +27,7 @@ LL | trait Baz {
 LL |     fn baz();
    |           - expected 0 const parameters
 
-error[E0049]: method `baz` has 1 const parameter but its trait declaration has 0 const parameters
+error[E0049]: associated function `baz` has 1 const parameter but its trait declaration has 0 const parameters
   --> $DIR/issue-95187-same-trait-bound-different-constness.rs:38:1
    |
 LL | #[const_trait]
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.stderr
index d49beb93259..7f363922947 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.stderr
@@ -1,4 +1,4 @@
-error[E0049]: method `value` has 1 const parameter but its trait declaration has 0 const parameters
+error[E0049]: associated function `value` has 1 const parameter but its trait declaration has 0 const parameters
   --> $DIR/non-const-default-const-specialized.rs:9:1
    |
 LL | #[const_trait]
@@ -7,7 +7,7 @@ LL | trait Value {
 LL |     fn value() -> u32;
    |             - expected 0 const parameters
 
-error[E0049]: method `value` has 1 const parameter but its trait declaration has 0 const parameters
+error[E0049]: associated function `value` has 1 const parameter but its trait declaration has 0 const parameters
   --> $DIR/non-const-default-const-specialized.rs:9:1
    |
 LL | #[const_trait]
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness-2.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness-2.stderr
index d082cd6de60..bf273f349b4 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness-2.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness-2.stderr
@@ -1,4 +1,4 @@
-error[E0049]: method `a` has 1 const parameter but its trait declaration has 0 const parameters
+error[E0049]: associated function `a` has 1 const parameter but its trait declaration has 0 const parameters
   --> $DIR/specializing-constness-2.rs:9:1
    |
 LL | #[const_trait]
@@ -7,7 +7,7 @@ LL | pub trait A {
 LL |     fn a() -> u32;
    |         - expected 0 const parameters
 
-error[E0049]: method `a` has 1 const parameter but its trait declaration has 0 const parameters
+error[E0049]: associated function `a` has 1 const parameter but its trait declaration has 0 const parameters
   --> $DIR/specializing-constness-2.rs:9:1
    |
 LL | #[const_trait]
diff --git a/tests/ui/rust-2018/auxiliary/edition-lint-infer-outlives-macro.rs b/tests/ui/rust-2018/edition-lint-inter-outlives/auxiliary/edition-lint-infer-outlives-macro.rs
index d45fa10f022..d45fa10f022 100644
--- a/tests/ui/rust-2018/auxiliary/edition-lint-infer-outlives-macro.rs
+++ b/tests/ui/rust-2018/edition-lint-inter-outlives/auxiliary/edition-lint-infer-outlives-macro.rs
diff --git a/tests/ui/rust-2018/edition-lint-infer-outlives-macro.fixed b/tests/ui/rust-2018/edition-lint-inter-outlives/edition-lint-infer-outlives-macro.fixed
index 435857224ac..435857224ac 100644
--- a/tests/ui/rust-2018/edition-lint-infer-outlives-macro.fixed
+++ b/tests/ui/rust-2018/edition-lint-inter-outlives/edition-lint-infer-outlives-macro.fixed
diff --git a/tests/ui/rust-2018/edition-lint-infer-outlives-macro.rs b/tests/ui/rust-2018/edition-lint-inter-outlives/edition-lint-infer-outlives-macro.rs
index 6c879231a16..6c879231a16 100644
--- a/tests/ui/rust-2018/edition-lint-infer-outlives-macro.rs
+++ b/tests/ui/rust-2018/edition-lint-inter-outlives/edition-lint-infer-outlives-macro.rs
diff --git a/tests/ui/rust-2018/edition-lint-infer-outlives-macro.stderr b/tests/ui/rust-2018/edition-lint-inter-outlives/edition-lint-infer-outlives-macro.stderr
index d684911be39..d684911be39 100644
--- a/tests/ui/rust-2018/edition-lint-infer-outlives-macro.stderr
+++ b/tests/ui/rust-2018/edition-lint-inter-outlives/edition-lint-infer-outlives-macro.stderr
diff --git a/tests/ui/rust-2018/edition-lint-infer-outlives-multispan.rs b/tests/ui/rust-2018/edition-lint-inter-outlives/edition-lint-infer-outlives-multispan.rs
index d2254acb33f..d2254acb33f 100644
--- a/tests/ui/rust-2018/edition-lint-infer-outlives-multispan.rs
+++ b/tests/ui/rust-2018/edition-lint-inter-outlives/edition-lint-infer-outlives-multispan.rs
diff --git a/tests/ui/rust-2018/edition-lint-infer-outlives-multispan.stderr b/tests/ui/rust-2018/edition-lint-inter-outlives/edition-lint-infer-outlives-multispan.stderr
index 1f4190665b9..1f4190665b9 100644
--- a/tests/ui/rust-2018/edition-lint-infer-outlives-multispan.stderr
+++ b/tests/ui/rust-2018/edition-lint-inter-outlives/edition-lint-infer-outlives-multispan.stderr
diff --git a/tests/ui/rust-2018/edition-lint-infer-outlives.fixed b/tests/ui/rust-2018/edition-lint-inter-outlives/edition-lint-infer-outlives.fixed
index c4948051c18..c4948051c18 100644
--- a/tests/ui/rust-2018/edition-lint-infer-outlives.fixed
+++ b/tests/ui/rust-2018/edition-lint-inter-outlives/edition-lint-infer-outlives.fixed
diff --git a/tests/ui/rust-2018/edition-lint-infer-outlives.rs b/tests/ui/rust-2018/edition-lint-inter-outlives/edition-lint-infer-outlives.rs
index c80e91ca12c..c80e91ca12c 100644
--- a/tests/ui/rust-2018/edition-lint-infer-outlives.rs
+++ b/tests/ui/rust-2018/edition-lint-inter-outlives/edition-lint-infer-outlives.rs
diff --git a/tests/ui/rust-2018/edition-lint-infer-outlives.stderr b/tests/ui/rust-2018/edition-lint-inter-outlives/edition-lint-infer-outlives.stderr
index dbf301fd8a1..dbf301fd8a1 100644
--- a/tests/ui/rust-2018/edition-lint-infer-outlives.stderr
+++ b/tests/ui/rust-2018/edition-lint-inter-outlives/edition-lint-infer-outlives.stderr
diff --git a/tests/ui/rust-2018/edition-lint-inter-outlives/explicit-outlives-recursive-119228.fixed b/tests/ui/rust-2018/edition-lint-inter-outlives/explicit-outlives-recursive-119228.fixed
new file mode 100644
index 00000000000..7b9fac8f408
--- /dev/null
+++ b/tests/ui/rust-2018/edition-lint-inter-outlives/explicit-outlives-recursive-119228.fixed
@@ -0,0 +1,41 @@
+//@ run-rustfix
+//@ check-pass
+#![deny(explicit_outlives_requirements)]
+
+pub trait TypeCx {
+    type Ty;
+}
+
+pub struct Pat<Cx: TypeCx> {
+    pub ty: Cx::Ty,
+}
+
+// Simple recursive case: no warning
+pub struct MyTypeContextSimpleRecursive<'thir, 'tcx: 'thir> {
+    pub pat: Pat<MyTypeContextSimpleRecursive<'thir, 'tcx>>,
+}
+impl<'thir, 'tcx: 'thir> TypeCx for MyTypeContextSimpleRecursive<'thir, 'tcx> {
+    type Ty = ();
+}
+
+// Non-recursive case: we want a warning
+pub struct MyTypeContextNotRecursive<'thir, 'tcx: 'thir> {
+    pub tcx: &'tcx (),
+    pub thir: &'thir (),
+}
+impl<'thir, 'tcx: 'thir> TypeCx for MyTypeContextNotRecursive<'thir, 'tcx> {
+    type Ty = ();
+}
+
+
+// Mixed-recursive case: we want a warning
+pub struct MyTypeContextMixedRecursive<'thir, 'tcx: 'thir> {
+    pub pat: Pat<MyTypeContextMixedRecursive<'thir, 'tcx>>,
+    pub tcx: &'tcx (),
+    pub thir: &'thir (),
+}
+impl<'thir, 'tcx: 'thir> TypeCx for MyTypeContextMixedRecursive<'thir, 'tcx> {
+    type Ty = ();
+}
+
+fn main() {}
diff --git a/tests/ui/rust-2018/edition-lint-inter-outlives/explicit-outlives-recursive-119228.rs b/tests/ui/rust-2018/edition-lint-inter-outlives/explicit-outlives-recursive-119228.rs
new file mode 100644
index 00000000000..7b9fac8f408
--- /dev/null
+++ b/tests/ui/rust-2018/edition-lint-inter-outlives/explicit-outlives-recursive-119228.rs
@@ -0,0 +1,41 @@
+//@ run-rustfix
+//@ check-pass
+#![deny(explicit_outlives_requirements)]
+
+pub trait TypeCx {
+    type Ty;
+}
+
+pub struct Pat<Cx: TypeCx> {
+    pub ty: Cx::Ty,
+}
+
+// Simple recursive case: no warning
+pub struct MyTypeContextSimpleRecursive<'thir, 'tcx: 'thir> {
+    pub pat: Pat<MyTypeContextSimpleRecursive<'thir, 'tcx>>,
+}
+impl<'thir, 'tcx: 'thir> TypeCx for MyTypeContextSimpleRecursive<'thir, 'tcx> {
+    type Ty = ();
+}
+
+// Non-recursive case: we want a warning
+pub struct MyTypeContextNotRecursive<'thir, 'tcx: 'thir> {
+    pub tcx: &'tcx (),
+    pub thir: &'thir (),
+}
+impl<'thir, 'tcx: 'thir> TypeCx for MyTypeContextNotRecursive<'thir, 'tcx> {
+    type Ty = ();
+}
+
+
+// Mixed-recursive case: we want a warning
+pub struct MyTypeContextMixedRecursive<'thir, 'tcx: 'thir> {
+    pub pat: Pat<MyTypeContextMixedRecursive<'thir, 'tcx>>,
+    pub tcx: &'tcx (),
+    pub thir: &'thir (),
+}
+impl<'thir, 'tcx: 'thir> TypeCx for MyTypeContextMixedRecursive<'thir, 'tcx> {
+    type Ty = ();
+}
+
+fn main() {}
diff --git a/tests/ui/specialization/const_trait_impl.stderr b/tests/ui/specialization/const_trait_impl.stderr
index e39138983c6..643f1de3e8d 100644
--- a/tests/ui/specialization/const_trait_impl.stderr
+++ b/tests/ui/specialization/const_trait_impl.stderr
@@ -1,4 +1,4 @@
-error[E0049]: method `foo` has 1 const parameter but its trait declaration has 0 const parameters
+error[E0049]: associated function `foo` has 1 const parameter but its trait declaration has 0 const parameters
   --> $DIR/const_trait_impl.rs:6:1
    |
 LL | #[const_trait]
@@ -7,7 +7,7 @@ LL | pub unsafe trait Sup {
 LL |     fn foo() -> u32;
    |           - expected 0 const parameters
 
-error[E0049]: method `foo` has 1 const parameter but its trait declaration has 0 const parameters
+error[E0049]: associated function `foo` has 1 const parameter but its trait declaration has 0 const parameters
   --> $DIR/const_trait_impl.rs:6:1
    |
 LL | #[const_trait]
@@ -36,7 +36,7 @@ error: `~const` can only be applied to `#[const_trait]` traits
 LL | impl<T: ~const Default + ~const Sub> const A for T {
    |                ^^^^^^^
 
-error[E0049]: method `a` has 1 const parameter but its trait declaration has 0 const parameters
+error[E0049]: associated function `a` has 1 const parameter but its trait declaration has 0 const parameters
   --> $DIR/const_trait_impl.rs:29:1
    |
 LL | #[const_trait]
@@ -45,7 +45,7 @@ LL | pub trait A {
 LL |     fn a() -> u32;
    |         - expected 0 const parameters
 
-error[E0049]: method `a` has 1 const parameter but its trait declaration has 0 const parameters
+error[E0049]: associated function `a` has 1 const parameter but its trait declaration has 0 const parameters
   --> $DIR/const_trait_impl.rs:29:1
    |
 LL | #[const_trait]
@@ -56,7 +56,7 @@ LL |     fn a() -> u32;
    |
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
-error[E0049]: method `a` has 1 const parameter but its trait declaration has 0 const parameters
+error[E0049]: associated function `a` has 1 const parameter but its trait declaration has 0 const parameters
   --> $DIR/const_trait_impl.rs:29:1
    |
 LL | #[const_trait]
diff --git a/tests/ui/typeck/issue-36708.stderr b/tests/ui/typeck/issue-36708.stderr
index 3589796b6aa..0aca575320f 100644
--- a/tests/ui/typeck/issue-36708.stderr
+++ b/tests/ui/typeck/issue-36708.stderr
@@ -1,4 +1,4 @@
-error[E0049]: method `foo` has 1 type parameter but its trait declaration has 0 type parameters
+error[E0049]: associated function `foo` has 1 type parameter but its trait declaration has 0 type parameters
   --> $DIR/issue-36708.rs:8:12
    |
 LL |     fn foo<T>() {}