about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_ast_passes/src/ast_validation.rs20
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs8
-rw-r--r--compiler/rustc_hir_typeck/messages.ftl2
-rw-r--r--compiler/rustc_hir_typeck/src/callee.rs1
-rw-r--r--compiler/rustc_hir_typeck/src/errors.rs11
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs15
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs30
-rw-r--r--compiler/rustc_hir_typeck/src/op.rs46
-rw-r--r--compiler/rustc_infer/src/infer/combine.rs6
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs95
-rw-r--r--compiler/rustc_privacy/messages.ftl7
-rw-r--r--compiler/rustc_privacy/src/errors.rs29
-rw-r--r--compiler/rustc_privacy/src/lib.rs270
-rw-r--r--compiler/rustc_target/src/spec/loongarch64_unknown_none.rs5
-rw-r--r--compiler/rustc_target/src/spec/loongarch64_unknown_none_softfloat.rs5
-rw-r--r--compiler/rustc_trait_selection/src/solve/assembly/mod.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs8
-rw-r--r--library/alloc/src/collections/binary_heap/mod.rs238
-rw-r--r--library/core/src/ptr/mut_ptr.rs18
-rw-r--r--library/std/src/sys/windows/c/windows_sys.rs20
-rw-r--r--library/std/src/thread/mod.rs2
-rw-r--r--src/bootstrap/render_tests.rs34
-rw-r--r--src/bootstrap/test.rs6
-rw-r--r--src/librustdoc/html/render/mod.rs90
-rw-r--r--src/librustdoc/html/render/print_item.rs48
-rw-r--r--src/tools/generate-windows-sys/src/arm_shim.rs20
-rw-r--r--src/tools/generate-windows-sys/src/main.rs4
-rw-r--r--tests/rustdoc-gui/headers-color.goml22
-rw-r--r--tests/rustdoc/issue-112515-impl-ty-alias.rs30
-rw-r--r--tests/rustdoc/issue-32077-type-alias-impls.rs59
-rw-r--r--tests/ui/associated-inherent-types/private-in-public.rs5
-rw-r--r--tests/ui/associated-inherent-types/private-in-public.stderr52
-rw-r--r--tests/ui/const-generics/generic_const_exprs/eval-privacy.rs6
-rw-r--r--tests/ui/const-generics/generic_const_exprs/eval-privacy.stderr22
-rw-r--r--tests/ui/error-codes/E0445.rs7
-rw-r--r--tests/ui/error-codes/E0445.stderr52
-rw-r--r--tests/ui/extern/issue-112363-extern-item-where-clauses-debug-ice.rs10
-rw-r--r--tests/ui/extern/issue-112363-extern-item-where-clauses-debug-ice.stderr47
-rw-r--r--tests/ui/issues/issue-18389.rs6
-rw-r--r--tests/ui/issues/issue-18389.stderr26
-rw-r--r--tests/ui/parser/foreign-ty-semantic-fail.rs1
-rw-r--r--tests/ui/parser/foreign-ty-semantic-fail.stderr13
-rw-r--r--tests/ui/privacy/private-in-public-non-principal.rs6
-rw-r--r--tests/ui/privacy/private-in-public-non-principal.stderr26
-rw-r--r--tests/ui/privacy/private-inferred-type-1.rs10
-rw-r--r--tests/ui/privacy/private-inferred-type-1.stderr18
-rw-r--r--tests/ui/privacy/unnameable_types.rs30
-rw-r--r--tests/ui/privacy/unnameable_types.stderr38
-rw-r--r--tests/ui/privacy/where-priv-type.rs6
-rw-r--r--tests/ui/privacy/where-priv-type.stderr110
-rw-r--r--tests/ui/privacy/where-pub-type-impls-priv-trait.rs5
-rw-r--r--tests/ui/privacy/where-pub-type-impls-priv-trait.stderr88
-rw-r--r--tests/ui/pub/issue-33174-restricted-type-in-public-interface.rs12
-rw-r--r--tests/ui/pub/issue-33174-restricted-type-in-public-interface.stderr52
-rw-r--r--tests/ui/typeck/issue-112252-ptr-arithmetics-help.fixed10
-rw-r--r--tests/ui/typeck/issue-112252-ptr-arithmetics-help.rs10
-rw-r--r--tests/ui/typeck/issue-112252-ptr-arithmetics-help.stderr54
-rw-r--r--tests/ui/typeck/ptr-null-mutability-suggestions.fixed11
-rw-r--r--tests/ui/typeck/ptr-null-mutability-suggestions.rs11
-rw-r--r--tests/ui/typeck/ptr-null-mutability-suggestions.stderr21
-rw-r--r--tests/ui/unsized-locals/rust-call.rs12
-rw-r--r--tests/ui/unsized-locals/rust-call.stderr13
62 files changed, 1576 insertions, 365 deletions
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index 04ed2767876..a0979bbda54 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -364,7 +364,12 @@ impl<'a> AstValidator<'a> {
         self.err_handler().emit_err(errors::BoundInContext { span, ctx });
     }
 
-    fn check_foreign_ty_genericless(&self, generics: &Generics, where_span: Span) {
+    fn check_foreign_ty_genericless(
+        &self,
+        generics: &Generics,
+        before_where_clause: &TyAliasWhereClause,
+        after_where_clause: &TyAliasWhereClause,
+    ) {
         let cannot_have = |span, descr, remove_descr| {
             self.err_handler().emit_err(errors::ExternTypesCannotHave {
                 span,
@@ -378,9 +383,14 @@ impl<'a> AstValidator<'a> {
             cannot_have(generics.span, "generic parameters", "generic parameters");
         }
 
-        if !generics.where_clause.predicates.is_empty() {
-            cannot_have(where_span, "`where` clauses", "`where` clause");
-        }
+        let check_where_clause = |where_clause: &TyAliasWhereClause| {
+            if let TyAliasWhereClause(true, where_clause_span) = where_clause {
+                cannot_have(*where_clause_span, "`where` clauses", "`where` clause");
+            }
+        };
+
+        check_where_clause(before_where_clause);
+        check_where_clause(after_where_clause);
     }
 
     fn check_foreign_kind_bodyless(&self, ident: Ident, kind: &str, body: Option<Span>) {
@@ -1039,7 +1049,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                 self.check_defaultness(fi.span, *defaultness);
                 self.check_foreign_kind_bodyless(fi.ident, "type", ty.as_ref().map(|b| b.span));
                 self.check_type_no_bounds(bounds, "`extern` blocks");
-                self.check_foreign_ty_genericless(generics, where_clauses.0.1);
+                self.check_foreign_ty_genericless(generics, &where_clauses.0, &where_clauses.1);
                 self.check_foreign_item_ascii_only(fi.ident);
             }
             ForeignItemKind::Static(_, _, body) => {
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index a269a7a1d8b..4554d167080 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -1449,7 +1449,7 @@ fn check_fn_or_method<'tcx>(
         let span = tcx.def_span(def_id);
         let has_implicit_self = hir_decl.implicit_self != hir::ImplicitSelfKind::None;
         let mut inputs = sig.inputs().iter().skip(if has_implicit_self { 1 } else { 0 });
-        // Check that the argument is a tuple
+        // Check that the argument is a tuple and is sized
         if let Some(ty) = inputs.next() {
             wfcx.register_bound(
                 ObligationCause::new(span, wfcx.body_def_id, ObligationCauseCode::RustCall),
@@ -1457,6 +1457,12 @@ fn check_fn_or_method<'tcx>(
                 *ty,
                 tcx.require_lang_item(hir::LangItem::Tuple, Some(span)),
             );
+            wfcx.register_bound(
+                ObligationCause::new(span, wfcx.body_def_id, ObligationCauseCode::RustCall),
+                wfcx.param_env,
+                *ty,
+                tcx.require_lang_item(hir::LangItem::Sized, Some(span)),
+            );
         } else {
             tcx.sess.span_err(
                 hir_decl.inputs.last().map_or(span, |input| input.span),
diff --git a/compiler/rustc_hir_typeck/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl
index 4728edd837a..c1c58db5764 100644
--- a/compiler/rustc_hir_typeck/messages.ftl
+++ b/compiler/rustc_hir_typeck/messages.ftl
@@ -89,6 +89,8 @@ hir_typeck_suggest_boxing_note = for more on the distinction between the stack a
 
 hir_typeck_suggest_boxing_when_appropriate = store this in the heap by calling `Box::new`
 
+hir_typeck_suggest_ptr_null_mut = consider using `core::ptr::null_mut` instead
+
 hir_typeck_union_pat_dotdot = `..` cannot be used in union patterns
 
 hir_typeck_union_pat_multiple_fields = union patterns should have exactly one field
diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs
index 4389ad6ef26..9da72aae776 100644
--- a/compiler/rustc_hir_typeck/src/callee.rs
+++ b/compiler/rustc_hir_typeck/src/callee.rs
@@ -470,6 +470,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     self.tcx.require_lang_item(hir::LangItem::Tuple, Some(sp)),
                     traits::ObligationCause::new(sp, self.body_id, traits::RustCall),
                 );
+                self.require_type_is_sized(ty, sp, traits::RustCall);
             } else {
                 self.tcx.sess.span_err(
                         sp,
diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs
index 5161a366ae7..6b4168d8944 100644
--- a/compiler/rustc_hir_typeck/src/errors.rs
+++ b/compiler/rustc_hir_typeck/src/errors.rs
@@ -298,6 +298,17 @@ pub enum SuggestBoxing {
     },
 }
 
+#[derive(Subdiagnostic)]
+#[suggestion(
+    hir_typeck_suggest_ptr_null_mut,
+    applicability = "maybe-incorrect",
+    code = "core::ptr::null_mut()"
+)]
+pub struct SuggestPtrNullMut {
+    #[primary_span]
+    pub span: Span,
+}
+
 #[derive(Diagnostic)]
 #[diag(hir_typeck_no_associated_item, code = "E0599")]
 pub struct NoAssociatedItem {
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index f03c7ca44ba..3f6847be91b 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -2871,6 +2871,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             );
                         }
                     }
+
+                    if base_t.is_unsafe_ptr() && idx_t.is_integral() {
+                        err.multipart_suggestion(
+                            "consider using `wrapping_add` or `add` for indexing into raw pointer",
+                            vec![
+                                (base.span.between(idx.span), ".wrapping_add(".to_owned()),
+                                (
+                                    idx.span.shrink_to_hi().until(expr.span.shrink_to_hi()),
+                                    ")".to_owned(),
+                                ),
+                            ],
+                            Applicability::MaybeIncorrect,
+                        );
+                    }
+
                     let reported = err.emit();
                     self.tcx.ty_error(reported)
                 }
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
index 48c3d6f08de..4a3e28ffce9 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -1,4 +1,5 @@
 use crate::coercion::CoerceMany;
+use crate::errors::SuggestPtrNullMut;
 use crate::fn_ctxt::arg_matrix::{ArgMatrix, Compatibility, Error, ExpectedIdx, ProvidedIdx};
 use crate::gather_locals::Declaration;
 use crate::method::MethodCallee;
@@ -814,6 +815,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 );
             }
 
+            self.suggest_ptr_null_mut(
+                expected_ty,
+                provided_ty,
+                provided_args[*provided_idx],
+                &mut err,
+            );
+
             // Call out where the function is defined
             self.label_fn_like(
                 &mut err,
@@ -1271,6 +1279,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         err.emit();
     }
 
+    fn suggest_ptr_null_mut(
+        &self,
+        expected_ty: Ty<'tcx>,
+        provided_ty: Ty<'tcx>,
+        arg: &hir::Expr<'tcx>,
+        err: &mut rustc_errors::DiagnosticBuilder<'tcx, ErrorGuaranteed>,
+    ) {
+        if let ty::RawPtr(ty::TypeAndMut { mutbl: hir::Mutability::Mut, .. }) = expected_ty.kind()
+            && let ty::RawPtr(ty::TypeAndMut { mutbl: hir::Mutability::Not, .. }) = provided_ty.kind()
+            && let hir::ExprKind::Call(callee, _) = arg.kind
+            && let hir::ExprKind::Path(hir::QPath::Resolved(_, path)) = callee.kind
+            && let Res::Def(_, def_id) = path.res
+            && self.tcx.get_diagnostic_item(sym::ptr_null) == Some(def_id)
+        {
+            // The user provided `ptr::null()`, but the function expects
+            // `ptr::null_mut()`.
+            err.subdiagnostic(SuggestPtrNullMut {
+                span: arg.span
+            });
+        }
+    }
+
     // AST fragment checking
     pub(in super::super) fn check_lit(
         &self,
diff --git a/compiler/rustc_hir_typeck/src/op.rs b/compiler/rustc_hir_typeck/src/op.rs
index b8bf2b69120..4f3d1d45679 100644
--- a/compiler/rustc_hir_typeck/src/op.rs
+++ b/compiler/rustc_hir_typeck/src/op.rs
@@ -521,6 +521,52 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         }
                     }
                 }
+
+                // Suggest using `add`, `offset` or `offset_from` for pointer - {integer},
+                // pointer + {integer} or pointer - pointer.
+                if op.span.can_be_used_for_suggestions() {
+                    match op.node {
+                        hir::BinOpKind::Add if lhs_ty.is_unsafe_ptr() && rhs_ty.is_integral() => {
+                            err.multipart_suggestion(
+                                "consider using `wrapping_add` or `add` for pointer + {integer}",
+                                vec![
+                                    (
+                                        lhs_expr.span.between(rhs_expr.span),
+                                        ".wrapping_add(".to_owned(),
+                                    ),
+                                    (rhs_expr.span.shrink_to_hi(), ")".to_owned()),
+                                ],
+                                Applicability::MaybeIncorrect,
+                            );
+                        }
+                        hir::BinOpKind::Sub => {
+                            if lhs_ty.is_unsafe_ptr() && rhs_ty.is_integral() {
+                                err.multipart_suggestion(
+                                    "consider using `wrapping_sub` or `sub` for pointer - {integer}",
+                                    vec![
+                                        (lhs_expr.span.between(rhs_expr.span), ".wrapping_sub(".to_owned()),
+                                        (rhs_expr.span.shrink_to_hi(), ")".to_owned()),
+                                    ],
+                                    Applicability::MaybeIncorrect
+                                );
+                            }
+
+                            if lhs_ty.is_unsafe_ptr() && rhs_ty.is_unsafe_ptr() {
+                                err.multipart_suggestion(
+                                    "consider using `offset_from` for pointer - pointer if the pointers point to the same allocation",
+                                    vec![
+                                        (lhs_expr.span.shrink_to_lo(), "unsafe { ".to_owned()),
+                                        (lhs_expr.span.between(rhs_expr.span), ".offset_from(".to_owned()),
+                                        (rhs_expr.span.shrink_to_hi(), ") }".to_owned()),
+                                    ],
+                                    Applicability::MaybeIncorrect
+                                );
+                            }
+                        }
+                        _ => {}
+                    }
+                }
+
                 let reported = err.emit();
                 self.tcx.ty_error(reported)
             }
diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs
index 7a80ee98cb3..bb2bd2faec2 100644
--- a/compiler/rustc_infer/src/infer/combine.rs
+++ b/compiler/rustc_infer/src/infer/combine.rs
@@ -34,7 +34,7 @@ use rustc_middle::infer::unify_key::{ConstVarValue, ConstVariableValue};
 use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
 use rustc_middle::ty::error::{ExpectedFound, TypeError};
 use rustc_middle::ty::relate::{RelateResult, TypeRelation};
-use rustc_middle::ty::{self, AliasKind, InferConst, ToPredicate, Ty, TyCtxt, TypeVisitableExt};
+use rustc_middle::ty::{self, InferConst, ToPredicate, Ty, TyCtxt, TypeVisitableExt};
 use rustc_middle::ty::{IntType, UintType};
 use rustc_span::DUMMY_SP;
 
@@ -103,12 +103,12 @@ impl<'tcx> InferCtxt<'tcx> {
 
             // We don't expect `TyVar` or `Fresh*` vars at this point with lazy norm.
             (
-                ty::Alias(AliasKind::Projection, _),
+                ty::Alias(..),
                 ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)),
             )
             | (
                 ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)),
-                ty::Alias(AliasKind::Projection, _),
+                ty::Alias(..),
             ) if self.next_trait_solver() => {
                 bug!()
             }
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index eb246c3f93e..53ece08ac3d 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -3372,7 +3372,9 @@ declare_lint_pass! {
         OVERLAPPING_RANGE_ENDPOINTS,
         PATTERNS_IN_FNS_WITHOUT_BODY,
         POINTER_STRUCTURAL_MATCH,
+        PRIVATE_BOUNDS,
         PRIVATE_IN_PUBLIC,
+        PRIVATE_INTERFACES,
         PROC_MACRO_BACK_COMPAT,
         PROC_MACRO_DERIVE_RESOLUTION_FALLBACK,
         PUB_USE_OF_PRIVATE_EXTERN_CRATE,
@@ -3399,6 +3401,7 @@ declare_lint_pass! {
         UNINHABITED_STATIC,
         UNKNOWN_CRATE_TYPES,
         UNKNOWN_LINTS,
+        UNNAMEABLE_TYPES,
         UNREACHABLE_CODE,
         UNREACHABLE_PATTERNS,
         UNSAFE_OP_IN_UNSAFE_FN,
@@ -4251,3 +4254,95 @@ declare_lint! {
     Warn,
     "\"invalid_parameter\" isn't a valid argument for `#[macro_export]`",
 }
+
+declare_lint! {
+    /// The `private_interfaces` lint detects types in a primary interface of an item,
+    /// that are more private than the item itself. Primary interface of an item is all
+    /// its interface except for bounds on generic parameters and where clauses.
+    ///
+    /// ### Example
+    ///
+    /// ```rust,compile_fail
+    /// # #![allow(unused)]
+    /// # #![allow(private_in_public)]
+    /// #![deny(private_interfaces)]
+    /// struct SemiPriv;
+    ///
+    /// mod m1 {
+    ///     struct Priv;
+    ///     impl crate::SemiPriv {
+    ///         pub fn f(_: Priv) {}
+    ///     }
+    /// }
+    ///
+    /// # fn main() {}
+    /// ```
+    ///
+    /// {{produces}}
+    ///
+    /// ### Explanation
+    ///
+    /// Having something private in primary interface guarantees that
+    /// the item will be unusable from outer modules due to type privacy.
+    pub PRIVATE_INTERFACES,
+    Allow,
+    "private type in primary interface of an item",
+}
+
+declare_lint! {
+    /// The `private_bounds` lint detects types in a secondary interface of an item,
+    /// that are more private than the item itself. Secondary interface of an item consists of
+    /// bounds on generic parameters and where clauses, including supertraits for trait items.
+    ///
+    /// ### Example
+    ///
+    /// ```rust,compile_fail
+    /// # #![allow(private_in_public)]
+    /// # #![allow(unused)]
+    /// #![deny(private_bounds)]
+    ///
+    /// struct PrivTy;
+    /// pub struct S
+    ///     where PrivTy:
+    /// {}
+    /// # fn main() {}
+    /// ```
+    ///
+    /// {{produces}}
+    ///
+    /// ### Explanation
+    ///
+    /// Having private types or traits in item bounds makes it less clear what interface
+    /// the item actually provides.
+    pub PRIVATE_BOUNDS,
+    Allow,
+    "private type in secondary interface of an item"
+}
+
+declare_lint! {
+    /// The `unnameable_types` lint detects types for which you can get objects of that type,
+    /// but cannot name the type itself.
+    ///
+    /// ### Example
+    ///
+    /// ```rust,compile_fail
+    /// # #![allow(unused)]
+    /// #![deny(unnameable_types)]
+    /// mod m {
+    ///     pub struct S;
+    /// }
+    ///
+    /// pub fn get_voldemort() -> m::S { m::S }
+    /// # fn main() {}
+    /// ```
+    ///
+    /// {{produces}}
+    ///
+    /// ### Explanation
+    ///
+    /// It is often expected that if you can obtain an object of type `T`, then
+    /// you can name the type `T` as well, this lint attempts to enforce this rule.
+    pub UNNAMEABLE_TYPES,
+    Allow,
+    "effective visibility of a type is larger than the area in which it can be named"
+}
diff --git a/compiler/rustc_privacy/messages.ftl b/compiler/rustc_privacy/messages.ftl
index b68e8a78aab..6f51981cf09 100644
--- a/compiler/rustc_privacy/messages.ftl
+++ b/compiler/rustc_privacy/messages.ftl
@@ -17,7 +17,14 @@ privacy_private_in_public_lint =
         *[other] E0446
     })
 
+privacy_private_interface_or_bounds_lint = {$ty_kind} `{$ty_descr}` is more private than the item `{$item_descr}`
+    .item_note = {$item_kind} `{$item_descr}` is reachable at visibility `{$item_vis_descr}`
+    .ty_note = but {$ty_kind} `{$ty_descr}` is only usable at visibility `{$ty_vis_descr}`
+
 privacy_report_effective_visibility = {$descr}
 
+privacy_unnameable_types_lint = {$kind} `{$descr}` is reachable but cannot be named
+    .label = reachable at visibility `{$reachable_vis}`, but can only be named at visibility `{$reexported_vis}`
+
 privacy_unnamed_item_is_private = {$kind} is private
     .label = private {$kind}
diff --git a/compiler/rustc_privacy/src/errors.rs b/compiler/rustc_privacy/src/errors.rs
index 72b53eefa08..67689b5e713 100644
--- a/compiler/rustc_privacy/src/errors.rs
+++ b/compiler/rustc_privacy/src/errors.rs
@@ -98,3 +98,32 @@ pub struct PrivateInPublicLint<'a> {
     pub kind: &'a str,
     pub descr: DiagnosticArgFromDisplay<'a>,
 }
+
+#[derive(LintDiagnostic)]
+#[diag(privacy_unnameable_types_lint)]
+pub struct UnnameableTypesLint<'a> {
+    #[label]
+    pub span: Span,
+    pub kind: &'a str,
+    pub descr: DiagnosticArgFromDisplay<'a>,
+    pub reachable_vis: &'a str,
+    pub reexported_vis: &'a str,
+}
+
+// Used for `private_interfaces` and `private_bounds` lints.
+// They will replace private-in-public errors and compatibility lints in future.
+// See https://rust-lang.github.io/rfcs/2145-type-privacy.html for more details.
+#[derive(LintDiagnostic)]
+#[diag(privacy_private_interface_or_bounds_lint)]
+pub struct PrivateInterfacesOrBoundsLint<'a> {
+    #[note(privacy_item_note)]
+    pub item_span: Span,
+    pub item_kind: &'a str,
+    pub item_descr: DiagnosticArgFromDisplay<'a>,
+    pub item_vis_descr: &'a str,
+    #[note(privacy_ty_note)]
+    pub ty_span: Span,
+    pub ty_kind: &'a str,
+    pub ty_descr: DiagnosticArgFromDisplay<'a>,
+    pub ty_vis_descr: &'a str,
+}
diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs
index afd32e38d5b..a51a1c9a8a4 100644
--- a/compiler/rustc_privacy/src/lib.rs
+++ b/compiler/rustc_privacy/src/lib.rs
@@ -22,7 +22,7 @@ use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID};
 use rustc_hir::intravisit::{self, Visitor};
-use rustc_hir::{AssocItemKind, HirIdSet, ItemId, Node, PatKind};
+use rustc_hir::{AssocItemKind, ForeignItemKind, HirIdSet, ItemId, Node, PatKind};
 use rustc_middle::bug;
 use rustc_middle::hir::nested_filter;
 use rustc_middle::middle::privacy::{EffectiveVisibilities, EffectiveVisibility, Level};
@@ -42,8 +42,8 @@ use std::{fmt, mem};
 
 use errors::{
     FieldIsPrivate, FieldIsPrivateLabel, FromPrivateDependencyInPublicInterface, InPublicInterface,
-    InPublicInterfaceTraits, ItemIsPrivate, PrivateInPublicLint, ReportEffectiveVisibility,
-    UnnamedItemIsPrivate,
+    InPublicInterfaceTraits, ItemIsPrivate, PrivateInPublicLint, PrivateInterfacesOrBoundsLint,
+    ReportEffectiveVisibility, UnnameableTypesLint, UnnamedItemIsPrivate,
 };
 
 fluent_messages! { "../messages.ftl" }
@@ -52,6 +52,17 @@ fluent_messages! { "../messages.ftl" }
 /// Generic infrastructure used to implement specific visitors below.
 ////////////////////////////////////////////////////////////////////////////////
 
+struct LazyDefPathStr<'tcx> {
+    def_id: DefId,
+    tcx: TyCtxt<'tcx>,
+}
+
+impl<'tcx> fmt::Display for LazyDefPathStr<'tcx> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "{}", self.tcx.def_path_str(self.def_id))
+    }
+}
+
 /// Implemented to visit all `DefId`s in a type.
 /// Visiting `DefId`s is useful because visibilities and reachabilities are attached to them.
 /// The idea is to visit "all components of a type", as documented in
@@ -259,16 +270,6 @@ where
                     &LazyDefPathStr { def_id: data.def_id, tcx },
                 )?;
 
-                struct LazyDefPathStr<'tcx> {
-                    def_id: DefId,
-                    tcx: TyCtxt<'tcx>,
-                }
-                impl<'tcx> fmt::Display for LazyDefPathStr<'tcx> {
-                    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-                        write!(f, "{}", self.tcx.def_path_str(self.def_id))
-                    }
-                }
-
                 // This will also visit substs if necessary, so we don't need to recurse.
                 return if self.def_id_visitor.shallow() {
                     ControlFlow::Continue(())
@@ -409,8 +410,25 @@ impl VisibilityLike for ty::Visibility {
     }
 }
 
-impl VisibilityLike for EffectiveVisibility {
-    const MAX: Self = EffectiveVisibility::from_vis(ty::Visibility::Public);
+struct NonShallowEffectiveVis(EffectiveVisibility);
+
+impl VisibilityLike for NonShallowEffectiveVis {
+    const MAX: Self = NonShallowEffectiveVis(EffectiveVisibility::from_vis(ty::Visibility::Public));
+    const SHALLOW: bool = false;
+
+    fn new_min(find: &FindMin<'_, '_, Self>, def_id: LocalDefId) -> Self {
+        let find = FindMin {
+            tcx: find.tcx,
+            effective_visibilities: find.effective_visibilities,
+            min: ShallowEffectiveVis(find.min.0),
+        };
+        NonShallowEffectiveVis(VisibilityLike::new_min(&find, def_id).0)
+    }
+}
+
+struct ShallowEffectiveVis(EffectiveVisibility);
+impl VisibilityLike for ShallowEffectiveVis {
+    const MAX: Self = ShallowEffectiveVis(EffectiveVisibility::from_vis(ty::Visibility::Public));
     // Type inference is very smart sometimes.
     // It can make an impl reachable even some components of its type or trait are unreachable.
     // E.g. methods of `impl ReachableTrait<UnreachableTy> for ReachableTy<UnreachableTy> { ... }`
@@ -429,7 +447,7 @@ impl VisibilityLike for EffectiveVisibility {
                 EffectiveVisibility::from_vis(private_vis)
             });
 
-        effective_vis.min(find.min, find.tcx)
+        ShallowEffectiveVis(effective_vis.min(find.min.0, find.tcx))
     }
 }
 
@@ -767,11 +785,13 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
                 }
             }
             hir::ItemKind::Impl(ref impl_) => {
-                let item_ev = EffectiveVisibility::of_impl(
+                let item_ev = ShallowEffectiveVis::of_impl(
                     item.owner_id.def_id,
                     self.tcx,
                     &self.effective_visibilities,
-                );
+                )
+                .0;
+
                 self.update_eff_vis(item.owner_id.def_id, item_ev, None, Level::Direct);
 
                 self.reach(item.owner_id.def_id, item_ev).generics().predicates().ty().trait_ref();
@@ -912,6 +932,21 @@ pub struct TestReachabilityVisitor<'tcx, 'a> {
     effective_visibilities: &'a EffectiveVisibilities,
 }
 
+fn vis_to_string<'tcx>(def_id: LocalDefId, vis: ty::Visibility, tcx: TyCtxt<'tcx>) -> String {
+    match vis {
+        ty::Visibility::Restricted(restricted_id) => {
+            if restricted_id.is_top_level_module() {
+                "pub(crate)".to_string()
+            } else if restricted_id == tcx.parent_module_from_def_id(def_id) {
+                "pub(self)".to_string()
+            } else {
+                format!("pub({})", tcx.item_name(restricted_id.to_def_id()))
+            }
+        }
+        ty::Visibility::Public => "pub".to_string(),
+    }
+}
+
 impl<'tcx, 'a> TestReachabilityVisitor<'tcx, 'a> {
     fn effective_visibility_diagnostic(&mut self, def_id: LocalDefId) {
         if self.tcx.has_attr(def_id, sym::rustc_effective_visibility) {
@@ -919,18 +954,7 @@ impl<'tcx, 'a> TestReachabilityVisitor<'tcx, 'a> {
             let span = self.tcx.def_span(def_id.to_def_id());
             if let Some(effective_vis) = self.effective_visibilities.effective_vis(def_id) {
                 for level in Level::all_levels() {
-                    let vis_str = match effective_vis.at_level(level) {
-                        ty::Visibility::Restricted(restricted_id) => {
-                            if restricted_id.is_top_level_module() {
-                                "pub(crate)".to_string()
-                            } else if *restricted_id == self.tcx.parent_module_from_def_id(def_id) {
-                                "pub(self)".to_string()
-                            } else {
-                                format!("pub({})", self.tcx.item_name(restricted_id.to_def_id()))
-                            }
-                        }
-                        ty::Visibility::Public => "pub".to_string(),
-                    };
+                    let vis_str = vis_to_string(def_id, *effective_vis.at_level(level), self.tcx);
                     if level != Level::Direct {
                         error_msg.push_str(", ");
                     }
@@ -1745,12 +1769,15 @@ struct SearchInterfaceForPrivateItemsVisitor<'tcx> {
     item_def_id: LocalDefId,
     /// The visitor checks that each component type is at least this visible.
     required_visibility: ty::Visibility,
+    required_effective_vis: Option<EffectiveVisibility>,
     has_old_errors: bool,
     in_assoc_ty: bool,
+    in_primary_interface: bool,
 }
 
 impl SearchInterfaceForPrivateItemsVisitor<'_> {
     fn generics(&mut self) -> &mut Self {
+        self.in_primary_interface = true;
         for param in &self.tcx.generics_of(self.item_def_id).params {
             match param.kind {
                 GenericParamDefKind::Lifetime => {}
@@ -1769,6 +1796,7 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> {
     }
 
     fn predicates(&mut self) -> &mut Self {
+        self.in_primary_interface = false;
         // N.B., we use `explicit_predicates_of` and not `predicates_of`
         // because we don't want to report privacy errors due to where
         // clauses that the compiler inferred. We only want to
@@ -1780,6 +1808,7 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> {
     }
 
     fn bounds(&mut self) -> &mut Self {
+        self.in_primary_interface = false;
         self.visit_predicates(ty::GenericPredicates {
             parent: None,
             predicates: self.tcx.explicit_item_bounds(self.item_def_id).skip_binder(),
@@ -1788,6 +1817,7 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> {
     }
 
     fn ty(&mut self) -> &mut Self {
+        self.in_primary_interface = true;
         self.visit(self.tcx.type_of(self.item_def_id).subst_identity());
         self
     }
@@ -1811,8 +1841,10 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> {
         };
 
         let vis = self.tcx.local_visibility(local_def_id);
+        let hir_id = self.tcx.hir().local_def_id_to_hir_id(local_def_id);
+        let span = self.tcx.def_span(self.item_def_id.to_def_id());
+        let vis_span = self.tcx.def_span(def_id);
         if !vis.is_at_least(self.required_visibility, self.tcx) {
-            let hir_id = self.tcx.hir().local_def_id_to_hir_id(local_def_id);
             let vis_descr = match vis {
                 ty::Visibility::Public => "public",
                 ty::Visibility::Restricted(vis_def_id) => {
@@ -1825,12 +1857,11 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> {
                     }
                 }
             };
-            let span = self.tcx.def_span(self.item_def_id.to_def_id());
+
             if self.has_old_errors
                 || self.in_assoc_ty
                 || self.tcx.resolutions(()).has_pub_restricted
             {
-                let vis_span = self.tcx.def_span(def_id);
                 if kind == "trait" {
                     self.tcx.sess.emit_err(InPublicInterfaceTraits {
                         span,
@@ -1858,6 +1889,39 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> {
             }
         }
 
+        let Some(effective_vis) = self.required_effective_vis else {
+            return false;
+        };
+
+        // FIXME: `Level::Reachable` should be taken instead of `Level::Reexported`
+        let reexported_at_vis = *effective_vis.at_level(Level::Reexported);
+
+        if !vis.is_at_least(reexported_at_vis, self.tcx) {
+            let lint = if self.in_primary_interface {
+                lint::builtin::PRIVATE_INTERFACES
+            } else {
+                lint::builtin::PRIVATE_BOUNDS
+            };
+            self.tcx.emit_lint(
+                lint,
+                hir_id,
+                PrivateInterfacesOrBoundsLint {
+                    item_span: span,
+                    item_kind: self.tcx.def_descr(self.item_def_id.to_def_id()),
+                    item_descr: (&LazyDefPathStr {
+                        def_id: self.item_def_id.to_def_id(),
+                        tcx: self.tcx,
+                    })
+                        .into(),
+                    item_vis_descr: &vis_to_string(self.item_def_id, reexported_at_vis, self.tcx),
+                    ty_span: vis_span,
+                    ty_kind: kind,
+                    ty_descr: descr.into(),
+                    ty_vis_descr: &vis_to_string(local_def_id, vis, self.tcx),
+                },
+            );
+        }
+
         false
     }
 
@@ -1891,25 +1955,55 @@ impl<'tcx> DefIdVisitor<'tcx> for SearchInterfaceForPrivateItemsVisitor<'tcx> {
     }
 }
 
-struct PrivateItemsInPublicInterfacesChecker<'tcx> {
+struct PrivateItemsInPublicInterfacesChecker<'tcx, 'a> {
     tcx: TyCtxt<'tcx>,
     old_error_set_ancestry: HirIdSet,
+    effective_visibilities: &'a EffectiveVisibilities,
 }
 
-impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx> {
+impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx, '_> {
     fn check(
         &self,
         def_id: LocalDefId,
         required_visibility: ty::Visibility,
+        required_effective_vis: Option<EffectiveVisibility>,
     ) -> SearchInterfaceForPrivateItemsVisitor<'tcx> {
         SearchInterfaceForPrivateItemsVisitor {
             tcx: self.tcx,
             item_def_id: def_id,
             required_visibility,
+            required_effective_vis,
             has_old_errors: self
                 .old_error_set_ancestry
                 .contains(&self.tcx.hir().local_def_id_to_hir_id(def_id)),
             in_assoc_ty: false,
+            in_primary_interface: true,
+        }
+    }
+
+    fn check_unnameable(&self, def_id: LocalDefId, effective_vis: Option<EffectiveVisibility>) {
+        let Some(effective_vis) = effective_vis else {
+            return;
+        };
+
+        let reexported_at_vis = effective_vis.at_level(Level::Reexported);
+        let reachable_at_vis = effective_vis.at_level(Level::Reachable);
+
+        if reexported_at_vis != reachable_at_vis {
+            let hir_id = self.tcx.hir().local_def_id_to_hir_id(def_id);
+            let span = self.tcx.def_span(def_id.to_def_id());
+            self.tcx.emit_spanned_lint(
+                lint::builtin::UNNAMEABLE_TYPES,
+                hir_id,
+                span,
+                UnnameableTypesLint {
+                    span,
+                    kind: self.tcx.def_descr(def_id.to_def_id()),
+                    descr: (&LazyDefPathStr { def_id: def_id.to_def_id(), tcx: self.tcx }).into(),
+                    reachable_vis: &vis_to_string(def_id, *reachable_at_vis, self.tcx),
+                    reexported_vis: &vis_to_string(def_id, *reexported_at_vis, self.tcx),
+                },
+            );
         }
     }
 
@@ -1918,13 +2012,19 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx> {
         def_id: LocalDefId,
         assoc_item_kind: AssocItemKind,
         vis: ty::Visibility,
+        effective_vis: Option<EffectiveVisibility>,
     ) {
-        let mut check = self.check(def_id, vis);
+        let mut check = self.check(def_id, vis, effective_vis);
 
         let (check_ty, is_assoc_ty) = match assoc_item_kind {
             AssocItemKind::Const | AssocItemKind::Fn { .. } => (true, false),
             AssocItemKind::Type => (self.tcx.defaultness(def_id).has_value(), true),
         };
+
+        if is_assoc_ty {
+            self.check_unnameable(def_id, self.get(def_id));
+        }
+
         check.in_assoc_ty = is_assoc_ty;
         check.generics().predicates();
         if check_ty {
@@ -1932,50 +2032,72 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx> {
         }
     }
 
+    fn get(&self, def_id: LocalDefId) -> Option<EffectiveVisibility> {
+        self.effective_visibilities.effective_vis(def_id).copied()
+    }
+
     pub fn check_item(&mut self, id: ItemId) {
         let tcx = self.tcx;
         let def_id = id.owner_id.def_id;
         let item_visibility = tcx.local_visibility(def_id);
+        let effective_vis = self.get(def_id);
         let def_kind = tcx.def_kind(def_id);
 
         match def_kind {
             DefKind::Const | DefKind::Static(_) | DefKind::Fn | DefKind::TyAlias => {
-                self.check(def_id, item_visibility).generics().predicates().ty();
+                if let DefKind::TyAlias = def_kind {
+                    self.check_unnameable(def_id, effective_vis);
+                }
+                self.check(def_id, item_visibility, effective_vis).generics().predicates().ty();
             }
             DefKind::OpaqueTy => {
                 // `ty()` for opaque types is the underlying type,
                 // it's not a part of interface, so we skip it.
-                self.check(def_id, item_visibility).generics().bounds();
+                self.check(def_id, item_visibility, effective_vis).generics().bounds();
             }
             DefKind::Trait => {
                 let item = tcx.hir().item(id);
                 if let hir::ItemKind::Trait(.., trait_item_refs) = item.kind {
-                    self.check(item.owner_id.def_id, item_visibility).generics().predicates();
+                    self.check_unnameable(item.owner_id.def_id, effective_vis);
+
+                    self.check(item.owner_id.def_id, item_visibility, effective_vis)
+                        .generics()
+                        .predicates();
 
                     for trait_item_ref in trait_item_refs {
                         self.check_assoc_item(
                             trait_item_ref.id.owner_id.def_id,
                             trait_item_ref.kind,
                             item_visibility,
+                            effective_vis,
                         );
 
                         if let AssocItemKind::Type = trait_item_ref.kind {
-                            self.check(trait_item_ref.id.owner_id.def_id, item_visibility).bounds();
+                            self.check(
+                                trait_item_ref.id.owner_id.def_id,
+                                item_visibility,
+                                effective_vis,
+                            )
+                            .bounds();
                         }
                     }
                 }
             }
             DefKind::TraitAlias => {
-                self.check(def_id, item_visibility).generics().predicates();
+                self.check(def_id, item_visibility, effective_vis).generics().predicates();
             }
             DefKind::Enum => {
                 let item = tcx.hir().item(id);
                 if let hir::ItemKind::Enum(ref def, _) = item.kind {
-                    self.check(item.owner_id.def_id, item_visibility).generics().predicates();
+                    self.check_unnameable(item.owner_id.def_id, effective_vis);
+
+                    self.check(item.owner_id.def_id, item_visibility, effective_vis)
+                        .generics()
+                        .predicates();
 
                     for variant in def.variants {
                         for field in variant.data.fields() {
-                            self.check(field.def_id, item_visibility).ty();
+                            self.check(field.def_id, item_visibility, effective_vis).ty();
                         }
                     }
                 }
@@ -1985,8 +2107,16 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx> {
                 let item = tcx.hir().item(id);
                 if let hir::ItemKind::ForeignMod { items, .. } = item.kind {
                     for foreign_item in items {
-                        let vis = tcx.local_visibility(foreign_item.id.owner_id.def_id);
-                        self.check(foreign_item.id.owner_id.def_id, vis)
+                        let foreign_item = tcx.hir().foreign_item(foreign_item.id);
+
+                        let ev = self.get(foreign_item.owner_id.def_id);
+                        let vis = tcx.local_visibility(foreign_item.owner_id.def_id);
+
+                        if let ForeignItemKind::Type = foreign_item.kind {
+                            self.check_unnameable(foreign_item.owner_id.def_id, ev);
+                        }
+
+                        self.check(foreign_item.owner_id.def_id, vis, ev)
                             .generics()
                             .predicates()
                             .ty();
@@ -1999,11 +2129,21 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx> {
                 if let hir::ItemKind::Struct(ref struct_def, _)
                 | hir::ItemKind::Union(ref struct_def, _) = item.kind
                 {
-                    self.check(item.owner_id.def_id, item_visibility).generics().predicates();
+                    self.check_unnameable(item.owner_id.def_id, effective_vis);
+                    self.check(item.owner_id.def_id, item_visibility, effective_vis)
+                        .generics()
+                        .predicates();
 
                     for field in struct_def.fields() {
                         let field_visibility = tcx.local_visibility(field.def_id);
-                        self.check(field.def_id, min(item_visibility, field_visibility, tcx)).ty();
+                        let field_ev = self.get(field.def_id);
+
+                        self.check(
+                            field.def_id,
+                            min(item_visibility, field_visibility, tcx),
+                            field_ev,
+                        )
+                        .ty();
                     }
                 }
             }
@@ -2016,10 +2156,30 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx> {
                 if let hir::ItemKind::Impl(ref impl_) = item.kind {
                     let impl_vis =
                         ty::Visibility::of_impl(item.owner_id.def_id, tcx, &Default::default());
+
+                    // we are using the non-shallow version here, unlike when building the
+                    // effective visisibilities table to avoid large number of false positives.
+                    // For example:
+                    //
+                    // impl From<Priv> for Pub {
+                    //     fn from(_: Priv) -> Pub {...}
+                    // }
+                    //
+                    // lints shouldn't be emmited even `from` effective visibility
+                    // is larger then `Priv` nominal visibility.
+                    let impl_ev = Some(
+                        NonShallowEffectiveVis::of_impl(
+                            item.owner_id.def_id,
+                            tcx,
+                            self.effective_visibilities,
+                        )
+                        .0,
+                    );
+
                     // check that private components do not appear in the generics or predicates of inherent impls
                     // this check is intentionally NOT performed for impls of traits, per #90586
                     if impl_.of_trait.is_none() {
-                        self.check(item.owner_id.def_id, impl_vis).generics().predicates();
+                        self.check(item.owner_id.def_id, impl_vis, impl_ev).generics().predicates();
                     }
                     for impl_item_ref in impl_.items {
                         let impl_item_vis = if impl_.of_trait.is_none() {
@@ -2031,10 +2191,18 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx> {
                         } else {
                             impl_vis
                         };
+
+                        let impl_item_ev = if impl_.of_trait.is_none() {
+                            self.get(impl_item_ref.id.owner_id.def_id)
+                        } else {
+                            impl_ev
+                        };
+
                         self.check_assoc_item(
                             impl_item_ref.id.owner_id.def_id,
                             impl_item_ref.kind,
                             impl_item_vis,
+                            impl_item_ev,
                         );
                     }
                 }
@@ -2186,7 +2354,11 @@ fn check_private_in_public(tcx: TyCtxt<'_>, (): ()) {
     }
 
     // Check for private types and traits in public interfaces.
-    let mut checker = PrivateItemsInPublicInterfacesChecker { tcx, old_error_set_ancestry };
+    let mut checker = PrivateItemsInPublicInterfacesChecker {
+        tcx,
+        old_error_set_ancestry,
+        effective_visibilities,
+    };
 
     for id in tcx.hir().items() {
         checker.check_item(id);
diff --git a/compiler/rustc_target/src/spec/loongarch64_unknown_none.rs b/compiler/rustc_target/src/spec/loongarch64_unknown_none.rs
index 618250591ad..209d481d6f8 100644
--- a/compiler/rustc_target/src/spec/loongarch64_unknown_none.rs
+++ b/compiler/rustc_target/src/spec/loongarch64_unknown_none.rs
@@ -1,4 +1,4 @@
-use super::{Cc, CodeModel, LinkerFlavor, Lld, PanicStrategy};
+use super::{Cc, CodeModel, LinkerFlavor, Lld, PanicStrategy, RelocModel};
 use super::{Target, TargetOptions};
 
 pub fn target() -> Target {
@@ -13,8 +13,7 @@ pub fn target() -> Target {
             linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::No),
             llvm_abiname: "lp64d".into(),
             max_atomic_width: Some(64),
-            position_independent_executables: true,
-            static_position_independent_executables: true,
+            relocation_model: RelocModel::Static,
             panic_strategy: PanicStrategy::Abort,
             code_model: Some(CodeModel::Small),
             ..Default::default()
diff --git a/compiler/rustc_target/src/spec/loongarch64_unknown_none_softfloat.rs b/compiler/rustc_target/src/spec/loongarch64_unknown_none_softfloat.rs
index 23123d7630c..93df4221e61 100644
--- a/compiler/rustc_target/src/spec/loongarch64_unknown_none_softfloat.rs
+++ b/compiler/rustc_target/src/spec/loongarch64_unknown_none_softfloat.rs
@@ -1,4 +1,4 @@
-use super::{Cc, CodeModel, LinkerFlavor, Lld, PanicStrategy};
+use super::{Cc, CodeModel, LinkerFlavor, Lld, PanicStrategy, RelocModel};
 use super::{Target, TargetOptions};
 
 pub fn target() -> Target {
@@ -14,8 +14,7 @@ pub fn target() -> Target {
             linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::No),
             llvm_abiname: "lp64s".into(),
             max_atomic_width: Some(64),
-            position_independent_executables: true,
-            static_position_independent_executables: true,
+            relocation_model: RelocModel::Static,
             panic_strategy: PanicStrategy::Abort,
             code_model: Some(CodeModel::Small),
             ..Default::default()
diff --git a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs
index f32ff0442a4..1b749b9c854 100644
--- a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs
@@ -320,7 +320,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         candidates
     }
 
-    /// If the self type of a goal is a projection, computing the relevant candidates is difficult.
+    /// If the self type of a goal is an alias, computing the relevant candidates is difficult.
     ///
     /// To deal with this, we first try to normalize the self type and add the candidates for the normalized
     /// self type to the list of candidates in case that succeeds. We also have to consider candidates with the
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index e73d917a8ae..5783383e93e 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -2663,9 +2663,15 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
             | ObligationCauseCode::LetElse
             | ObligationCauseCode::BinOp { .. }
             | ObligationCauseCode::AscribeUserTypeProvePredicate(..)
-            | ObligationCauseCode::RustCall
             | ObligationCauseCode::DropImpl
             | ObligationCauseCode::ConstParam(_) => {}
+            ObligationCauseCode::RustCall => {
+                if let Some(pred) = predicate.to_opt_poly_trait_pred()
+                    && Some(pred.def_id()) == self.tcx.lang_items().sized_trait()
+                {
+                    err.note("argument required to be sized due to `extern \"rust-call\"` ABI");
+                }
+            }
             ObligationCauseCode::SliceOrArrayElem => {
                 err.note("slice and array elements must have `Sized` type");
             }
diff --git a/library/alloc/src/collections/binary_heap/mod.rs b/library/alloc/src/collections/binary_heap/mod.rs
index 2c089bb3149..66573b90db9 100644
--- a/library/alloc/src/collections/binary_heap/mod.rs
+++ b/library/alloc/src/collections/binary_heap/mod.rs
@@ -143,6 +143,7 @@
 #![allow(missing_docs)]
 #![stable(feature = "rust1", since = "1.0.0")]
 
+use core::alloc::Allocator;
 use core::fmt;
 use core::iter::{FusedIterator, InPlaceIterable, SourceIter, TrustedLen};
 use core::mem::{self, swap, ManuallyDrop};
@@ -150,6 +151,7 @@ use core::num::NonZeroUsize;
 use core::ops::{Deref, DerefMut};
 use core::ptr;
 
+use crate::alloc::Global;
 use crate::collections::TryReserveError;
 use crate::slice;
 use crate::vec::{self, AsVecIntoIter, Vec};
@@ -271,8 +273,11 @@ mod tests;
 /// [peek\_mut]: BinaryHeap::peek_mut
 #[stable(feature = "rust1", since = "1.0.0")]
 #[cfg_attr(not(test), rustc_diagnostic_item = "BinaryHeap")]
-pub struct BinaryHeap<T> {
-    data: Vec<T>,
+pub struct BinaryHeap<
+    T,
+    #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
+> {
+    data: Vec<T, A>,
 }
 
 /// Structure wrapping a mutable reference to the greatest item on a
@@ -283,22 +288,26 @@ pub struct BinaryHeap<T> {
 ///
 /// [`peek_mut`]: BinaryHeap::peek_mut
 #[stable(feature = "binary_heap_peek_mut", since = "1.12.0")]
-pub struct PeekMut<'a, T: 'a + Ord> {
-    heap: &'a mut BinaryHeap<T>,
+pub struct PeekMut<
+    'a,
+    T: 'a + Ord,
+    #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
+> {
+    heap: &'a mut BinaryHeap<T, A>,
     // If a set_len + sift_down are required, this is Some. If a &mut T has not
     // yet been exposed to peek_mut()'s caller, it's None.
     original_len: Option<NonZeroUsize>,
 }
 
 #[stable(feature = "collection_debug", since = "1.17.0")]
-impl<T: Ord + fmt::Debug> fmt::Debug for PeekMut<'_, T> {
+impl<T: Ord + fmt::Debug, A: Allocator> fmt::Debug for PeekMut<'_, T, A> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_tuple("PeekMut").field(&self.heap.data[0]).finish()
     }
 }
 
 #[stable(feature = "binary_heap_peek_mut", since = "1.12.0")]
-impl<T: Ord> Drop for PeekMut<'_, T> {
+impl<T: Ord, A: Allocator> Drop for PeekMut<'_, T, A> {
     fn drop(&mut self) {
         if let Some(original_len) = self.original_len {
             // SAFETY: That's how many elements were in the Vec at the time of
@@ -315,7 +324,7 @@ impl<T: Ord> Drop for PeekMut<'_, T> {
 }
 
 #[stable(feature = "binary_heap_peek_mut", since = "1.12.0")]
-impl<T: Ord> Deref for PeekMut<'_, T> {
+impl<T: Ord, A: Allocator> Deref for PeekMut<'_, T, A> {
     type Target = T;
     fn deref(&self) -> &T {
         debug_assert!(!self.heap.is_empty());
@@ -325,7 +334,7 @@ impl<T: Ord> Deref for PeekMut<'_, T> {
 }
 
 #[stable(feature = "binary_heap_peek_mut", since = "1.12.0")]
-impl<T: Ord> DerefMut for PeekMut<'_, T> {
+impl<T: Ord, A: Allocator> DerefMut for PeekMut<'_, T, A> {
     fn deref_mut(&mut self) -> &mut T {
         debug_assert!(!self.heap.is_empty());
 
@@ -353,10 +362,10 @@ impl<T: Ord> DerefMut for PeekMut<'_, T> {
     }
 }
 
-impl<'a, T: Ord> PeekMut<'a, T> {
+impl<'a, T: Ord, A: Allocator> PeekMut<'a, T, A> {
     /// Removes the peeked value from the heap and returns it.
     #[stable(feature = "binary_heap_peek_mut_pop", since = "1.18.0")]
-    pub fn pop(mut this: PeekMut<'a, T>) -> T {
+    pub fn pop(mut this: PeekMut<'a, T, A>) -> T {
         if let Some(original_len) = this.original_len.take() {
             // SAFETY: This is how many elements were in the Vec at the time of
             // the BinaryHeap::peek_mut call.
@@ -371,7 +380,7 @@ impl<'a, T: Ord> PeekMut<'a, T> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: Clone> Clone for BinaryHeap<T> {
+impl<T: Clone, A: Allocator + Clone> Clone for BinaryHeap<T, A> {
     fn clone(&self) -> Self {
         BinaryHeap { data: self.data.clone() }
     }
@@ -391,18 +400,22 @@ impl<T: Ord> Default for BinaryHeap<T> {
 }
 
 #[stable(feature = "binaryheap_debug", since = "1.4.0")]
-impl<T: fmt::Debug> fmt::Debug for BinaryHeap<T> {
+impl<T: fmt::Debug, A: Allocator> fmt::Debug for BinaryHeap<T, A> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_list().entries(self.iter()).finish()
     }
 }
 
-struct RebuildOnDrop<'a, T: Ord> {
-    heap: &'a mut BinaryHeap<T>,
+struct RebuildOnDrop<
+    'a,
+    T: Ord,
+    #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
+> {
+    heap: &'a mut BinaryHeap<T, A>,
     rebuild_from: usize,
 }
 
-impl<'a, T: Ord> Drop for RebuildOnDrop<'a, T> {
+impl<T: Ord, A: Allocator> Drop for RebuildOnDrop<'_, T, A> {
     fn drop(&mut self) {
         self.heap.rebuild_tail(self.rebuild_from);
     }
@@ -446,6 +459,52 @@ impl<T: Ord> BinaryHeap<T> {
     pub fn with_capacity(capacity: usize) -> BinaryHeap<T> {
         BinaryHeap { data: Vec::with_capacity(capacity) }
     }
+}
+
+impl<T: Ord, A: Allocator> BinaryHeap<T, A> {
+    /// Creates an empty `BinaryHeap` as a max-heap, using `A` as allocator.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// #![feature(allocator_api)]
+    ///
+    /// use std::alloc::System;
+    /// use std::collections::BinaryHeap;
+    /// let mut heap = BinaryHeap::new_in(System);
+    /// heap.push(4);
+    /// ```
+    #[unstable(feature = "allocator_api", issue = "32838")]
+    #[must_use]
+    pub fn new_in(alloc: A) -> BinaryHeap<T, A> {
+        BinaryHeap { data: Vec::new_in(alloc) }
+    }
+
+    /// Creates an empty `BinaryHeap` with at least the specified capacity, using `A` as allocator.
+    ///
+    /// The binary heap will be able to hold at least `capacity` elements without
+    /// reallocating. This method is allowed to allocate for more elements than
+    /// `capacity`. If `capacity` is 0, the binary heap will not allocate.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// #![feature(allocator_api)]
+    ///
+    /// use std::alloc::System;
+    /// use std::collections::BinaryHeap;
+    /// let mut heap = BinaryHeap::with_capacity_in(10, System);
+    /// heap.push(4);
+    /// ```
+    #[unstable(feature = "allocator_api", issue = "32838")]
+    #[must_use]
+    pub fn with_capacity_in(capacity: usize, alloc: A) -> BinaryHeap<T, A> {
+        BinaryHeap { data: Vec::with_capacity_in(capacity, alloc) }
+    }
 
     /// Returns a mutable reference to the greatest item in the binary heap, or
     /// `None` if it is empty.
@@ -478,7 +537,7 @@ impl<T: Ord> BinaryHeap<T> {
     /// If the item is modified then the worst case time complexity is *O*(log(*n*)),
     /// otherwise it's *O*(1).
     #[stable(feature = "binary_heap_peek_mut", since = "1.12.0")]
-    pub fn peek_mut(&mut self) -> Option<PeekMut<'_, T>> {
+    pub fn peek_mut(&mut self) -> Option<PeekMut<'_, T, A>> {
         if self.is_empty() { None } else { Some(PeekMut { heap: self, original_len: None }) }
     }
 
@@ -573,7 +632,7 @@ impl<T: Ord> BinaryHeap<T> {
     /// ```
     #[must_use = "`self` will be dropped if the result is not used"]
     #[stable(feature = "binary_heap_extras_15", since = "1.5.0")]
-    pub fn into_sorted_vec(mut self) -> Vec<T> {
+    pub fn into_sorted_vec(mut self) -> Vec<T, A> {
         let mut end = self.len();
         while end > 1 {
             end -= 1;
@@ -831,7 +890,7 @@ impl<T: Ord> BinaryHeap<T> {
     /// ```
     #[inline]
     #[unstable(feature = "binary_heap_drain_sorted", issue = "59278")]
-    pub fn drain_sorted(&mut self) -> DrainSorted<'_, T> {
+    pub fn drain_sorted(&mut self) -> DrainSorted<'_, T, A> {
         DrainSorted { inner: self }
     }
 
@@ -874,7 +933,7 @@ impl<T: Ord> BinaryHeap<T> {
     }
 }
 
-impl<T> BinaryHeap<T> {
+impl<T, A: Allocator> BinaryHeap<T, A> {
     /// Returns an iterator visiting all values in the underlying vector, in
     /// arbitrary order.
     ///
@@ -911,7 +970,7 @@ impl<T> BinaryHeap<T> {
     /// assert_eq!(heap.into_iter_sorted().take(2).collect::<Vec<_>>(), [5, 4]);
     /// ```
     #[unstable(feature = "binary_heap_into_iter_sorted", issue = "59278")]
-    pub fn into_iter_sorted(self) -> IntoIterSorted<T> {
+    pub fn into_iter_sorted(self) -> IntoIterSorted<T, A> {
         IntoIterSorted { inner: self }
     }
 
@@ -1178,10 +1237,17 @@ impl<T> BinaryHeap<T> {
     /// ```
     #[must_use = "`self` will be dropped if the result is not used"]
     #[stable(feature = "binary_heap_extras_15", since = "1.5.0")]
-    pub fn into_vec(self) -> Vec<T> {
+    pub fn into_vec(self) -> Vec<T, A> {
         self.into()
     }
 
+    /// Returns a reference to the underlying allocator.
+    #[unstable(feature = "allocator_api", issue = "32838")]
+    #[inline]
+    pub fn allocator(&self) -> &A {
+        self.data.allocator()
+    }
+
     /// Returns the length of the binary heap.
     ///
     /// # Examples
@@ -1249,7 +1315,7 @@ impl<T> BinaryHeap<T> {
     /// ```
     #[inline]
     #[stable(feature = "drain", since = "1.6.0")]
-    pub fn drain(&mut self) -> Drain<'_, T> {
+    pub fn drain(&mut self) -> Drain<'_, T, A> {
         Drain { iter: self.data.drain(..) }
     }
 
@@ -1419,19 +1485,30 @@ impl<T> FusedIterator for Iter<'_, T> {}
 /// [`into_iter`]: BinaryHeap::into_iter
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(Clone)]
-pub struct IntoIter<T> {
-    iter: vec::IntoIter<T>,
+pub struct IntoIter<
+    T,
+    #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
+> {
+    iter: vec::IntoIter<T, A>,
+}
+
+impl<T, A: Allocator> IntoIter<T, A> {
+    /// Returns a reference to the underlying allocator.
+    #[unstable(feature = "allocator_api", issue = "32838")]
+    pub fn allocator(&self) -> &A {
+        self.iter.allocator()
+    }
 }
 
 #[stable(feature = "collection_debug", since = "1.17.0")]
-impl<T: fmt::Debug> fmt::Debug for IntoIter<T> {
+impl<T: fmt::Debug, A: Allocator> fmt::Debug for IntoIter<T, A> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_tuple("IntoIter").field(&self.iter.as_slice()).finish()
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T> Iterator for IntoIter<T> {
+impl<T, A: Allocator> Iterator for IntoIter<T, A> {
     type Item = T;
 
     #[inline]
@@ -1446,7 +1523,7 @@ impl<T> Iterator for IntoIter<T> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T> DoubleEndedIterator for IntoIter<T> {
+impl<T, A: Allocator> DoubleEndedIterator for IntoIter<T, A> {
     #[inline]
     fn next_back(&mut self) -> Option<T> {
         self.iter.next_back()
@@ -1454,14 +1531,14 @@ impl<T> DoubleEndedIterator for IntoIter<T> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T> ExactSizeIterator for IntoIter<T> {
+impl<T, A: Allocator> ExactSizeIterator for IntoIter<T, A> {
     fn is_empty(&self) -> bool {
         self.iter.is_empty()
     }
 }
 
 #[stable(feature = "fused", since = "1.26.0")]
-impl<T> FusedIterator for IntoIter<T> {}
+impl<T, A: Allocator> FusedIterator for IntoIter<T, A> {}
 
 #[stable(feature = "default_iters", since = "1.70.0")]
 impl<T> Default for IntoIter<T> {
@@ -1481,8 +1558,8 @@ impl<T> Default for IntoIter<T> {
 // also refer to the vec::in_place_collect module documentation to get an overview
 #[unstable(issue = "none", feature = "inplace_iteration")]
 #[doc(hidden)]
-unsafe impl<T> SourceIter for IntoIter<T> {
-    type Source = IntoIter<T>;
+unsafe impl<T, A: Allocator> SourceIter for IntoIter<T, A> {
+    type Source = IntoIter<T, A>;
 
     #[inline]
     unsafe fn as_inner(&mut self) -> &mut Self::Source {
@@ -1492,7 +1569,7 @@ unsafe impl<T> SourceIter for IntoIter<T> {
 
 #[unstable(issue = "none", feature = "inplace_iteration")]
 #[doc(hidden)]
-unsafe impl<I> InPlaceIterable for IntoIter<I> {}
+unsafe impl<I, A: Allocator> InPlaceIterable for IntoIter<I, A> {}
 
 unsafe impl<I> AsVecIntoIter for IntoIter<I> {
     type Item = I;
@@ -1505,12 +1582,23 @@ unsafe impl<I> AsVecIntoIter for IntoIter<I> {
 #[must_use = "iterators are lazy and do nothing unless consumed"]
 #[unstable(feature = "binary_heap_into_iter_sorted", issue = "59278")]
 #[derive(Clone, Debug)]
-pub struct IntoIterSorted<T> {
-    inner: BinaryHeap<T>,
+pub struct IntoIterSorted<
+    T,
+    #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
+> {
+    inner: BinaryHeap<T, A>,
+}
+
+impl<T, A: Allocator> IntoIterSorted<T, A> {
+    /// Returns a reference to the underlying allocator.
+    #[unstable(feature = "allocator_api", issue = "32838")]
+    pub fn allocator(&self) -> &A {
+        self.inner.allocator()
+    }
 }
 
 #[unstable(feature = "binary_heap_into_iter_sorted", issue = "59278")]
-impl<T: Ord> Iterator for IntoIterSorted<T> {
+impl<T: Ord, A: Allocator> Iterator for IntoIterSorted<T, A> {
     type Item = T;
 
     #[inline]
@@ -1526,13 +1614,13 @@ impl<T: Ord> Iterator for IntoIterSorted<T> {
 }
 
 #[unstable(feature = "binary_heap_into_iter_sorted", issue = "59278")]
-impl<T: Ord> ExactSizeIterator for IntoIterSorted<T> {}
+impl<T: Ord, A: Allocator> ExactSizeIterator for IntoIterSorted<T, A> {}
 
 #[unstable(feature = "binary_heap_into_iter_sorted", issue = "59278")]
-impl<T: Ord> FusedIterator for IntoIterSorted<T> {}
+impl<T: Ord, A: Allocator> FusedIterator for IntoIterSorted<T, A> {}
 
 #[unstable(feature = "trusted_len", issue = "37572")]
-unsafe impl<T: Ord> TrustedLen for IntoIterSorted<T> {}
+unsafe impl<T: Ord, A: Allocator> TrustedLen for IntoIterSorted<T, A> {}
 
 /// A draining iterator over the elements of a `BinaryHeap`.
 ///
@@ -1542,12 +1630,24 @@ unsafe impl<T: Ord> TrustedLen for IntoIterSorted<T> {}
 /// [`drain`]: BinaryHeap::drain
 #[stable(feature = "drain", since = "1.6.0")]
 #[derive(Debug)]
-pub struct Drain<'a, T: 'a> {
-    iter: vec::Drain<'a, T>,
+pub struct Drain<
+    'a,
+    T: 'a,
+    #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
+> {
+    iter: vec::Drain<'a, T, A>,
+}
+
+impl<T, A: Allocator> Drain<'_, T, A> {
+    /// Returns a reference to the underlying allocator.
+    #[unstable(feature = "allocator_api", issue = "32838")]
+    pub fn allocator(&self) -> &A {
+        self.iter.allocator()
+    }
 }
 
 #[stable(feature = "drain", since = "1.6.0")]
-impl<T> Iterator for Drain<'_, T> {
+impl<T, A: Allocator> Iterator for Drain<'_, T, A> {
     type Item = T;
 
     #[inline]
@@ -1562,7 +1662,7 @@ impl<T> Iterator for Drain<'_, T> {
 }
 
 #[stable(feature = "drain", since = "1.6.0")]
-impl<T> DoubleEndedIterator for Drain<'_, T> {
+impl<T, A: Allocator> DoubleEndedIterator for Drain<'_, T, A> {
     #[inline]
     fn next_back(&mut self) -> Option<T> {
         self.iter.next_back()
@@ -1570,14 +1670,14 @@ impl<T> DoubleEndedIterator for Drain<'_, T> {
 }
 
 #[stable(feature = "drain", since = "1.6.0")]
-impl<T> ExactSizeIterator for Drain<'_, T> {
+impl<T, A: Allocator> ExactSizeIterator for Drain<'_, T, A> {
     fn is_empty(&self) -> bool {
         self.iter.is_empty()
     }
 }
 
 #[stable(feature = "fused", since = "1.26.0")]
-impl<T> FusedIterator for Drain<'_, T> {}
+impl<T, A: Allocator> FusedIterator for Drain<'_, T, A> {}
 
 /// A draining iterator over the elements of a `BinaryHeap`.
 ///
@@ -1587,17 +1687,29 @@ impl<T> FusedIterator for Drain<'_, T> {}
 /// [`drain_sorted`]: BinaryHeap::drain_sorted
 #[unstable(feature = "binary_heap_drain_sorted", issue = "59278")]
 #[derive(Debug)]
-pub struct DrainSorted<'a, T: Ord> {
-    inner: &'a mut BinaryHeap<T>,
+pub struct DrainSorted<
+    'a,
+    T: Ord,
+    #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
+> {
+    inner: &'a mut BinaryHeap<T, A>,
+}
+
+impl<'a, T: Ord, A: Allocator> DrainSorted<'a, T, A> {
+    /// Returns a reference to the underlying allocator.
+    #[unstable(feature = "allocator_api", issue = "32838")]
+    pub fn allocator(&self) -> &A {
+        self.inner.allocator()
+    }
 }
 
 #[unstable(feature = "binary_heap_drain_sorted", issue = "59278")]
-impl<'a, T: Ord> Drop for DrainSorted<'a, T> {
+impl<'a, T: Ord, A: Allocator> Drop for DrainSorted<'a, T, A> {
     /// Removes heap elements in heap order.
     fn drop(&mut self) {
-        struct DropGuard<'r, 'a, T: Ord>(&'r mut DrainSorted<'a, T>);
+        struct DropGuard<'r, 'a, T: Ord, A: Allocator>(&'r mut DrainSorted<'a, T, A>);
 
-        impl<'r, 'a, T: Ord> Drop for DropGuard<'r, 'a, T> {
+        impl<'r, 'a, T: Ord, A: Allocator> Drop for DropGuard<'r, 'a, T, A> {
             fn drop(&mut self) {
                 while self.0.inner.pop().is_some() {}
             }
@@ -1612,7 +1724,7 @@ impl<'a, T: Ord> Drop for DrainSorted<'a, T> {
 }
 
 #[unstable(feature = "binary_heap_drain_sorted", issue = "59278")]
-impl<T: Ord> Iterator for DrainSorted<'_, T> {
+impl<T: Ord, A: Allocator> Iterator for DrainSorted<'_, T, A> {
     type Item = T;
 
     #[inline]
@@ -1628,20 +1740,20 @@ impl<T: Ord> Iterator for DrainSorted<'_, T> {
 }
 
 #[unstable(feature = "binary_heap_drain_sorted", issue = "59278")]
-impl<T: Ord> ExactSizeIterator for DrainSorted<'_, T> {}
+impl<T: Ord, A: Allocator> ExactSizeIterator for DrainSorted<'_, T, A> {}
 
 #[unstable(feature = "binary_heap_drain_sorted", issue = "59278")]
-impl<T: Ord> FusedIterator for DrainSorted<'_, T> {}
+impl<T: Ord, A: Allocator> FusedIterator for DrainSorted<'_, T, A> {}
 
 #[unstable(feature = "trusted_len", issue = "37572")]
-unsafe impl<T: Ord> TrustedLen for DrainSorted<'_, T> {}
+unsafe impl<T: Ord, A: Allocator> TrustedLen for DrainSorted<'_, T, A> {}
 
 #[stable(feature = "binary_heap_extras_15", since = "1.5.0")]
-impl<T: Ord> From<Vec<T>> for BinaryHeap<T> {
+impl<T: Ord, A: Allocator> From<Vec<T, A>> for BinaryHeap<T, A> {
     /// Converts a `Vec<T>` into a `BinaryHeap<T>`.
     ///
     /// This conversion happens in-place, and has *O*(*n*) time complexity.
-    fn from(vec: Vec<T>) -> BinaryHeap<T> {
+    fn from(vec: Vec<T, A>) -> BinaryHeap<T, A> {
         let mut heap = BinaryHeap { data: vec };
         heap.rebuild();
         heap
@@ -1665,12 +1777,12 @@ impl<T: Ord, const N: usize> From<[T; N]> for BinaryHeap<T> {
 }
 
 #[stable(feature = "binary_heap_extras_15", since = "1.5.0")]
-impl<T> From<BinaryHeap<T>> for Vec<T> {
+impl<T, A: Allocator> From<BinaryHeap<T, A>> for Vec<T, A> {
     /// Converts a `BinaryHeap<T>` into a `Vec<T>`.
     ///
     /// This conversion requires no data movement or allocation, and has
     /// constant time complexity.
-    fn from(heap: BinaryHeap<T>) -> Vec<T> {
+    fn from(heap: BinaryHeap<T, A>) -> Vec<T, A> {
         heap.data
     }
 }
@@ -1683,9 +1795,9 @@ impl<T: Ord> FromIterator<T> for BinaryHeap<T> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T> IntoIterator for BinaryHeap<T> {
+impl<T, A: Allocator> IntoIterator for BinaryHeap<T, A> {
     type Item = T;
-    type IntoIter = IntoIter<T>;
+    type IntoIter = IntoIter<T, A>;
 
     /// Creates a consuming iterator, that is, one that moves each value out of
     /// the binary heap in arbitrary order. The binary heap cannot be used
@@ -1705,13 +1817,13 @@ impl<T> IntoIterator for BinaryHeap<T> {
     ///     println!("{x}");
     /// }
     /// ```
-    fn into_iter(self) -> IntoIter<T> {
+    fn into_iter(self) -> IntoIter<T, A> {
         IntoIter { iter: self.data.into_iter() }
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T> IntoIterator for &'a BinaryHeap<T> {
+impl<'a, T, A: Allocator> IntoIterator for &'a BinaryHeap<T, A> {
     type Item = &'a T;
     type IntoIter = Iter<'a, T>;
 
@@ -1721,7 +1833,7 @@ impl<'a, T> IntoIterator for &'a BinaryHeap<T> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: Ord> Extend<T> for BinaryHeap<T> {
+impl<T: Ord, A: Allocator> Extend<T> for BinaryHeap<T, A> {
     #[inline]
     fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
         let guard = RebuildOnDrop { rebuild_from: self.len(), heap: self };
@@ -1740,7 +1852,7 @@ impl<T: Ord> Extend<T> for BinaryHeap<T> {
 }
 
 #[stable(feature = "extend_ref", since = "1.2.0")]
-impl<'a, T: 'a + Ord + Copy> Extend<&'a T> for BinaryHeap<T> {
+impl<'a, T: 'a + Ord + Copy, A: Allocator> Extend<&'a T> for BinaryHeap<T, A> {
     fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
         self.extend(iter.into_iter().cloned());
     }
diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs
index e753647ff78..c6f43857887 100644
--- a/library/core/src/ptr/mut_ptr.rs
+++ b/library/core/src/ptr/mut_ptr.rs
@@ -106,7 +106,7 @@ impl<T: ?Sized> *mut T {
     /// with [`cast_mut`] on `*const T` and may have documentation value if used instead of implicit
     /// coercion.
     ///
-    /// [`cast_mut`]: pointer::cast_mut
+    /// [`cast_mut`]: #method.cast_mut
     #[stable(feature = "ptr_const_cast", since = "1.65.0")]
     #[rustc_const_stable(feature = "ptr_const_cast", since = "1.65.0")]
     #[inline(always)]
@@ -117,7 +117,7 @@ impl<T: ?Sized> *mut T {
     /// Casts a pointer to its raw bits.
     ///
     /// This is equivalent to `as usize`, but is more specific to enhance readability.
-    /// The inverse method is [`from_bits`](pointer#method.from_bits-1).
+    /// The inverse method is [`from_bits`](#method.from_bits-1).
     ///
     /// In particular, `*p as usize` and `p as usize` will both compile for
     /// pointers to numeric types but do very different things, so using this
@@ -153,7 +153,7 @@ impl<T: ?Sized> *mut T {
     /// Creates a pointer from its raw bits.
     ///
     /// This is equivalent to `as *mut T`, but is more specific to enhance readability.
-    /// The inverse method is [`to_bits`](pointer#method.to_bits-1).
+    /// The inverse method is [`to_bits`](#method.to_bits-1).
     ///
     /// # Examples
     ///
@@ -303,7 +303,7 @@ impl<T: ?Sized> *mut T {
     ///
     /// For the mutable counterpart see [`as_mut`].
     ///
-    /// [`as_uninit_ref`]: pointer#method.as_uninit_ref-1
+    /// [`as_uninit_ref`]: #method.as_uninit_ref-1
     /// [`as_mut`]: #method.as_mut
     ///
     /// # Safety
@@ -369,7 +369,7 @@ impl<T: ?Sized> *mut T {
     ///
     /// For the mutable counterpart see [`as_uninit_mut`].
     ///
-    /// [`as_ref`]: pointer#method.as_ref-1
+    /// [`as_ref`]: #method.as_ref-1
     /// [`as_uninit_mut`]: #method.as_uninit_mut
     ///
     /// # Safety
@@ -624,7 +624,7 @@ impl<T: ?Sized> *mut T {
     /// For the shared counterpart see [`as_ref`].
     ///
     /// [`as_uninit_mut`]: #method.as_uninit_mut
-    /// [`as_ref`]: pointer#method.as_ref-1
+    /// [`as_ref`]: #method.as_ref-1
     ///
     /// # Safety
     ///
@@ -689,7 +689,7 @@ impl<T: ?Sized> *mut T {
     /// For the shared counterpart see [`as_uninit_ref`].
     ///
     /// [`as_mut`]: #method.as_mut
-    /// [`as_uninit_ref`]: pointer#method.as_uninit_ref-1
+    /// [`as_uninit_ref`]: #method.as_uninit_ref-1
     ///
     /// # Safety
     ///
@@ -779,7 +779,7 @@ impl<T: ?Sized> *mut T {
     ///
     /// This function is the inverse of [`offset`].
     ///
-    /// [`offset`]: pointer#method.offset-1
+    /// [`offset`]: #method.offset-1
     ///
     /// # Safety
     ///
@@ -2051,7 +2051,7 @@ impl<T> *mut [T] {
     ///
     /// For the mutable counterpart see [`as_uninit_slice_mut`].
     ///
-    /// [`as_ref`]: pointer#method.as_ref-1
+    /// [`as_ref`]: #method.as_ref-1
     /// [`as_uninit_slice_mut`]: #method.as_uninit_slice_mut
     ///
     /// # Safety
diff --git a/library/std/src/sys/windows/c/windows_sys.rs b/library/std/src/sys/windows/c/windows_sys.rs
index 8c8b006a1d3..a4294f336fe 100644
--- a/library/std/src/sys/windows/c/windows_sys.rs
+++ b/library/std/src/sys/windows/c/windows_sys.rs
@@ -4275,3 +4275,23 @@ impl ::core::clone::Clone for XSAVE_FORMAT {
         *self
     }
 }
+// Begin of ARM32 shim
+// The raw content of this file should be processed by `generate-windows-sys`
+// to be merged with the generated binding. It is not supposed to be used as
+// a normal Rust module.
+cfg_if::cfg_if! {
+if #[cfg(target_arch = "arm")] {
+#[repr(C)]
+pub struct WSADATA {
+    pub wVersion: u16,
+    pub wHighVersion: u16,
+    pub szDescription: [u8; 257],
+    pub szSystemStatus: [u8; 129],
+    pub iMaxSockets: u16,
+    pub iMaxUdpDg: u16,
+    pub lpVendorInfo: PSTR,
+}
+pub enum CONTEXT {}
+}
+}
+// End of ARM32 shim
diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs
index d9973185bc4..1230bb5deed 100644
--- a/library/std/src/thread/mod.rs
+++ b/library/std/src/thread/mod.rs
@@ -195,7 +195,7 @@ mod local;
 
 cfg_if::cfg_if! {
     if #[cfg(test)] {
-        // Avoid duplicating the global state assoicated with thread-locals between this crate and
+        // Avoid duplicating the global state associated with thread-locals between this crate and
         // realstd. Miri relies on this.
         pub use realstd::thread::{local_impl, AccessError, LocalKey};
     } else {
diff --git a/src/bootstrap/render_tests.rs b/src/bootstrap/render_tests.rs
index 06ab820953d..98a468c883d 100644
--- a/src/bootstrap/render_tests.rs
+++ b/src/bootstrap/render_tests.rs
@@ -7,7 +7,7 @@
 //! to reimplement all the rendering logic in this module because of that.
 
 use crate::builder::Builder;
-use std::io::{BufRead, BufReader, Write};
+use std::io::{BufRead, BufReader, Read, Write};
 use std::process::{ChildStdout, Command, Stdio};
 use std::time::Duration;
 use termcolor::{Color, ColorSpec, WriteColor};
@@ -20,15 +20,15 @@ pub(crate) fn add_flags_and_try_run_tests(builder: &Builder<'_>, cmd: &mut Comma
     }
     cmd.args(&["-Z", "unstable-options", "--format", "json"]);
 
-    try_run_tests(builder, cmd)
+    try_run_tests(builder, cmd, false)
 }
 
-pub(crate) fn try_run_tests(builder: &Builder<'_>, cmd: &mut Command) -> bool {
+pub(crate) fn try_run_tests(builder: &Builder<'_>, cmd: &mut Command, stream: bool) -> bool {
     if builder.config.dry_run() {
         return true;
     }
 
-    if !run_tests(builder, cmd) {
+    if !run_tests(builder, cmd, stream) {
         if builder.fail_fast {
             crate::detail_exit_macro!(1);
         } else {
@@ -41,7 +41,7 @@ pub(crate) fn try_run_tests(builder: &Builder<'_>, cmd: &mut Command) -> bool {
     }
 }
 
-fn run_tests(builder: &Builder<'_>, cmd: &mut Command) -> bool {
+fn run_tests(builder: &Builder<'_>, cmd: &mut Command, stream: bool) -> bool {
     cmd.stdout(Stdio::piped());
 
     builder.verbose(&format!("running: {cmd:?}"));
@@ -50,7 +50,12 @@ fn run_tests(builder: &Builder<'_>, cmd: &mut Command) -> bool {
 
     // This runs until the stdout of the child is closed, which means the child exited. We don't
     // run this on another thread since the builder is not Sync.
-    Renderer::new(process.stdout.take().unwrap(), builder).render_all();
+    let renderer = Renderer::new(process.stdout.take().unwrap(), builder);
+    if stream {
+        renderer.stream_all();
+    } else {
+        renderer.render_all();
+    }
 
     let result = process.wait_with_output().unwrap();
     if !result.status.success() && builder.is_verbose() {
@@ -112,6 +117,23 @@ impl<'a> Renderer<'a> {
         }
     }
 
+    /// Renders the stdout characters one by one
+    fn stream_all(mut self) {
+        let mut buffer = [0; 1];
+        loop {
+            match self.stdout.read(&mut buffer) {
+                Ok(0) => break,
+                Ok(_) => {
+                    let mut stdout = std::io::stdout();
+                    stdout.write_all(&buffer).unwrap();
+                    let _ = stdout.flush();
+                }
+                Err(err) if err.kind() == std::io::ErrorKind::UnexpectedEof => break,
+                Err(err) => panic!("failed to read output of test runner: {err}"),
+            }
+        }
+    }
+
     fn render_test_outcome(&mut self, outcome: Outcome<'_>, test: &TestOutcome) {
         self.executed_tests += 1;
 
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index f31ba946099..cde77f4720b 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -1035,7 +1035,7 @@ impl Step for RustdocGUI {
         }
 
         let _time = util::timeit(&builder);
-        crate::render_tests::try_run_tests(builder, &mut cmd);
+        crate::render_tests::try_run_tests(builder, &mut cmd, true);
     }
 }
 
@@ -1732,7 +1732,7 @@ note: if you're sure you want to do this, please open an issue as to why. In the
             suite, mode, &compiler.host, target
         ));
         let _time = util::timeit(&builder);
-        crate::render_tests::try_run_tests(builder, &mut cmd);
+        crate::render_tests::try_run_tests(builder, &mut cmd, false);
 
         if let Some(compare_mode) = compare_mode {
             cmd.arg("--compare-mode").arg(compare_mode);
@@ -1755,7 +1755,7 @@ note: if you're sure you want to do this, please open an issue as to why. In the
                 suite, mode, compare_mode, &compiler.host, target
             ));
             let _time = util::timeit(&builder);
-            crate::render_tests::try_run_tests(builder, &mut cmd);
+            crate::render_tests::try_run_tests(builder, &mut cmd, false);
         }
     }
 }
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index baffee0964d..f205ff15ec3 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -53,15 +53,12 @@ use rustc_data_structures::captures::Captures;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_hir::def_id::{DefId, DefIdSet};
 use rustc_hir::Mutability;
-use rustc_infer::infer::TyCtxtInferExt;
-use rustc_infer::traits::{Obligation, ObligationCause};
 use rustc_middle::middle::stability;
-use rustc_middle::ty::{ParamEnv, TyCtxt};
+use rustc_middle::ty::TyCtxt;
 use rustc_span::{
     symbol::{sym, Symbol},
     BytePos, FileName, RealFileName,
 };
-use rustc_trait_selection::traits::ObligationCtxt;
 use serde::ser::{SerializeMap, SerializeSeq};
 use serde::{Serialize, Serializer};
 
@@ -1115,47 +1112,15 @@ fn render_assoc_items<'a, 'cx: 'a>(
     containing_item: &'a clean::Item,
     it: DefId,
     what: AssocItemRender<'a>,
-    aliased_type: Option<DefId>,
 ) -> impl fmt::Display + 'a + Captures<'cx> {
     let mut derefs = DefIdSet::default();
     derefs.insert(it);
     display_fn(move |f| {
-        render_assoc_items_inner(f, cx, containing_item, it, what, &mut derefs, aliased_type);
+        render_assoc_items_inner(f, cx, containing_item, it, what, &mut derefs);
         Ok(())
     })
 }
 
-/// Check whether `impl_def_id` may apply to *some instantiation* of `item_def_id`.
-fn is_valid_impl_for(tcx: TyCtxt<'_>, item_def_id: DefId, impl_def_id: DefId) -> bool {
-    let infcx = tcx.infer_ctxt().intercrate(true).build();
-    let ocx = ObligationCtxt::new(&infcx);
-    let param_env = ParamEnv::empty();
-
-    let alias_substs = infcx.fresh_substs_for_item(rustc_span::DUMMY_SP, item_def_id);
-    let alias_ty = tcx.type_of(item_def_id).subst(tcx, alias_substs);
-    let alias_bounds = tcx.predicates_of(item_def_id).instantiate(tcx, alias_substs);
-
-    let impl_substs = infcx.fresh_substs_for_item(rustc_span::DUMMY_SP, impl_def_id);
-    let impl_self_ty = tcx.type_of(impl_def_id).subst(tcx, impl_substs);
-    let impl_bounds = tcx.predicates_of(impl_def_id).instantiate(tcx, impl_substs);
-
-    if ocx.eq(&ObligationCause::dummy(), param_env, impl_self_ty, alias_ty).is_err() {
-        return false;
-    }
-    ocx.register_obligations(
-        alias_bounds
-            .iter()
-            .chain(impl_bounds)
-            .map(|(p, _)| Obligation::new(tcx, ObligationCause::dummy(), param_env, p)),
-    );
-
-    let errors = ocx.select_where_possible();
-    errors.is_empty()
-}
-
-// If `aliased_type` is `Some`, it means `it` is a type alias and `aliased_type` is the "actual"
-// type aliased behind `it`. It is used to check whether or not the implementation of the aliased
-// type can be displayed on the alias doc page.
 fn render_assoc_items_inner(
     mut w: &mut dyn fmt::Write,
     cx: &mut Context<'_>,
@@ -1163,28 +1128,12 @@ fn render_assoc_items_inner(
     it: DefId,
     what: AssocItemRender<'_>,
     derefs: &mut DefIdSet,
-    aliased_type: Option<DefId>,
 ) {
     info!("Documenting associated items of {:?}", containing_item.name);
     let shared = Rc::clone(&cx.shared);
     let cache = &shared.cache;
-    let empty = Vec::new();
-    let v = match cache.impls.get(&it) {
-        Some(v) => v,
-        None => &empty,
-    };
-    let v2 = match aliased_type {
-        Some(aliased_type) => cache.impls.get(&aliased_type).unwrap_or(&empty),
-        None => &empty,
-    };
-    if v.is_empty() && v2.is_empty() {
-        return;
-    }
-    let mut saw_impls = FxHashSet::default();
-    let (non_trait, traits): (Vec<_>, _) =
-        v.iter().chain(v2).partition(|i| i.inner_impl().trait_.is_none());
-    let tcx = cx.tcx();
-    let is_alias = aliased_type.is_some();
+    let Some(v) = cache.impls.get(&it) else { return };
+    let (non_trait, traits): (Vec<_>, _) = v.iter().partition(|i| i.inner_impl().trait_.is_none());
     if !non_trait.is_empty() {
         let mut tmp_buf = Buffer::html();
         let (render_mode, id, class_html) = match what {
@@ -1216,12 +1165,6 @@ fn render_assoc_items_inner(
         };
         let mut impls_buf = Buffer::html();
         for i in &non_trait {
-            if !saw_impls.insert(i.def_id()) {
-                continue;
-            }
-            if is_alias && !is_valid_impl_for(tcx, it, i.def_id()) {
-                continue;
-            }
             render_impl(
                 &mut impls_buf,
                 cx,
@@ -1250,14 +1193,9 @@ fn render_assoc_items_inner(
     if !traits.is_empty() {
         let deref_impl =
             traits.iter().find(|t| t.trait_did() == cx.tcx().lang_items().deref_trait());
-        if let Some(impl_) = deref_impl &&
-            (!is_alias || is_valid_impl_for(tcx, it, impl_.def_id()))
-        {
+        if let Some(impl_) = deref_impl {
             let has_deref_mut =
-                traits.iter().any(|t| {
-                    t.trait_did() == cx.tcx().lang_items().deref_mut_trait() &&
-                    (!is_alias || is_valid_impl_for(tcx, it, t.def_id()))
-                });
+                traits.iter().any(|t| t.trait_did() == cx.tcx().lang_items().deref_mut_trait());
             render_deref_methods(&mut w, cx, impl_, containing_item, has_deref_mut, derefs);
         }
 
@@ -1267,14 +1205,10 @@ fn render_assoc_items_inner(
             return;
         }
 
-        let (synthetic, concrete): (Vec<&Impl>, Vec<&Impl>) = traits
-            .into_iter()
-            .filter(|t| saw_impls.insert(t.def_id()))
-            .partition(|t| t.inner_impl().kind.is_auto());
-        let (blanket_impl, concrete): (Vec<&Impl>, _) = concrete
-            .into_iter()
-            .filter(|t| !is_alias || is_valid_impl_for(tcx, it, t.def_id()))
-            .partition(|t| t.inner_impl().kind.is_blanket());
+        let (synthetic, concrete): (Vec<&Impl>, Vec<&Impl>) =
+            traits.into_iter().partition(|t| t.inner_impl().kind.is_auto());
+        let (blanket_impl, concrete): (Vec<&Impl>, _) =
+            concrete.into_iter().partition(|t| t.inner_impl().kind.is_blanket());
 
         render_all_impls(w, cx, containing_item, &concrete, &synthetic, &blanket_impl);
     }
@@ -1313,10 +1247,10 @@ fn render_deref_methods(
                 return;
             }
         }
-        render_assoc_items_inner(&mut w, cx, container_item, did, what, derefs, None);
+        render_assoc_items_inner(&mut w, cx, container_item, did, what, derefs);
     } else if let Some(prim) = target.primitive_type() {
         if let Some(&did) = cache.primitive_locations.get(&prim) {
-            render_assoc_items_inner(&mut w, cx, container_item, did, what, derefs, None);
+            render_assoc_items_inner(&mut w, cx, container_item, did, what, derefs);
         }
     }
 }
diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs
index 02cfad6b346..383e3c17088 100644
--- a/src/librustdoc/html/render/print_item.rs
+++ b/src/librustdoc/html/render/print_item.rs
@@ -129,7 +129,7 @@ macro_rules! item_template_methods {
             display_fn(move |f| {
                 let (item, mut cx) = self.item_and_mut_cx();
                 let def_id = item.item_id.expect_def_id();
-                let v = render_assoc_items(*cx, item, def_id, AssocItemRender::All, None);
+                let v = render_assoc_items(*cx, item, def_id, AssocItemRender::All);
                 write!(f, "{v}")
             })
         }
@@ -953,11 +953,7 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean:
     }
 
     // If there are methods directly on this trait object, render them here.
-    write!(
-        w,
-        "{}",
-        render_assoc_items(cx, it, it.item_id.expect_def_id(), AssocItemRender::All, None)
-    );
+    write!(w, "{}", render_assoc_items(cx, it, it.item_id.expect_def_id(), AssocItemRender::All));
 
     let cloned_shared = Rc::clone(&cx.shared);
     let cache = &cloned_shared.cache;
@@ -1189,12 +1185,8 @@ fn item_trait_alias(
     // won't be visible anywhere in the docs. It would be nice to also show
     // associated items from the aliased type (see discussion in #32077), but
     // we need #14072 to make sense of the generics.
-    write!(
-        w,
-        "{}",
-        render_assoc_items(cx, it, it.item_id.expect_def_id(), AssocItemRender::All, None)
-    )
-    .unwrap();
+    write!(w, "{}", render_assoc_items(cx, it, it.item_id.expect_def_id(), AssocItemRender::All))
+        .unwrap();
 }
 
 fn item_opaque_ty(
@@ -1222,12 +1214,8 @@ fn item_opaque_ty(
     // won't be visible anywhere in the docs. It would be nice to also show
     // associated items from the aliased type (see discussion in #32077), but
     // we need #14072 to make sense of the generics.
-    write!(
-        w,
-        "{}",
-        render_assoc_items(cx, it, it.item_id.expect_def_id(), AssocItemRender::All, None)
-    )
-    .unwrap();
+    write!(w, "{}", render_assoc_items(cx, it, it.item_id.expect_def_id(), AssocItemRender::All))
+        .unwrap();
 }
 
 fn item_typedef(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean::Typedef) {
@@ -1251,11 +1239,11 @@ fn item_typedef(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clea
     write!(w, "{}", document(cx, it, None, HeadingOffset::H2));
 
     let def_id = it.item_id.expect_def_id();
-    write!(
-        w,
-        "{}",
-        render_assoc_items(cx, it, def_id, AssocItemRender::All, t.type_.def_id(&cx.cache()))
-    );
+    // Render any items associated directly to this alias, as otherwise they
+    // won't be visible anywhere in the docs. It would be nice to also show
+    // associated items from the aliased type (see discussion in #32077), but
+    // we need #14072 to make sense of the generics.
+    write!(w, "{}", render_assoc_items(cx, it, def_id, AssocItemRender::All));
     write!(w, "{}", document_type_layout(cx, def_id));
 }
 
@@ -1494,7 +1482,7 @@ fn item_enum(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, e: &clean::
         write!(w, "</div>");
     }
     let def_id = it.item_id.expect_def_id();
-    write!(w, "{}", render_assoc_items(cx, it, def_id, AssocItemRender::All, None));
+    write!(w, "{}", render_assoc_items(cx, it, def_id, AssocItemRender::All));
     write!(w, "{}", document_type_layout(cx, def_id));
 }
 
@@ -1537,7 +1525,7 @@ fn item_primitive(w: &mut impl fmt::Write, cx: &mut Context<'_>, it: &clean::Ite
     let def_id = it.item_id.expect_def_id();
     write!(w, "{}", document(cx, it, None, HeadingOffset::H2)).unwrap();
     if it.name.map(|n| n.as_str() != "reference").unwrap_or(false) {
-        write!(w, "{}", render_assoc_items(cx, it, def_id, AssocItemRender::All, None)).unwrap();
+        write!(w, "{}", render_assoc_items(cx, it, def_id, AssocItemRender::All)).unwrap();
     } else {
         // We handle the "reference" primitive type on its own because we only want to list
         // implementations on generic types.
@@ -1642,7 +1630,7 @@ fn item_struct(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, s: &clean
         }
     }
     let def_id = it.item_id.expect_def_id();
-    write!(w, "{}", render_assoc_items(cx, it, def_id, AssocItemRender::All, None));
+    write!(w, "{}", render_assoc_items(cx, it, def_id, AssocItemRender::All));
     write!(w, "{}", document_type_layout(cx, def_id));
 }
 
@@ -1677,12 +1665,8 @@ fn item_foreign_type(w: &mut impl fmt::Write, cx: &mut Context<'_>, it: &clean::
     });
 
     write!(w, "{}", document(cx, it, None, HeadingOffset::H2)).unwrap();
-    write!(
-        w,
-        "{}",
-        render_assoc_items(cx, it, it.item_id.expect_def_id(), AssocItemRender::All, None)
-    )
-    .unwrap();
+    write!(w, "{}", render_assoc_items(cx, it, it.item_id.expect_def_id(), AssocItemRender::All))
+        .unwrap();
 }
 
 fn item_keyword(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item) {
diff --git a/src/tools/generate-windows-sys/src/arm_shim.rs b/src/tools/generate-windows-sys/src/arm_shim.rs
new file mode 100644
index 00000000000..17c2ccb223c
--- /dev/null
+++ b/src/tools/generate-windows-sys/src/arm_shim.rs
@@ -0,0 +1,20 @@
+// Begin of ARM32 shim
+// The raw content of this file should be processed by `generate-windows-sys`
+// to be merged with the generated binding. It is not supposed to be used as
+// a normal Rust module.
+cfg_if::cfg_if! {
+if #[cfg(target_arch = "arm")] {
+#[repr(C)]
+pub struct WSADATA {
+    pub wVersion: u16,
+    pub wHighVersion: u16,
+    pub szDescription: [u8; 257],
+    pub szSystemStatus: [u8; 129],
+    pub iMaxSockets: u16,
+    pub iMaxUdpDg: u16,
+    pub lpVendorInfo: PSTR,
+}
+pub enum CONTEXT {}
+}
+}
+// End of ARM32 shim
diff --git a/src/tools/generate-windows-sys/src/main.rs b/src/tools/generate-windows-sys/src/main.rs
index 91d981462e8..65e480715ee 100644
--- a/src/tools/generate-windows-sys/src/main.rs
+++ b/src/tools/generate-windows-sys/src/main.rs
@@ -11,6 +11,9 @@ const PRELUDE: &str = r#"// This file is autogenerated.
 // ignore-tidy-filelength
 "#;
 
+/// This is a shim for the ARM (32-bit) architecture, which is no longer supported by windows-rs.
+const ARM_SHIM: &str = include_str!("arm_shim.rs");
+
 fn main() -> io::Result<()> {
     let mut path: PathBuf =
         std::env::args_os().nth(1).expect("a path to the rust repository is required").into();
@@ -32,6 +35,7 @@ fn main() -> io::Result<()> {
     let mut f = std::fs::File::create(&path)?;
     f.write_all(PRELUDE.as_bytes())?;
     f.write_all(bindings.as_bytes())?;
+    f.write_all(ARM_SHIM.as_bytes())?;
 
     Ok(())
 }
diff --git a/tests/rustdoc-gui/headers-color.goml b/tests/rustdoc-gui/headers-color.goml
index 7d83833a8bd..a7ac94c4943 100644
--- a/tests/rustdoc-gui/headers-color.goml
+++ b/tests/rustdoc-gui/headers-color.goml
@@ -42,29 +42,29 @@ call-function: (
     "check-colors",
     {
         "theme": "ayu",
-        "color": "rgb(197, 197, 197)",
-        "code_header_color": "rgb(230, 225, 207)",
+        "color": "#c5c5c5",
+        "code_header_color": "#e6e1cf",
         "focus_background_color": "rgba(255, 236, 164, 0.06)",
-        "headings_color": "rgb(57, 175, 215)",
+        "headings_color": "#39afd7",
     },
 )
 call-function: (
     "check-colors",
     {
         "theme": "dark",
-        "color": "rgb(221, 221, 221)",
-        "code_header_color": "rgb(221, 221, 221)",
-        "focus_background_color": "rgb(73, 74, 61)",
-        "headings_color": "rgb(210, 153, 29)",
+        "color": "#ddd",
+        "code_header_color": "#ddd",
+        "focus_background_color": "#494a3d",
+        "headings_color": "#d2991d",
     },
 )
 call-function: (
     "check-colors",
     {
         "theme": "light",
-        "color": "rgb(0, 0, 0)",
-        "code_header_color": "rgb(0, 0, 0)",
-        "focus_background_color": "rgb(253, 255, 211)",
-        "headings_color": "rgb(56, 115, 173)",
+        "color": "black",
+        "code_header_color": "black",
+        "focus_background_color": "#fdffd3",
+        "headings_color": "#3873ad",
     },
 )
diff --git a/tests/rustdoc/issue-112515-impl-ty-alias.rs b/tests/rustdoc/issue-112515-impl-ty-alias.rs
new file mode 100644
index 00000000000..161188ee576
--- /dev/null
+++ b/tests/rustdoc/issue-112515-impl-ty-alias.rs
@@ -0,0 +1,30 @@
+// Regression test for <https://github.com/rust-lang/rust/issues/112515>.
+// It's to ensure that this code doesn't have infinite loop in rustdoc when
+// trying to retrive type alias implementations.
+
+// ignore-tidy-linelength
+
+pub type Boom = S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<u64, u8>, ()>, ()>, ()>, u8>, ()>, u8>, ()>, u8>, u8>, ()>, ()>, ()>, u8>, u8>, u8>, ()>, ()>, u8>, ()>, ()>, ()>, u8>, u8>, ()>, ()>, ()>, ()>, ()>, u8>, ()>, ()>, u8>, ()>, ()>, ()>, u8>, ()>, ()>, u8>, u8>, u8>, u8>, ()>, u8>, ()>, ()>, ()>, ()>, ()>, ()>, ()>, ()>, ()>, ()>, ()>, ()>, ()>, ()>, ()>, ()>, ()>, ()>, ()>;
+pub struct S<T, U>(T, U);
+
+pub trait A {}
+
+pub trait B<T> {
+    type P;
+}
+
+impl A for u64 {}
+
+impl<T, U> A for S<T, U> {}
+
+impl<T> B<u8> for S<T, ()>
+where
+    T: B<u8>,
+    <T as B<u8>>::P: A,
+{
+    type P = ();
+}
+
+impl<T: A, U, V> B<T> for S<U, V> {
+    type P = ();
+}
diff --git a/tests/rustdoc/issue-32077-type-alias-impls.rs b/tests/rustdoc/issue-32077-type-alias-impls.rs
deleted file mode 100644
index 555d0579bee..00000000000
--- a/tests/rustdoc/issue-32077-type-alias-impls.rs
+++ /dev/null
@@ -1,59 +0,0 @@
-// Regression test for <https://github.com/rust-lang/rust/issues/32077>.
-
-#![crate_name = "foo"]
-
-pub struct GenericStruct<T>(T);
-
-impl<T> GenericStruct<T> {
-    pub fn on_gen(arg: T) {}
-}
-
-impl GenericStruct<u32> {
-    pub fn on_u32(arg: u32) {}
-}
-
-pub trait Foo {}
-pub trait Bar {}
-
-impl<T> Foo for GenericStruct<T> {}
-impl Bar for GenericStruct<u32> {}
-
-// @has 'foo/type.TypedefStruct.html'
-// We check that we have the implementation of the type alias itself.
-// @has - '//*[@id="impl-TypedefStruct"]/h3' 'impl TypedefStruct'
-// @has - '//*[@id="method.on_alias"]/h4' 'pub fn on_alias()'
-// @has - '//*[@id="impl-GenericStruct%3CT%3E"]/h3' 'impl<T> GenericStruct<T>'
-// @has - '//*[@id="method.on_gen"]/h4' 'pub fn on_gen(arg: T)'
-// @has - '//*[@id="impl-Foo-for-GenericStruct%3CT%3E"]/h3' 'impl<T> Foo for GenericStruct<T>'
-// This trait implementation doesn't match the type alias parameters so shouldn't appear in docs.
-// @!has - '//h3' 'impl Bar for GenericStruct<u32> {}'
-// Same goes for the `Deref` impl.
-// @!has - '//h2' 'Methods from Deref<Target = u32>'
-pub type TypedefStruct = GenericStruct<u8>;
-
-impl TypedefStruct {
-    pub fn on_alias() {}
-}
-
-impl std::ops::Deref for GenericStruct<u32> {
-    type Target = u32;
-
-    fn deref(&self) -> &Self::Target {
-        &self.0
-    }
-}
-
-pub struct Wrap<T>(GenericStruct<T>);
-
-// @has 'foo/type.Alias.html'
-// @has - '//h2' 'Methods from Deref<Target = u32>'
-// @has - '//*[@id="impl-Deref-for-Wrap%3CT%3E"]/h3' 'impl<T> Deref for Wrap<T>'
-pub type Alias = Wrap<u32>;
-
-impl<T> std::ops::Deref for Wrap<T> {
-    type Target = GenericStruct<T>;
-
-    fn deref(&self) -> &Self::Target {
-        &self.0
-    }
-}
diff --git a/tests/ui/associated-inherent-types/private-in-public.rs b/tests/ui/associated-inherent-types/private-in-public.rs
index a4b372537c7..44a20a79ad6 100644
--- a/tests/ui/associated-inherent-types/private-in-public.rs
+++ b/tests/ui/associated-inherent-types/private-in-public.rs
@@ -3,6 +3,11 @@
 #![crate_type = "lib"]
 
 #![deny(private_in_public)]
+#![warn(private_interfaces)]
+
+// In this test both old and new private-in-public diagnostic were emitted.
+// Old diagnostic will be deleted soon.
+// See https://rust-lang.github.io/rfcs/2145-type-privacy.html.
 
 pub type PubAlias0 = PubTy::PrivAssocTy;
 //~^ ERROR private associated type `PubTy::PrivAssocTy` in public interface (error E0446)
diff --git a/tests/ui/associated-inherent-types/private-in-public.stderr b/tests/ui/associated-inherent-types/private-in-public.stderr
index f0a64e96179..d40db83707b 100644
--- a/tests/ui/associated-inherent-types/private-in-public.stderr
+++ b/tests/ui/associated-inherent-types/private-in-public.stderr
@@ -1,5 +1,5 @@
 error: private associated type `PubTy::PrivAssocTy` in public interface (error E0446)
-  --> $DIR/private-in-public.rs:7:1
+  --> $DIR/private-in-public.rs:12:1
    |
 LL | pub type PubAlias0 = PubTy::PrivAssocTy;
    | ^^^^^^^^^^^^^^^^^^
@@ -12,8 +12,26 @@ note: the lint level is defined here
 LL | #![deny(private_in_public)]
    |         ^^^^^^^^^^^^^^^^^
 
+warning: associated type `PubTy::PrivAssocTy` is more private than the item `PubAlias0`
+   |
+note: type alias `PubAlias0` is reachable at visibility `pub`
+  --> $DIR/private-in-public.rs:12:1
+   |
+LL | pub type PubAlias0 = PubTy::PrivAssocTy;
+   | ^^^^^^^^^^^^^^^^^^
+note: but associated type `PubTy::PrivAssocTy` is only usable at visibility `pub(crate)`
+  --> $DIR/private-in-public.rs:24:5
+   |
+LL |     type PrivAssocTy = ();
+   |     ^^^^^^^^^^^^^^^^
+note: the lint level is defined here
+  --> $DIR/private-in-public.rs:6:9
+   |
+LL | #![warn(private_interfaces)]
+   |         ^^^^^^^^^^^^^^^^^^
+
 error: private type `PrivTy` in public interface (error E0446)
-  --> $DIR/private-in-public.rs:10:1
+  --> $DIR/private-in-public.rs:15:1
    |
 LL | pub type PubAlias1 = PrivTy::PubAssocTy;
    | ^^^^^^^^^^^^^^^^^^
@@ -21,8 +39,21 @@ LL | pub type PubAlias1 = PrivTy::PubAssocTy;
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
 
+warning: type `PrivTy` is more private than the item `PubAlias1`
+   |
+note: type alias `PubAlias1` is reachable at visibility `pub`
+  --> $DIR/private-in-public.rs:15:1
+   |
+LL | pub type PubAlias1 = PrivTy::PubAssocTy;
+   | ^^^^^^^^^^^^^^^^^^
+note: but type `PrivTy` is only usable at visibility `pub(crate)`
+  --> $DIR/private-in-public.rs:28:1
+   |
+LL | struct PrivTy;
+   | ^^^^^^^^^^^^^
+
 error: private type `PrivTy` in public interface (error E0446)
-  --> $DIR/private-in-public.rs:13:1
+  --> $DIR/private-in-public.rs:18:1
    |
 LL | pub type PubAlias2 = PubTy::PubAssocTy<PrivTy>;
    | ^^^^^^^^^^^^^^^^^^
@@ -30,5 +61,18 @@ LL | pub type PubAlias2 = PubTy::PubAssocTy<PrivTy>;
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
 
-error: aborting due to 3 previous errors
+warning: type `PrivTy` is more private than the item `PubAlias2`
+   |
+note: type alias `PubAlias2` is reachable at visibility `pub`
+  --> $DIR/private-in-public.rs:18:1
+   |
+LL | pub type PubAlias2 = PubTy::PubAssocTy<PrivTy>;
+   | ^^^^^^^^^^^^^^^^^^
+note: but type `PrivTy` is only usable at visibility `pub(crate)`
+  --> $DIR/private-in-public.rs:28:1
+   |
+LL | struct PrivTy;
+   | ^^^^^^^^^^^^^
+
+error: aborting due to 3 previous errors; 3 warnings emitted
 
diff --git a/tests/ui/const-generics/generic_const_exprs/eval-privacy.rs b/tests/ui/const-generics/generic_const_exprs/eval-privacy.rs
index 8023b998a40..96b769699cc 100644
--- a/tests/ui/const-generics/generic_const_exprs/eval-privacy.rs
+++ b/tests/ui/const-generics/generic_const_exprs/eval-privacy.rs
@@ -2,6 +2,12 @@
 #![feature(generic_const_exprs)]
 #![allow(incomplete_features)]
 
+#![warn(private_interfaces)]
+
+// In this test both old and new private-in-public diagnostic were emitted.
+// Old diagnostic will be deleted soon.
+// See https://rust-lang.github.io/rfcs/2145-type-privacy.html.
+
 pub struct Const<const U: u8>;
 
 pub trait Trait {
diff --git a/tests/ui/const-generics/generic_const_exprs/eval-privacy.stderr b/tests/ui/const-generics/generic_const_exprs/eval-privacy.stderr
index 2d9de8805bb..465621619b4 100644
--- a/tests/ui/const-generics/generic_const_exprs/eval-privacy.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/eval-privacy.stderr
@@ -1,5 +1,5 @@
 error[E0446]: private type `fn(u8) -> u8 {my_const_fn}` in public interface
-  --> $DIR/eval-privacy.rs:16:5
+  --> $DIR/eval-privacy.rs:22:5
    |
 LL |     type AssocTy = Const<{ my_const_fn(U) }>;
    |     ^^^^^^^^^^^^ can't leak private type
@@ -7,6 +7,24 @@ LL |     type AssocTy = Const<{ my_const_fn(U) }>;
 LL | const fn my_const_fn(val: u8) -> u8 {
    | ----------------------------------- `fn(u8) -> u8 {my_const_fn}` declared as private
 
-error: aborting due to previous error
+warning: type `fn(u8) -> u8 {my_const_fn}` is more private than the item `<Const<U> as Trait>::AssocTy`
+   |
+note: associated type `<Const<U> as Trait>::AssocTy` is reachable at visibility `pub`
+  --> $DIR/eval-privacy.rs:22:5
+   |
+LL |     type AssocTy = Const<{ my_const_fn(U) }>;
+   |     ^^^^^^^^^^^^
+note: but type `fn(u8) -> u8 {my_const_fn}` is only usable at visibility `pub(crate)`
+  --> $DIR/eval-privacy.rs:29:1
+   |
+LL | const fn my_const_fn(val: u8) -> u8 {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: the lint level is defined here
+  --> $DIR/eval-privacy.rs:5:9
+   |
+LL | #![warn(private_interfaces)]
+   |         ^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error; 1 warning emitted
 
 For more information about this error, try `rustc --explain E0446`.
diff --git a/tests/ui/error-codes/E0445.rs b/tests/ui/error-codes/E0445.rs
index a9a3aee2500..f5f35fb8a4d 100644
--- a/tests/ui/error-codes/E0445.rs
+++ b/tests/ui/error-codes/E0445.rs
@@ -1,3 +1,10 @@
+#[warn(private_bounds)]
+#[warn(private_interfaces)]
+
+// In this test both old and new private-in-public diagnostic were emitted.
+// Old diagnostic will be deleted soon.
+// See https://rust-lang.github.io/rfcs/2145-type-privacy.html.
+
 trait Foo {
     fn dummy(&self) { }
 }
diff --git a/tests/ui/error-codes/E0445.stderr b/tests/ui/error-codes/E0445.stderr
index 23b7a335047..ac3637a8218 100644
--- a/tests/ui/error-codes/E0445.stderr
+++ b/tests/ui/error-codes/E0445.stderr
@@ -1,5 +1,5 @@
 error[E0445]: private trait `Foo` in public interface
-  --> $DIR/E0445.rs:5:1
+  --> $DIR/E0445.rs:12:1
    |
 LL | trait Foo {
    | --------- `Foo` declared as private
@@ -7,8 +7,26 @@ LL | trait Foo {
 LL | pub trait Bar : Foo {}
    | ^^^^^^^^^^^^^^^^^^^ can't leak private trait
 
+warning: trait `Foo` is more private than the item `Bar`
+   |
+note: trait `Bar` is reachable at visibility `pub`
+  --> $DIR/E0445.rs:12:1
+   |
+LL | pub trait Bar : Foo {}
+   | ^^^^^^^^^^^^^^^^^^^
+note: but trait `Foo` is only usable at visibility `pub(crate)`
+  --> $DIR/E0445.rs:8:1
+   |
+LL | trait Foo {
+   | ^^^^^^^^^
+note: the lint level is defined here
+  --> $DIR/E0445.rs:1:8
+   |
+LL | #[warn(private_bounds)]
+   |        ^^^^^^^^^^^^^^
+
 error[E0445]: private trait `Foo` in public interface
-  --> $DIR/E0445.rs:7:1
+  --> $DIR/E0445.rs:14:1
    |
 LL | trait Foo {
    | --------- `Foo` declared as private
@@ -16,8 +34,21 @@ LL | trait Foo {
 LL | pub struct Bar2<T: Foo>(pub T);
    | ^^^^^^^^^^^^^^^^^^^^^^^ can't leak private trait
 
+warning: trait `Foo` is more private than the item `Bar2`
+   |
+note: struct `Bar2` is reachable at visibility `pub`
+  --> $DIR/E0445.rs:14:1
+   |
+LL | pub struct Bar2<T: Foo>(pub T);
+   | ^^^^^^^^^^^^^^^^^^^^^^^
+note: but trait `Foo` is only usable at visibility `pub(crate)`
+  --> $DIR/E0445.rs:8:1
+   |
+LL | trait Foo {
+   | ^^^^^^^^^
+
 error[E0445]: private trait `Foo` in public interface
-  --> $DIR/E0445.rs:9:1
+  --> $DIR/E0445.rs:16:1
    |
 LL | trait Foo {
    | --------- `Foo` declared as private
@@ -25,6 +56,19 @@ LL | trait Foo {
 LL | pub fn foo<T: Foo> (t: T) {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private trait
 
-error: aborting due to 3 previous errors
+warning: trait `Foo` is more private than the item `foo`
+   |
+note: function `foo` is reachable at visibility `pub`
+  --> $DIR/E0445.rs:16:1
+   |
+LL | pub fn foo<T: Foo> (t: T) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^
+note: but trait `Foo` is only usable at visibility `pub(crate)`
+  --> $DIR/E0445.rs:8:1
+   |
+LL | trait Foo {
+   | ^^^^^^^^^
+
+error: aborting due to 3 previous errors; 3 warnings emitted
 
 For more information about this error, try `rustc --explain E0445`.
diff --git a/tests/ui/extern/issue-112363-extern-item-where-clauses-debug-ice.rs b/tests/ui/extern/issue-112363-extern-item-where-clauses-debug-ice.rs
new file mode 100644
index 00000000000..17e08f511d7
--- /dev/null
+++ b/tests/ui/extern/issue-112363-extern-item-where-clauses-debug-ice.rs
@@ -0,0 +1,10 @@
+extern "C" {
+    type Item = [T] where [T]: Sized;
+    //~^ incorrect `type` inside `extern` block
+    //~| `type`s inside `extern` blocks cannot have `where` clauses
+    //~| cannot find type `T` in this scope
+    //~| cannot find type `T` in this scope
+    //~| extern types are experimental
+}
+
+fn main() {}
diff --git a/tests/ui/extern/issue-112363-extern-item-where-clauses-debug-ice.stderr b/tests/ui/extern/issue-112363-extern-item-where-clauses-debug-ice.stderr
new file mode 100644
index 00000000000..bdc6755038a
--- /dev/null
+++ b/tests/ui/extern/issue-112363-extern-item-where-clauses-debug-ice.stderr
@@ -0,0 +1,47 @@
+error: incorrect `type` inside `extern` block
+  --> $DIR/issue-112363-extern-item-where-clauses-debug-ice.rs:2:10
+   |
+LL | extern "C" {
+   | ---------- `extern` blocks define existing foreign types and types inside of them cannot have a body
+LL |     type Item = [T] where [T]: Sized;
+   |          ^^^^   --- the invalid body
+   |          |
+   |          cannot have a body
+   |
+   = note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html
+
+error: `type`s inside `extern` blocks cannot have `where` clauses
+  --> $DIR/issue-112363-extern-item-where-clauses-debug-ice.rs:2:21
+   |
+LL | extern "C" {
+   | ---------- `extern` block begins here
+LL |     type Item = [T] where [T]: Sized;
+   |                     ^^^^^^^^^^^^^^^^ help: remove the `where` clause
+   |
+   = note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html
+
+error[E0412]: cannot find type `T` in this scope
+  --> $DIR/issue-112363-extern-item-where-clauses-debug-ice.rs:2:28
+   |
+LL |     type Item = [T] where [T]: Sized;
+   |                            ^ not found in this scope
+
+error[E0412]: cannot find type `T` in this scope
+  --> $DIR/issue-112363-extern-item-where-clauses-debug-ice.rs:2:18
+   |
+LL |     type Item = [T] where [T]: Sized;
+   |                  ^ not found in this scope
+
+error[E0658]: extern types are experimental
+  --> $DIR/issue-112363-extern-item-where-clauses-debug-ice.rs:2:5
+   |
+LL |     type Item = [T] where [T]: Sized;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #43467 <https://github.com/rust-lang/rust/issues/43467> for more information
+   = help: add `#![feature(extern_types)]` to the crate attributes to enable
+
+error: aborting due to 5 previous errors
+
+Some errors have detailed explanations: E0412, E0658.
+For more information about an error, try `rustc --explain E0412`.
diff --git a/tests/ui/issues/issue-18389.rs b/tests/ui/issues/issue-18389.rs
index 654dfb63b88..3686afc48af 100644
--- a/tests/ui/issues/issue-18389.rs
+++ b/tests/ui/issues/issue-18389.rs
@@ -1,3 +1,9 @@
+#![warn(private_bounds)]
+
+// In this test both old and new private-in-public diagnostic were emitted.
+// Old diagnostic will be deleted soon.
+// See https://rust-lang.github.io/rfcs/2145-type-privacy.html.
+
 use std::any::Any;
 use std::any::TypeId;
 
diff --git a/tests/ui/issues/issue-18389.stderr b/tests/ui/issues/issue-18389.stderr
index 6ce78c45d6e..f9ebde48a45 100644
--- a/tests/ui/issues/issue-18389.stderr
+++ b/tests/ui/issues/issue-18389.stderr
@@ -1,5 +1,5 @@
 error[E0445]: private trait `Private<<Self as Public>::P, <Self as Public>::R>` in public interface
-  --> $DIR/issue-18389.rs:7:1
+  --> $DIR/issue-18389.rs:13:1
    |
 LL |   trait Private<P, R> {
    |   ------------------- `Private<<Self as Public>::P, <Self as Public>::R>` declared as private
@@ -11,6 +11,28 @@ LL | |     <Self as Public>::R
 LL | | > {
    | |_^ can't leak private trait
 
-error: aborting due to previous error
+warning: trait `Private<<Self as Public>::P, <Self as Public>::R>` is more private than the item `Public`
+   |
+note: trait `Public` is reachable at visibility `pub`
+  --> $DIR/issue-18389.rs:13:1
+   |
+LL | / pub trait Public: Private<
+LL | |
+LL | |     <Self as Public>::P,
+LL | |     <Self as Public>::R
+LL | | > {
+   | |_^
+note: but trait `Private<<Self as Public>::P, <Self as Public>::R>` is only usable at visibility `pub(crate)`
+  --> $DIR/issue-18389.rs:10:1
+   |
+LL | trait Private<P, R> {
+   | ^^^^^^^^^^^^^^^^^^^
+note: the lint level is defined here
+  --> $DIR/issue-18389.rs:1:9
+   |
+LL | #![warn(private_bounds)]
+   |         ^^^^^^^^^^^^^^
+
+error: aborting due to previous error; 1 warning emitted
 
 For more information about this error, try `rustc --explain E0445`.
diff --git a/tests/ui/parser/foreign-ty-semantic-fail.rs b/tests/ui/parser/foreign-ty-semantic-fail.rs
index 96b15232b10..4d30086e765 100644
--- a/tests/ui/parser/foreign-ty-semantic-fail.rs
+++ b/tests/ui/parser/foreign-ty-semantic-fail.rs
@@ -15,4 +15,5 @@ extern "C" {
     //~^ ERROR incorrect `type` inside `extern` block
 
     type E: where;
+    //~^ ERROR `type`s inside `extern` blocks cannot have `where` clauses
 }
diff --git a/tests/ui/parser/foreign-ty-semantic-fail.stderr b/tests/ui/parser/foreign-ty-semantic-fail.stderr
index 588e4966aae..2b400dfea3b 100644
--- a/tests/ui/parser/foreign-ty-semantic-fail.stderr
+++ b/tests/ui/parser/foreign-ty-semantic-fail.stderr
@@ -61,5 +61,16 @@ LL |     type D = u8;
    |
    = note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html
 
-error: aborting due to 6 previous errors
+error: `type`s inside `extern` blocks cannot have `where` clauses
+  --> $DIR/foreign-ty-semantic-fail.rs:17:13
+   |
+LL | extern "C" {
+   | ---------- `extern` block begins here
+...
+LL |     type E: where;
+   |             ^^^^^ help: remove the `where` clause
+   |
+   = note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html
+
+error: aborting due to 7 previous errors
 
diff --git a/tests/ui/privacy/private-in-public-non-principal.rs b/tests/ui/privacy/private-in-public-non-principal.rs
index ac1d5a9e6a2..a80c1541463 100644
--- a/tests/ui/privacy/private-in-public-non-principal.rs
+++ b/tests/ui/privacy/private-in-public-non-principal.rs
@@ -1,6 +1,12 @@
 #![feature(auto_traits)]
 #![feature(negative_impls)]
 
+#![deny(private_interfaces)]
+
+// In this test both old and new private-in-public diagnostic were emitted.
+// Old diagnostic will be deleted soon.
+// See https://rust-lang.github.io/rfcs/2145-type-privacy.html.
+
 pub trait PubPrincipal {}
 auto trait PrivNonPrincipal {}
 
diff --git a/tests/ui/privacy/private-in-public-non-principal.stderr b/tests/ui/privacy/private-in-public-non-principal.stderr
index de20cada42e..9fc12affe4b 100644
--- a/tests/ui/privacy/private-in-public-non-principal.stderr
+++ b/tests/ui/privacy/private-in-public-non-principal.stderr
@@ -1,5 +1,5 @@
 warning: private trait `PrivNonPrincipal` in public interface (error E0445)
-  --> $DIR/private-in-public-non-principal.rs:7:1
+  --> $DIR/private-in-public-non-principal.rs:13:1
    |
 LL | pub fn leak_dyn_nonprincipal() -> Box<dyn PubPrincipal + PrivNonPrincipal> { loop {} }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -8,17 +8,35 @@ LL | pub fn leak_dyn_nonprincipal() -> Box<dyn PubPrincipal + PrivNonPrincipal>
    = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
    = note: `#[warn(private_in_public)]` on by default
 
+error: trait `PrivNonPrincipal` is more private than the item `leak_dyn_nonprincipal`
+   |
+note: function `leak_dyn_nonprincipal` is reachable at visibility `pub`
+  --> $DIR/private-in-public-non-principal.rs:13:1
+   |
+LL | pub fn leak_dyn_nonprincipal() -> Box<dyn PubPrincipal + PrivNonPrincipal> { loop {} }
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: but trait `PrivNonPrincipal` is only usable at visibility `pub(crate)`
+  --> $DIR/private-in-public-non-principal.rs:11:1
+   |
+LL | auto trait PrivNonPrincipal {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: the lint level is defined here
+  --> $DIR/private-in-public-non-principal.rs:4:9
+   |
+LL | #![deny(private_interfaces)]
+   |         ^^^^^^^^^^^^^^^^^^
+
 error: missing documentation for an associated function
-  --> $DIR/private-in-public-non-principal.rs:14:9
+  --> $DIR/private-in-public-non-principal.rs:20:9
    |
 LL |         pub fn check_doc_lint() {}
    |         ^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: the lint level is defined here
-  --> $DIR/private-in-public-non-principal.rs:11:8
+  --> $DIR/private-in-public-non-principal.rs:17:8
    |
 LL | #[deny(missing_docs)]
    |        ^^^^^^^^^^^^
 
-error: aborting due to previous error; 1 warning emitted
+error: aborting due to 2 previous errors; 1 warning emitted
 
diff --git a/tests/ui/privacy/private-inferred-type-1.rs b/tests/ui/privacy/private-inferred-type-1.rs
index d633189e3fb..b3eba53dd13 100644
--- a/tests/ui/privacy/private-inferred-type-1.rs
+++ b/tests/ui/privacy/private-inferred-type-1.rs
@@ -5,14 +5,24 @@ trait TyParam {
     fn ty_param_secret(&self);
 }
 
+trait Ref {
+    fn ref_secret(self);
+}
+
 mod m {
     struct Priv;
 
     impl ::Arr0 for [Priv; 0] { fn arr0_secret(&self) {} }
     impl ::TyParam for Option<Priv> { fn ty_param_secret(&self) {} }
+    impl<'a> ::Ref for &'a Priv { fn ref_secret(self) {} }
 }
 
+fn anyref<'a, T>() -> &'a T { panic!() }
+
 fn main() {
     [].arr0_secret(); //~ ERROR type `Priv` is private
     None.ty_param_secret(); //~ ERROR type `Priv` is private
+    Ref::ref_secret(anyref());
+    //~^ ERROR type `Priv` is private
+    //~| ERROR type `Priv` is private
 }
diff --git a/tests/ui/privacy/private-inferred-type-1.stderr b/tests/ui/privacy/private-inferred-type-1.stderr
index 245789f4353..47c11d6ec76 100644
--- a/tests/ui/privacy/private-inferred-type-1.stderr
+++ b/tests/ui/privacy/private-inferred-type-1.stderr
@@ -1,14 +1,26 @@
 error: type `Priv` is private
-  --> $DIR/private-inferred-type-1.rs:16:5
+  --> $DIR/private-inferred-type-1.rs:23:5
    |
 LL |     [].arr0_secret();
    |     ^^^^^^^^^^^^^^^^ private type
 
 error: type `Priv` is private
-  --> $DIR/private-inferred-type-1.rs:17:5
+  --> $DIR/private-inferred-type-1.rs:24:5
    |
 LL |     None.ty_param_secret();
    |     ^^^^^^^^^^^^^^^^^^^^^^ private type
 
-error: aborting due to 2 previous errors
+error: type `Priv` is private
+  --> $DIR/private-inferred-type-1.rs:25:5
+   |
+LL |     Ref::ref_secret(anyref());
+   |     ^^^^^^^^^^^^^^^ private type
+
+error: type `Priv` is private
+  --> $DIR/private-inferred-type-1.rs:25:21
+   |
+LL |     Ref::ref_secret(anyref());
+   |                     ^^^^^^^^ private type
+
+error: aborting due to 4 previous errors
 
diff --git a/tests/ui/privacy/unnameable_types.rs b/tests/ui/privacy/unnameable_types.rs
new file mode 100644
index 00000000000..8b53f372fc9
--- /dev/null
+++ b/tests/ui/privacy/unnameable_types.rs
@@ -0,0 +1,30 @@
+#![allow(unused)]
+#![allow(private_in_public)]
+#![deny(unnameable_types)]
+
+mod m {
+    pub struct PubStruct(pub i32); //~ ERROR struct `PubStruct` is reachable but cannot be named
+
+    pub enum PubE { //~ ERROR enum `PubE` is reachable but cannot be named
+        V(i32),
+    }
+
+    pub trait PubTr { //~ ERROR trait `PubTr` is reachable but cannot be named
+        const C : i32 = 0;
+        type Alias; //~ ERROR associated type `PubTr::Alias` is reachable but cannot be named
+        fn f() {}
+    }
+
+    impl PubTr for PubStruct {
+        type Alias = i32; //~ ERROR associated type `<PubStruct as PubTr>::Alias` is reachable but cannot be named
+        fn f() {}
+    }
+}
+
+pub trait Voldemort<T> {}
+
+impl Voldemort<m::PubStruct> for i32 {}
+impl Voldemort<m::PubE> for i32 {}
+impl<T> Voldemort<T> for u32 where T: m::PubTr {}
+
+fn main() {}
diff --git a/tests/ui/privacy/unnameable_types.stderr b/tests/ui/privacy/unnameable_types.stderr
new file mode 100644
index 00000000000..25eb5c9434a
--- /dev/null
+++ b/tests/ui/privacy/unnameable_types.stderr
@@ -0,0 +1,38 @@
+error: struct `PubStruct` is reachable but cannot be named
+  --> $DIR/unnameable_types.rs:6:5
+   |
+LL |     pub struct PubStruct(pub i32);
+   |     ^^^^^^^^^^^^^^^^^^^^ reachable at visibility `pub`, but can only be named at visibility `pub(crate)`
+   |
+note: the lint level is defined here
+  --> $DIR/unnameable_types.rs:3:9
+   |
+LL | #![deny(unnameable_types)]
+   |         ^^^^^^^^^^^^^^^^
+
+error: enum `PubE` is reachable but cannot be named
+  --> $DIR/unnameable_types.rs:8:5
+   |
+LL |     pub enum PubE {
+   |     ^^^^^^^^^^^^^ reachable at visibility `pub`, but can only be named at visibility `pub(crate)`
+
+error: trait `PubTr` is reachable but cannot be named
+  --> $DIR/unnameable_types.rs:12:5
+   |
+LL |     pub trait PubTr {
+   |     ^^^^^^^^^^^^^^^ reachable at visibility `pub`, but can only be named at visibility `pub(crate)`
+
+error: associated type `PubTr::Alias` is reachable but cannot be named
+  --> $DIR/unnameable_types.rs:14:9
+   |
+LL |         type Alias;
+   |         ^^^^^^^^^^ reachable at visibility `pub`, but can only be named at visibility `pub(crate)`
+
+error: associated type `<PubStruct as PubTr>::Alias` is reachable but cannot be named
+  --> $DIR/unnameable_types.rs:19:9
+   |
+LL |         type Alias = i32;
+   |         ^^^^^^^^^^ reachable at visibility `pub`, but can only be named at visibility `pub(crate)`
+
+error: aborting due to 5 previous errors
+
diff --git a/tests/ui/privacy/where-priv-type.rs b/tests/ui/privacy/where-priv-type.rs
index 66ee9c4bbd8..9899902dd88 100644
--- a/tests/ui/privacy/where-priv-type.rs
+++ b/tests/ui/privacy/where-priv-type.rs
@@ -5,6 +5,12 @@
 #![feature(generic_const_exprs)]
 #![allow(incomplete_features)]
 
+#![warn(private_bounds)]
+#![warn(private_interfaces)]
+
+// In this test both old and new private-in-public diagnostic were emitted.
+// Old diagnostic will be deleted soon.
+// See https://rust-lang.github.io/rfcs/2145-type-privacy.html.
 
 struct PrivTy;
 trait PrivTr {}
diff --git a/tests/ui/privacy/where-priv-type.stderr b/tests/ui/privacy/where-priv-type.stderr
index c5fb2cdb0cf..2830fa6cd44 100644
--- a/tests/ui/privacy/where-priv-type.stderr
+++ b/tests/ui/privacy/where-priv-type.stderr
@@ -1,5 +1,5 @@
 warning: private type `PrivTy` in public interface (error E0446)
-  --> $DIR/where-priv-type.rs:19:1
+  --> $DIR/where-priv-type.rs:25:1
    |
 LL | pub struct S
    | ^^^^^^^^^^^^
@@ -8,8 +8,26 @@ LL | pub struct S
    = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
    = note: `#[warn(private_in_public)]` on by default
 
+warning: type `PrivTy` is more private than the item `S`
+   |
+note: struct `S` is reachable at visibility `pub`
+  --> $DIR/where-priv-type.rs:25:1
+   |
+LL | pub struct S
+   | ^^^^^^^^^^^^
+note: but type `PrivTy` is only usable at visibility `pub(crate)`
+  --> $DIR/where-priv-type.rs:15:1
+   |
+LL | struct PrivTy;
+   | ^^^^^^^^^^^^^
+note: the lint level is defined here
+  --> $DIR/where-priv-type.rs:8:9
+   |
+LL | #![warn(private_bounds)]
+   |         ^^^^^^^^^^^^^^
+
 warning: private type `PrivTy` in public interface (error E0446)
-  --> $DIR/where-priv-type.rs:27:1
+  --> $DIR/where-priv-type.rs:33:1
    |
 LL | pub enum E
    | ^^^^^^^^^^
@@ -17,8 +35,21 @@ LL | pub enum E
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
 
+warning: type `PrivTy` is more private than the item `E`
+   |
+note: enum `E` is reachable at visibility `pub`
+  --> $DIR/where-priv-type.rs:33:1
+   |
+LL | pub enum E
+   | ^^^^^^^^^^
+note: but type `PrivTy` is only usable at visibility `pub(crate)`
+  --> $DIR/where-priv-type.rs:15:1
+   |
+LL | struct PrivTy;
+   | ^^^^^^^^^^^^^
+
 warning: private type `PrivTy` in public interface (error E0446)
-  --> $DIR/where-priv-type.rs:35:1
+  --> $DIR/where-priv-type.rs:41:1
    |
 LL | / pub fn f()
 LL | |
@@ -30,8 +61,25 @@ LL | |     PrivTy:
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
 
+warning: type `PrivTy` is more private than the item `f`
+   |
+note: function `f` is reachable at visibility `pub`
+  --> $DIR/where-priv-type.rs:41:1
+   |
+LL | / pub fn f()
+LL | |
+LL | |
+LL | | where
+LL | |     PrivTy:
+   | |___________^
+note: but type `PrivTy` is only usable at visibility `pub(crate)`
+  --> $DIR/where-priv-type.rs:15:1
+   |
+LL | struct PrivTy;
+   | ^^^^^^^^^^^^^
+
 error[E0446]: private type `PrivTy` in public interface
-  --> $DIR/where-priv-type.rs:43:1
+  --> $DIR/where-priv-type.rs:49:1
    |
 LL | struct PrivTy;
    | ------------- `PrivTy` declared as private
@@ -39,8 +87,21 @@ LL | struct PrivTy;
 LL | impl S
    | ^^^^^^ can't leak private type
 
+warning: type `PrivTy` is more private than the item `S`
+   |
+note: implementation `S` is reachable at visibility `pub`
+  --> $DIR/where-priv-type.rs:49:1
+   |
+LL | impl S
+   | ^^^^^^
+note: but type `PrivTy` is only usable at visibility `pub(crate)`
+  --> $DIR/where-priv-type.rs:15:1
+   |
+LL | struct PrivTy;
+   | ^^^^^^^^^^^^^
+
 warning: private type `PrivTy` in public interface (error E0446)
-  --> $DIR/where-priv-type.rs:48:5
+  --> $DIR/where-priv-type.rs:54:5
    |
 LL | /     pub fn f()
 LL | |
@@ -52,8 +113,25 @@ LL | |         PrivTy:
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
 
+warning: type `PrivTy` is more private than the item `S::f`
+   |
+note: associated function `S::f` is reachable at visibility `pub`
+  --> $DIR/where-priv-type.rs:54:5
+   |
+LL | /     pub fn f()
+LL | |
+LL | |
+LL | |     where
+LL | |         PrivTy:
+   | |_______________^
+note: but type `PrivTy` is only usable at visibility `pub(crate)`
+  --> $DIR/where-priv-type.rs:15:1
+   |
+LL | struct PrivTy;
+   | ^^^^^^^^^^^^^
+
 error[E0446]: private type `fn(u8) -> u8 {my_const_fn}` in public interface
-  --> $DIR/where-priv-type.rs:80:5
+  --> $DIR/where-priv-type.rs:86:5
    |
 LL |     type AssocTy = Const<{ my_const_fn(U) }>;
    |     ^^^^^^^^^^^^ can't leak private type
@@ -61,6 +139,24 @@ LL |     type AssocTy = Const<{ my_const_fn(U) }>;
 LL | const fn my_const_fn(val: u8) -> u8 {
    | ----------------------------------- `fn(u8) -> u8 {my_const_fn}` declared as private
 
-error: aborting due to 2 previous errors; 4 warnings emitted
+warning: type `fn(u8) -> u8 {my_const_fn}` is more private than the item `<Const<U> as Trait>::AssocTy`
+   |
+note: associated type `<Const<U> as Trait>::AssocTy` is reachable at visibility `pub`
+  --> $DIR/where-priv-type.rs:86:5
+   |
+LL |     type AssocTy = Const<{ my_const_fn(U) }>;
+   |     ^^^^^^^^^^^^
+note: but type `fn(u8) -> u8 {my_const_fn}` is only usable at visibility `pub(crate)`
+  --> $DIR/where-priv-type.rs:93:1
+   |
+LL | const fn my_const_fn(val: u8) -> u8 {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: the lint level is defined here
+  --> $DIR/where-priv-type.rs:9:9
+   |
+LL | #![warn(private_interfaces)]
+   |         ^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors; 10 warnings emitted
 
 For more information about this error, try `rustc --explain E0446`.
diff --git a/tests/ui/privacy/where-pub-type-impls-priv-trait.rs b/tests/ui/privacy/where-pub-type-impls-priv-trait.rs
index 87c211df169..3aad893eae2 100644
--- a/tests/ui/privacy/where-pub-type-impls-priv-trait.rs
+++ b/tests/ui/privacy/where-pub-type-impls-priv-trait.rs
@@ -4,6 +4,11 @@
 #![feature(generic_const_exprs)]
 #![allow(incomplete_features)]
 
+#![warn(private_bounds)]
+
+// In this test both old and new private-in-public diagnostic were emitted.
+// Old diagnostic will be deleted soon.
+// See https://rust-lang.github.io/rfcs/2145-type-privacy.html.
 
 struct PrivTy;
 trait PrivTr {}
diff --git a/tests/ui/privacy/where-pub-type-impls-priv-trait.stderr b/tests/ui/privacy/where-pub-type-impls-priv-trait.stderr
index a433cebbbc0..413f7f781cd 100644
--- a/tests/ui/privacy/where-pub-type-impls-priv-trait.stderr
+++ b/tests/ui/privacy/where-pub-type-impls-priv-trait.stderr
@@ -1,5 +1,5 @@
 error[E0445]: private trait `PrivTr` in public interface
-  --> $DIR/where-pub-type-impls-priv-trait.rs:19:1
+  --> $DIR/where-pub-type-impls-priv-trait.rs:24:1
    |
 LL | trait PrivTr {}
    | ------------ `PrivTr` declared as private
@@ -7,8 +7,26 @@ LL | trait PrivTr {}
 LL | pub struct S
    | ^^^^^^^^^^^^ can't leak private trait
 
+warning: trait `PrivTr` is more private than the item `S`
+   |
+note: struct `S` is reachable at visibility `pub`
+  --> $DIR/where-pub-type-impls-priv-trait.rs:24:1
+   |
+LL | pub struct S
+   | ^^^^^^^^^^^^
+note: but trait `PrivTr` is only usable at visibility `pub(crate)`
+  --> $DIR/where-pub-type-impls-priv-trait.rs:14:1
+   |
+LL | trait PrivTr {}
+   | ^^^^^^^^^^^^
+note: the lint level is defined here
+  --> $DIR/where-pub-type-impls-priv-trait.rs:7:9
+   |
+LL | #![warn(private_bounds)]
+   |         ^^^^^^^^^^^^^^
+
 error[E0445]: private trait `PrivTr` in public interface
-  --> $DIR/where-pub-type-impls-priv-trait.rs:26:1
+  --> $DIR/where-pub-type-impls-priv-trait.rs:31:1
    |
 LL | trait PrivTr {}
    | ------------ `PrivTr` declared as private
@@ -16,8 +34,21 @@ LL | trait PrivTr {}
 LL | pub enum E
    | ^^^^^^^^^^ can't leak private trait
 
+warning: trait `PrivTr` is more private than the item `E`
+   |
+note: enum `E` is reachable at visibility `pub`
+  --> $DIR/where-pub-type-impls-priv-trait.rs:31:1
+   |
+LL | pub enum E
+   | ^^^^^^^^^^
+note: but trait `PrivTr` is only usable at visibility `pub(crate)`
+  --> $DIR/where-pub-type-impls-priv-trait.rs:14:1
+   |
+LL | trait PrivTr {}
+   | ^^^^^^^^^^^^
+
 error[E0445]: private trait `PrivTr` in public interface
-  --> $DIR/where-pub-type-impls-priv-trait.rs:33:1
+  --> $DIR/where-pub-type-impls-priv-trait.rs:38:1
    |
 LL |   trait PrivTr {}
    |   ------------ `PrivTr` declared as private
@@ -28,8 +59,24 @@ LL | | where
 LL | |     PubTy: PrivTr
    | |_________________^ can't leak private trait
 
+warning: trait `PrivTr` is more private than the item `f`
+   |
+note: function `f` is reachable at visibility `pub`
+  --> $DIR/where-pub-type-impls-priv-trait.rs:38:1
+   |
+LL | / pub fn f()
+LL | |
+LL | | where
+LL | |     PubTy: PrivTr
+   | |_________________^
+note: but trait `PrivTr` is only usable at visibility `pub(crate)`
+  --> $DIR/where-pub-type-impls-priv-trait.rs:14:1
+   |
+LL | trait PrivTr {}
+   | ^^^^^^^^^^^^
+
 error[E0445]: private trait `PrivTr` in public interface
-  --> $DIR/where-pub-type-impls-priv-trait.rs:40:1
+  --> $DIR/where-pub-type-impls-priv-trait.rs:45:1
    |
 LL | trait PrivTr {}
    | ------------ `PrivTr` declared as private
@@ -37,8 +84,21 @@ LL | trait PrivTr {}
 LL | impl S
    | ^^^^^^ can't leak private trait
 
+warning: trait `PrivTr` is more private than the item `S`
+   |
+note: implementation `S` is reachable at visibility `pub`
+  --> $DIR/where-pub-type-impls-priv-trait.rs:45:1
+   |
+LL | impl S
+   | ^^^^^^
+note: but trait `PrivTr` is only usable at visibility `pub(crate)`
+  --> $DIR/where-pub-type-impls-priv-trait.rs:14:1
+   |
+LL | trait PrivTr {}
+   | ^^^^^^^^^^^^
+
 error[E0445]: private trait `PrivTr` in public interface
-  --> $DIR/where-pub-type-impls-priv-trait.rs:45:5
+  --> $DIR/where-pub-type-impls-priv-trait.rs:50:5
    |
 LL |   trait PrivTr {}
    |   ------------ `PrivTr` declared as private
@@ -49,6 +109,22 @@ LL | |     where
 LL | |         PubTy: PrivTr
    | |_____________________^ can't leak private trait
 
-error: aborting due to 5 previous errors
+warning: trait `PrivTr` is more private than the item `S::f`
+   |
+note: associated function `S::f` is reachable at visibility `pub`
+  --> $DIR/where-pub-type-impls-priv-trait.rs:50:5
+   |
+LL | /     pub fn f()
+LL | |
+LL | |     where
+LL | |         PubTy: PrivTr
+   | |_____________________^
+note: but trait `PrivTr` is only usable at visibility `pub(crate)`
+  --> $DIR/where-pub-type-impls-priv-trait.rs:14:1
+   |
+LL | trait PrivTr {}
+   | ^^^^^^^^^^^^
+
+error: aborting due to 5 previous errors; 5 warnings emitted
 
 For more information about this error, try `rustc --explain E0445`.
diff --git a/tests/ui/pub/issue-33174-restricted-type-in-public-interface.rs b/tests/ui/pub/issue-33174-restricted-type-in-public-interface.rs
index 67f888c5e94..9e4ba80a784 100644
--- a/tests/ui/pub/issue-33174-restricted-type-in-public-interface.rs
+++ b/tests/ui/pub/issue-33174-restricted-type-in-public-interface.rs
@@ -1,15 +1,24 @@
 #![allow(non_camel_case_types)] // genus is always capitalized
+#![warn(private_interfaces)]
+//~^ NOTE the lint level is defined here
+
+// In this test both old and new private-in-public diagnostic were emitted.
+// Old diagnostic will be deleted soon.
+// See https://rust-lang.github.io/rfcs/2145-type-privacy.html.
 
 pub(crate) struct Snail;
 //~^ NOTE `Snail` declared as private
+//~| NOTE but type `Snail` is only usable at visibility `pub(crate)`
 
 mod sea {
     pub(super) struct Turtle;
     //~^ NOTE `Turtle` declared as crate-private
+    //~| NOTE but type `Turtle` is only usable at visibility `pub(crate)`
 }
 
 struct Tortoise;
 //~^ NOTE `Tortoise` declared as private
+//~| NOTE but type `Tortoise` is only usable at visibility `pub(crate)`
 
 pub struct Shell<T> {
     pub(crate) creature: T,
@@ -18,11 +27,14 @@ pub struct Shell<T> {
 pub type Helix_pomatia = Shell<Snail>;
 //~^ ERROR private type `Snail` in public interface
 //~| NOTE can't leak private type
+//~| NOTE type alias `Helix_pomatia` is reachable at visibility `pub`
 pub type Dermochelys_coriacea = Shell<sea::Turtle>;
 //~^ ERROR crate-private type `Turtle` in public interface
 //~| NOTE can't leak crate-private type
+//~| NOTE type alias `Dermochelys_coriacea` is reachable at visibility `pub`
 pub type Testudo_graeca = Shell<Tortoise>;
 //~^ ERROR private type `Tortoise` in public interface
 //~| NOTE can't leak private type
+//~| NOTE type alias `Testudo_graeca` is reachable at visibility `pub`
 
 fn main() {}
diff --git a/tests/ui/pub/issue-33174-restricted-type-in-public-interface.stderr b/tests/ui/pub/issue-33174-restricted-type-in-public-interface.stderr
index 39d4f5ac8d3..52f67d4cdd5 100644
--- a/tests/ui/pub/issue-33174-restricted-type-in-public-interface.stderr
+++ b/tests/ui/pub/issue-33174-restricted-type-in-public-interface.stderr
@@ -1,5 +1,5 @@
 error[E0446]: private type `Snail` in public interface
-  --> $DIR/issue-33174-restricted-type-in-public-interface.rs:18:1
+  --> $DIR/issue-33174-restricted-type-in-public-interface.rs:27:1
    |
 LL | pub(crate) struct Snail;
    | ----------------------- `Snail` declared as private
@@ -7,8 +7,26 @@ LL | pub(crate) struct Snail;
 LL | pub type Helix_pomatia = Shell<Snail>;
    | ^^^^^^^^^^^^^^^^^^^^^^ can't leak private type
 
+warning: type `Snail` is more private than the item `Helix_pomatia`
+   |
+note: type alias `Helix_pomatia` is reachable at visibility `pub`
+  --> $DIR/issue-33174-restricted-type-in-public-interface.rs:27:1
+   |
+LL | pub type Helix_pomatia = Shell<Snail>;
+   | ^^^^^^^^^^^^^^^^^^^^^^
+note: but type `Snail` is only usable at visibility `pub(crate)`
+  --> $DIR/issue-33174-restricted-type-in-public-interface.rs:9:1
+   |
+LL | pub(crate) struct Snail;
+   | ^^^^^^^^^^^^^^^^^^^^^^^
+note: the lint level is defined here
+  --> $DIR/issue-33174-restricted-type-in-public-interface.rs:2:9
+   |
+LL | #![warn(private_interfaces)]
+   |         ^^^^^^^^^^^^^^^^^^
+
 error[E0446]: crate-private type `Turtle` in public interface
-  --> $DIR/issue-33174-restricted-type-in-public-interface.rs:21:1
+  --> $DIR/issue-33174-restricted-type-in-public-interface.rs:31:1
    |
 LL |     pub(super) struct Turtle;
    |     ------------------------ `Turtle` declared as crate-private
@@ -16,8 +34,21 @@ LL |     pub(super) struct Turtle;
 LL | pub type Dermochelys_coriacea = Shell<sea::Turtle>;
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't leak crate-private type
 
+warning: type `Turtle` is more private than the item `Dermochelys_coriacea`
+   |
+note: type alias `Dermochelys_coriacea` is reachable at visibility `pub`
+  --> $DIR/issue-33174-restricted-type-in-public-interface.rs:31:1
+   |
+LL | pub type Dermochelys_coriacea = Shell<sea::Turtle>;
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: but type `Turtle` is only usable at visibility `pub(crate)`
+  --> $DIR/issue-33174-restricted-type-in-public-interface.rs:14:5
+   |
+LL |     pub(super) struct Turtle;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^
+
 error[E0446]: private type `Tortoise` in public interface
-  --> $DIR/issue-33174-restricted-type-in-public-interface.rs:24:1
+  --> $DIR/issue-33174-restricted-type-in-public-interface.rs:35:1
    |
 LL | struct Tortoise;
    | --------------- `Tortoise` declared as private
@@ -25,6 +56,19 @@ LL | struct Tortoise;
 LL | pub type Testudo_graeca = Shell<Tortoise>;
    | ^^^^^^^^^^^^^^^^^^^^^^^ can't leak private type
 
-error: aborting due to 3 previous errors
+warning: type `Tortoise` is more private than the item `Testudo_graeca`
+   |
+note: type alias `Testudo_graeca` is reachable at visibility `pub`
+  --> $DIR/issue-33174-restricted-type-in-public-interface.rs:35:1
+   |
+LL | pub type Testudo_graeca = Shell<Tortoise>;
+   | ^^^^^^^^^^^^^^^^^^^^^^^
+note: but type `Tortoise` is only usable at visibility `pub(crate)`
+  --> $DIR/issue-33174-restricted-type-in-public-interface.rs:19:1
+   |
+LL | struct Tortoise;
+   | ^^^^^^^^^^^^^^^
+
+error: aborting due to 3 previous errors; 3 warnings emitted
 
 For more information about this error, try `rustc --explain E0446`.
diff --git a/tests/ui/typeck/issue-112252-ptr-arithmetics-help.fixed b/tests/ui/typeck/issue-112252-ptr-arithmetics-help.fixed
new file mode 100644
index 00000000000..bdb884f5431
--- /dev/null
+++ b/tests/ui/typeck/issue-112252-ptr-arithmetics-help.fixed
@@ -0,0 +1,10 @@
+// run-rustfix
+
+fn main() {
+    let _ptr1: *const u32 = std::ptr::null();
+    let _ptr2: *const u32 = std::ptr::null();
+    let _a = _ptr1.wrapping_add(5); //~ ERROR cannot add
+    let _b = _ptr1.wrapping_sub(5); //~ ERROR cannot subtract
+    let _c = unsafe { _ptr2.offset_from(_ptr1) }; //~ ERROR cannot subtract
+    let _d = _ptr1.wrapping_add(5); //~ ERROR cannot index
+}
diff --git a/tests/ui/typeck/issue-112252-ptr-arithmetics-help.rs b/tests/ui/typeck/issue-112252-ptr-arithmetics-help.rs
new file mode 100644
index 00000000000..cf68850cc4d
--- /dev/null
+++ b/tests/ui/typeck/issue-112252-ptr-arithmetics-help.rs
@@ -0,0 +1,10 @@
+// run-rustfix
+
+fn main() {
+    let _ptr1: *const u32 = std::ptr::null();
+    let _ptr2: *const u32 = std::ptr::null();
+    let _a = _ptr1 + 5; //~ ERROR cannot add
+    let _b = _ptr1 - 5; //~ ERROR cannot subtract
+    let _c = _ptr2 - _ptr1; //~ ERROR cannot subtract
+    let _d = _ptr1[5]; //~ ERROR cannot index
+}
diff --git a/tests/ui/typeck/issue-112252-ptr-arithmetics-help.stderr b/tests/ui/typeck/issue-112252-ptr-arithmetics-help.stderr
new file mode 100644
index 00000000000..c55930da225
--- /dev/null
+++ b/tests/ui/typeck/issue-112252-ptr-arithmetics-help.stderr
@@ -0,0 +1,54 @@
+error[E0369]: cannot add `{integer}` to `*const u32`
+  --> $DIR/issue-112252-ptr-arithmetics-help.rs:6:20
+   |
+LL |     let _a = _ptr1 + 5;
+   |              ----- ^ - {integer}
+   |              |
+   |              *const u32
+   |
+help: consider using `wrapping_add` or `add` for pointer + {integer}
+   |
+LL |     let _a = _ptr1.wrapping_add(5);
+   |                   ~~~~~~~~~~~~~~ +
+
+error[E0369]: cannot subtract `{integer}` from `*const u32`
+  --> $DIR/issue-112252-ptr-arithmetics-help.rs:7:20
+   |
+LL |     let _b = _ptr1 - 5;
+   |              ----- ^ - {integer}
+   |              |
+   |              *const u32
+   |
+help: consider using `wrapping_sub` or `sub` for pointer - {integer}
+   |
+LL |     let _b = _ptr1.wrapping_sub(5);
+   |                   ~~~~~~~~~~~~~~ +
+
+error[E0369]: cannot subtract `*const u32` from `*const u32`
+  --> $DIR/issue-112252-ptr-arithmetics-help.rs:8:20
+   |
+LL |     let _c = _ptr2 - _ptr1;
+   |              ----- ^ ----- *const u32
+   |              |
+   |              *const u32
+   |
+help: consider using `offset_from` for pointer - pointer if the pointers point to the same allocation
+   |
+LL |     let _c = unsafe { _ptr2.offset_from(_ptr1) };
+   |              ++++++++      ~~~~~~~~~~~~~     +++
+
+error[E0608]: cannot index into a value of type `*const u32`
+  --> $DIR/issue-112252-ptr-arithmetics-help.rs:9:14
+   |
+LL |     let _d = _ptr1[5];
+   |              ^^^^^^^^
+   |
+help: consider using `wrapping_add` or `add` for indexing into raw pointer
+   |
+LL |     let _d = _ptr1.wrapping_add(5);
+   |                   ~~~~~~~~~~~~~~ ~
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0369, E0608.
+For more information about an error, try `rustc --explain E0369`.
diff --git a/tests/ui/typeck/ptr-null-mutability-suggestions.fixed b/tests/ui/typeck/ptr-null-mutability-suggestions.fixed
new file mode 100644
index 00000000000..d00536b29cf
--- /dev/null
+++ b/tests/ui/typeck/ptr-null-mutability-suggestions.fixed
@@ -0,0 +1,11 @@
+// run-rustfix
+
+#[allow(unused_imports)]
+use std::ptr;
+
+fn expecting_null_mut(_: *mut u8) {}
+
+fn main() {
+    expecting_null_mut(core::ptr::null_mut());
+    //~^ ERROR mismatched types
+}
diff --git a/tests/ui/typeck/ptr-null-mutability-suggestions.rs b/tests/ui/typeck/ptr-null-mutability-suggestions.rs
new file mode 100644
index 00000000000..ea3066d2289
--- /dev/null
+++ b/tests/ui/typeck/ptr-null-mutability-suggestions.rs
@@ -0,0 +1,11 @@
+// run-rustfix
+
+#[allow(unused_imports)]
+use std::ptr;
+
+fn expecting_null_mut(_: *mut u8) {}
+
+fn main() {
+    expecting_null_mut(ptr::null());
+    //~^ ERROR mismatched types
+}
diff --git a/tests/ui/typeck/ptr-null-mutability-suggestions.stderr b/tests/ui/typeck/ptr-null-mutability-suggestions.stderr
new file mode 100644
index 00000000000..705b029bdea
--- /dev/null
+++ b/tests/ui/typeck/ptr-null-mutability-suggestions.stderr
@@ -0,0 +1,21 @@
+error[E0308]: mismatched types
+  --> $DIR/ptr-null-mutability-suggestions.rs:9:24
+   |
+LL |     expecting_null_mut(ptr::null());
+   |     ------------------ ^^^^^^^^^^^
+   |     |                  |
+   |     |                  types differ in mutability
+   |     |                  help: consider using `core::ptr::null_mut` instead: `core::ptr::null_mut()`
+   |     arguments to this function are incorrect
+   |
+   = note: expected raw pointer `*mut u8`
+              found raw pointer `*const _`
+note: function defined here
+  --> $DIR/ptr-null-mutability-suggestions.rs:6:4
+   |
+LL | fn expecting_null_mut(_: *mut u8) {}
+   |    ^^^^^^^^^^^^^^^^^^ ----------
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/unsized-locals/rust-call.rs b/tests/ui/unsized-locals/rust-call.rs
new file mode 100644
index 00000000000..ff4075aa4c0
--- /dev/null
+++ b/tests/ui/unsized-locals/rust-call.rs
@@ -0,0 +1,12 @@
+#![feature(unsized_tuple_coercion)]
+#![feature(unboxed_closures)]
+#![feature(unsized_fn_params)]
+
+fn bad() -> extern "rust-call" fn(([u8],)) { todo!() }
+
+fn main() {
+    let f = bad();
+    let slice: Box<([u8],)> = Box::new(([1; 8],));
+    f(*slice);
+    //~^ ERROR the size for values of type `[u8]` cannot be known at compilation time
+}
diff --git a/tests/ui/unsized-locals/rust-call.stderr b/tests/ui/unsized-locals/rust-call.stderr
new file mode 100644
index 00000000000..fff7ef75b33
--- /dev/null
+++ b/tests/ui/unsized-locals/rust-call.stderr
@@ -0,0 +1,13 @@
+error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
+  --> $DIR/rust-call.rs:10:7
+   |
+LL |     f(*slice);
+   |       ^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: within `([u8],)`, the trait `Sized` is not implemented for `[u8]`
+   = note: required because it appears within the type `([u8],)`
+   = note: argument required to be sized due to `extern "rust-call"` ABI
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.