about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs11
-rw-r--r--compiler/rustc_borrowck/src/region_infer/mod.rs9
-rw-r--r--compiler/rustc_borrowck/src/type_check/canonical.rs19
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs4
-rw-r--r--compiler/rustc_codegen_llvm/src/back/archive.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/back/lto.rs2
-rw-r--r--compiler/rustc_const_eval/src/interpret/terminator.rs47
-rw-r--r--compiler/rustc_data_structures/src/sync.rs4
-rw-r--r--compiler/rustc_error_codes/src/error_codes.rs1
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0445.md8
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0446.md46
-rw-r--r--compiler/rustc_errors/src/lib.rs2
-rw-r--r--compiler/rustc_feature/src/accepted.rs2
-rw-r--r--compiler/rustc_hir/src/hir.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/mod.rs19
-rw-r--r--compiler/rustc_hir_analysis/src/collect.rs17
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs10
-rw-r--r--compiler/rustc_interface/src/passes.rs4
-rw-r--r--compiler/rustc_interface/src/queries.rs6
-rw-r--r--compiler/rustc_lint/src/early.rs1
-rw-r--r--compiler/rustc_lint/src/lib.rs5
-rw-r--r--compiler/rustc_lint/src/passes.rs1
-rw-r--r--compiler/rustc_lint/src/unused.rs29
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs49
-rw-r--r--compiler/rustc_llvm/build.rs5
-rw-r--r--compiler/rustc_metadata/src/lib.rs2
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder.rs4
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs106
-rw-r--r--compiler/rustc_metadata/src/rmeta/mod.rs2
-rw-r--r--compiler/rustc_middle/src/hir/map/mod.rs1
-rw-r--r--compiler/rustc_middle/src/mir/basic_blocks.rs12
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs2
-rw-r--r--compiler/rustc_mir_build/src/build/expr/into.rs68
-rw-r--r--compiler/rustc_mir_build/src/build/matches/mod.rs44
-rw-r--r--compiler/rustc_privacy/messages.ftl5
-rw-r--r--compiler/rustc_privacy/src/errors.rs23
-rw-r--r--compiler/rustc_privacy/src/lib.rs421
-rw-r--r--compiler/rustc_query_system/src/query/caches.rs12
-rw-r--r--compiler/rustc_resolve/src/build_reduced_graph.rs2
-rw-r--r--compiler/rustc_resolve/src/effective_visibilities.rs9
-rw-r--r--compiler/rustc_resolve/src/late.rs64
-rw-r--r--compiler/rustc_resolve/src/lib.rs4
-rw-r--r--compiler/rustc_smir/src/rustc_internal/mod.rs18
-rw-r--r--compiler/rustc_smir/src/rustc_smir/alloc.rs124
-rw-r--r--compiler/rustc_smir/src/rustc_smir/mod.rs65
-rw-r--r--compiler/rustc_smir/src/stable_mir/mod.rs1
-rw-r--r--compiler/rustc_smir/src/stable_mir/ty.rs129
-rw-r--r--compiler/rustc_smir/src/stable_mir/visitor.rs186
-rw-r--r--compiler/rustc_trait_selection/messages.ftl1
-rw-r--r--compiler/rustc_trait_selection/src/solve/eval_ctxt.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/project.rs21
-rw-r--r--library/core/src/char/convert.rs38
-rw-r--r--library/core/src/iter/adapters/take.rs101
-rw-r--r--library/core/src/iter/range.rs45
-rw-r--r--library/core/src/lib.rs1
-rw-r--r--library/core/src/num/nonzero.rs14
-rw-r--r--library/core/src/num/saturating.rs1
-rw-r--r--library/core/src/num/wrapping.rs1
-rw-r--r--library/core/src/option.rs2
-rw-r--r--library/core/src/ptr/non_null.rs18
-rw-r--r--library/core/src/slice/ascii.rs2
-rw-r--r--library/core/src/str/mod.rs2
-rw-r--r--library/core/tests/iter/range.rs18
-rw-r--r--library/core/tests/lib.rs2
-rw-r--r--library/std/src/ffi/mod.rs4
-rw-r--r--library/std/src/ffi/os_str.rs68
-rw-r--r--library/std/src/fs.rs12
-rw-r--r--library/std/src/path.rs34
-rw-r--r--library/std/src/sys/common/small_c_string.rs2
-rw-r--r--library/std/src/sys/common/tests.rs4
-rw-r--r--library/std/src/sys/solid/error.rs5
-rw-r--r--library/std/src/sys/solid/mod.rs2
-rw-r--r--library/std/src/sys/solid/net.rs3
-rw-r--r--library/std/src/sys/unix/os_str.rs10
-rw-r--r--library/std/src/sys/unix/os_str/tests.rs4
-rw-r--r--library/std/src/sys/unix/path.rs2
-rw-r--r--library/std/src/sys/unix/process/process_common.rs4
-rw-r--r--library/std/src/sys/windows/args.rs4
-rw-r--r--library/std/src/sys/windows/os_str.rs8
-rw-r--r--library/std/src/sys/windows/path.rs28
-rw-r--r--library/std/src/sys/windows/process.rs4
-rw-r--r--src/bootstrap/llvm.rs9
-rw-r--r--src/bootstrap/sanity.rs23
-rw-r--r--src/doc/rustc/src/platform-support.md12
-rw-r--r--src/librustdoc/clean/mod.rs27
-rw-r--r--src/librustdoc/clean/types.rs7
-rw-r--r--src/librustdoc/clean/utils.rs101
-rw-r--r--src/librustdoc/html/render/search_index.rs257
-rw-r--r--src/librustdoc/html/static/js/search.js120
-rw-r--r--src/librustdoc/json/conversions.rs4
-rw-r--r--src/tools/build_helper/src/git.rs38
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs49
-rw-r--r--src/tools/clippy/tests/ui/arithmetic_side_effects.rs30
-rw-r--r--src/tools/clippy/tests/ui/arithmetic_side_effects.stderr14
-rw-r--r--src/tools/miri/rust-version2
-rw-r--r--src/tools/miri/src/lib.rs1
-rw-r--r--src/tools/miri/src/shims/os_str.rs4
-rw-r--r--src/tools/miri/src/shims/unix/fs.rs4
-rw-r--r--src/tools/miri/tests/utils/fs.rs2
-rw-r--r--tests/codegen/lib-optimizations/iter-sum.rs15
-rw-r--r--tests/codegen/slice-as_chunks.rs6
-rw-r--r--tests/codegen/slice-iter-nonnull.rs6
-rw-r--r--tests/mir-opt/bool_compare.opt1.InstSimplify.diff3
-rw-r--r--tests/mir-opt/bool_compare.opt2.InstSimplify.diff3
-rw-r--r--tests/mir-opt/bool_compare.opt3.InstSimplify.diff3
-rw-r--r--tests/mir-opt/bool_compare.opt4.InstSimplify.diff3
-rw-r--r--tests/mir-opt/building/logical_or_in_conditional.rs39
-rw-r--r--tests/mir-opt/building/logical_or_in_conditional.test_complex.built.after.mir186
-rw-r--r--tests/mir-opt/building/logical_or_in_conditional.test_or.built.after.mir87
-rw-r--r--tests/mir-opt/const_goto_storage.match_nested_if.ConstGoto.diff6
-rw-r--r--tests/mir-opt/dataflow-const-prop/if.main.DataflowConstProp.diff10
-rw-r--r--tests/mir-opt/equal_true.opt.InstSimplify.diff3
-rw-r--r--tests/mir-opt/if_condition_int.dont_opt_floats.SimplifyComparisonIntegral.diff3
-rw-r--r--tests/mir-opt/if_condition_int.opt_char.SimplifyComparisonIntegral.diff6
-rw-r--r--tests/mir-opt/if_condition_int.opt_i8.SimplifyComparisonIntegral.diff6
-rw-r--r--tests/mir-opt/if_condition_int.opt_multiple_ifs.SimplifyComparisonIntegral.diff12
-rw-r--r--tests/mir-opt/if_condition_int.opt_negative.SimplifyComparisonIntegral.diff6
-rw-r--r--tests/mir-opt/if_condition_int.opt_u32.SimplifyComparisonIntegral.diff6
-rw-r--r--tests/mir-opt/inline/inline_diverging.g.Inline.panic-abort.diff3
-rw-r--r--tests/mir-opt/inline/inline_diverging.g.Inline.panic-unwind.diff3
-rw-r--r--tests/mir-opt/issue_99325.main.built.after.mir256
-rw-r--r--tests/mir-opt/lower_array_len.array_bound.NormalizeArrayLen.panic-abort.diff6
-rw-r--r--tests/mir-opt/lower_array_len.array_bound.NormalizeArrayLen.panic-unwind.diff6
-rw-r--r--tests/mir-opt/lower_array_len.array_bound_mut.NormalizeArrayLen.panic-abort.diff6
-rw-r--r--tests/mir-opt/lower_array_len.array_bound_mut.NormalizeArrayLen.panic-unwind.diff6
-rw-r--r--tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-abort.diff6
-rw-r--r--tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-unwind.diff6
-rw-r--r--tests/mir-opt/matches_reduce_branches.match_nested_if.MatchBranchSimplification.diff24
-rw-r--r--tests/mir-opt/not_equal_false.opt.InstSimplify.diff3
-rw-r--r--tests/mir-opt/pre-codegen/chained_comparison.naive.PreCodegen.after.mir135
-rw-r--r--tests/mir-opt/pre-codegen/chained_comparison.returning.PreCodegen.after.mir30
-rw-r--r--tests/mir-opt/pre-codegen/checked_ops.step_forward.PreCodegen.after.mir14
-rw-r--r--tests/mir-opt/pre-codegen/loops.int_range.PreCodegen.after.mir6
-rw-r--r--tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.mir34
-rw-r--r--tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-abort.mir6
-rw-r--r--tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-unwind.mir6
-rw-r--r--tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-abort.mir6
-rw-r--r--tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-unwind.mir6
-rw-r--r--tests/mir-opt/pre-codegen/slice_filter.variant_a-{closure#0}.PreCodegen.after.mir204
-rw-r--r--tests/mir-opt/pre-codegen/slice_filter.variant_b-{closure#0}.PreCodegen.after.mir47
-rw-r--r--tests/mir-opt/pre-codegen/slice_index.slice_get_mut_usize.PreCodegen.after.panic-abort.mir3
-rw-r--r--tests/mir-opt/pre-codegen/slice_index.slice_get_mut_usize.PreCodegen.after.panic-unwind.mir3
-rw-r--r--tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-abort.mir39
-rw-r--r--tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-unwind.mir39
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-abort.mir6
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir6
-rw-r--r--tests/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.panic-abort.mir86
-rw-r--r--tests/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.panic-unwind.mir86
-rw-r--r--tests/run-coverage/lazy_boolean.coverage2
-rw-r--r--tests/rustdoc-gui/sidebar.goml18
-rw-r--r--tests/rustdoc-js-std/full-path-function.js7
-rw-r--r--tests/rustdoc-js/full-path-function.js43
-rw-r--r--tests/rustdoc-js/full-path-function.rs17
-rw-r--r--tests/rustdoc/inline_cross/auxiliary/dyn_trait.rs19
-rw-r--r--tests/rustdoc/inline_cross/dyn_trait.rs15
-rw-r--r--tests/rustdoc/show-const-contents.rs2
-rw-r--r--tests/ui/argument-suggestions/two-mismatch-notes.stderr1
-rw-r--r--tests/ui/associated-consts/double-elided.rs12
-rw-r--r--tests/ui/associated-consts/double-elided.stderr47
-rw-r--r--tests/ui/associated-inherent-types/private-in-public.rs21
-rw-r--r--tests/ui/associated-inherent-types/private-in-public.stderr52
-rw-r--r--tests/ui/attributes/issue-115264-expr-field.rs17
-rw-r--r--tests/ui/attributes/issue-115264-pat-field.rs19
-rw-r--r--tests/ui/c-variadic/variadic-ffi-1.stderr2
-rw-r--r--tests/ui/const-generics/generic_const_exprs/eval-privacy.rs7
-rw-r--r--tests/ui/const-generics/generic_const_exprs/eval-privacy.stderr21
-rw-r--r--tests/ui/error-codes/E0445.rs23
-rw-r--r--tests/ui/error-codes/E0445.stderr71
-rw-r--r--tests/ui/error-codes/E0446.rs15
-rw-r--r--tests/ui/error-codes/E0446.stderr23
-rw-r--r--tests/ui/feature-gates/feature-gate-type_privacy_lints.rs6
-rw-r--r--tests/ui/feature-gates/feature-gate-type_privacy_lints.stderr70
-rw-r--r--tests/ui/fn/fn-pointer-mismatch.stderr1
-rw-r--r--tests/ui/fn/signature-error-reporting-under-verbose.rs1
-rw-r--r--tests/ui/fn/signature-error-reporting-under-verbose.stderr1
-rw-r--r--tests/ui/impl-trait/in-trait/lifetime-in-associated-trait-bound.rs19
-rw-r--r--tests/ui/imports/ambiguous-4.rs2
-rw-r--r--tests/ui/infinite/infinite-type-alias-mutual-recursion.feature.stderr27
-rw-r--r--tests/ui/infinite/infinite-type-alias-mutual-recursion.gated.stderr (renamed from tests/ui/infinite/infinite-type-alias-mutual-recursion.stderr)15
-rw-r--r--tests/ui/infinite/infinite-type-alias-mutual-recursion.rs10
-rw-r--r--tests/ui/infinite/infinite-vec-type-recursion.feature.stderr11
-rw-r--r--tests/ui/infinite/infinite-vec-type-recursion.gated.stderr (renamed from tests/ui/infinite/infinite-vec-type-recursion.stderr)11
-rw-r--r--tests/ui/infinite/infinite-vec-type-recursion.rs9
-rw-r--r--tests/ui/issues/issue-10764.stderr1
-rw-r--r--tests/ui/issues/issue-18389.rs10
-rw-r--r--tests/ui/issues/issue-18389.stderr28
-rw-r--r--tests/ui/lint/issue-99387.rs2
-rw-r--r--tests/ui/lint/lint-ctypes-fn.rs2
-rw-r--r--tests/ui/lint/lint-ctypes.rs2
-rw-r--r--tests/ui/lint/unused/unused-parens-issue-106413.rs32
-rw-r--r--tests/ui/lint/unused/unused-parens-issue-106413.stderr127
-rw-r--r--tests/ui/mismatched_types/normalize-fn-sig.stderr1
-rw-r--r--tests/ui/nll/missing-universe-cause-issue-114907.rs40
-rw-r--r--tests/ui/nll/missing-universe-cause-issue-114907.stderr79
-rw-r--r--tests/ui/privacy/associated-item-privacy-inherent.rs2
-rw-r--r--tests/ui/privacy/associated-item-privacy-trait.rs2
-rw-r--r--tests/ui/privacy/associated-item-privacy-type-binding.rs2
-rw-r--r--tests/ui/privacy/effective_visibilities_full_priv.rs2
-rw-r--r--tests/ui/privacy/issue-30079.rs3
-rw-r--r--tests/ui/privacy/issue-30079.stderr17
-rw-r--r--tests/ui/privacy/private-in-public-assoc-ty.rs9
-rw-r--r--tests/ui/privacy/private-in-public-assoc-ty.stderr50
-rw-r--r--tests/ui/privacy/private-in-public-lint.rs19
-rw-r--r--tests/ui/privacy/private-in-public-lint.stderr21
-rw-r--r--tests/ui/privacy/private-in-public-non-principal-2.rs2
-rw-r--r--tests/ui/privacy/private-in-public-non-principal.rs10
-rw-r--r--tests/ui/privacy/private-in-public-non-principal.stderr28
-rw-r--r--tests/ui/privacy/private-in-public-type-alias-impl-trait.rs2
-rw-r--r--tests/ui/privacy/private-in-public-warn.rs85
-rw-r--r--tests/ui/privacy/private-in-public-warn.stderr376
-rw-r--r--tests/ui/privacy/private-in-public.rs66
-rw-r--r--tests/ui/privacy/private-in-public.stderr468
-rw-r--r--tests/ui/privacy/private-inferred-type-2.rs1
-rw-r--r--tests/ui/privacy/private-inferred-type-2.stderr6
-rw-r--r--tests/ui/privacy/private-inferred-type.rs2
-rw-r--r--tests/ui/privacy/private-type-in-interface.rs1
-rw-r--r--tests/ui/privacy/private-type-in-interface.stderr18
-rw-r--r--tests/ui/privacy/restricted/private-in-public.rs5
-rw-r--r--tests/ui/privacy/restricted/private-in-public.stderr21
-rw-r--r--tests/ui/privacy/unnameable_types.rs1
-rw-r--r--tests/ui/privacy/unnameable_types.stderr8
-rw-r--r--tests/ui/privacy/where-priv-type.rs27
-rw-r--r--tests/ui/privacy/where-priv-type.stderr107
-rw-r--r--tests/ui/privacy/where-pub-type-impls-priv-trait.rs23
-rw-r--r--tests/ui/privacy/where-pub-type-impls-priv-trait.stderr84
-rw-r--r--tests/ui/proc-macro/allowed-signatures.rs2
-rw-r--r--tests/ui/pub/issue-33174-restricted-type-in-public-interface.rs30
-rw-r--r--tests/ui/pub/issue-33174-restricted-type-in-public-interface.stderr48
-rw-r--r--tests/ui/range/range-1.stderr2
-rw-r--r--tests/ui/regions/region-lifetime-bounds-on-fns-where-clause.stderr1
-rw-r--r--tests/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.stderr1
-rw-r--r--tests/ui/regions/regions-fn-subtyping-return-static-fail.stderr1
-rw-r--r--tests/ui/regions/regions-lifetime-bounds-on-fns.stderr1
-rw-r--r--tests/ui/reify-intrinsic.stderr1
-rw-r--r--tests/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.mir.stderr1
-rw-r--r--tests/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.thir.stderr1
-rw-r--r--tests/ui/rfcs/rfc-2497-if-let-chains/chains-without-let.rs5
-rw-r--r--tests/ui/rfcs/rfc-2497-if-let-chains/chains-without-let.stderr33
-rw-r--r--tests/ui/static/static-reference-to-fn-1.stderr1
-rw-r--r--tests/ui/test-attrs/issue-36768.rs2
-rw-r--r--tests/ui/transmutability/visibility/assume/should_accept_if_dst_has_unreachable_field.rs4
-rw-r--r--tests/ui/transmutability/visibility/assume/should_accept_if_dst_has_unreachable_field.stderr19
-rw-r--r--tests/ui/transmutability/visibility/should_accept_if_src_has_unreachable_field.rs4
-rw-r--r--tests/ui/transmutability/visibility/should_accept_if_src_has_unreachable_field.stderr19
-rw-r--r--tests/ui/type-alias-impl-trait/privacy.rs4
-rw-r--r--tests/ui/type-alias-impl-trait/privacy.stderr18
-rw-r--r--tests/ui/unsafe/initializing-ranged-via-ctor.rs11
-rw-r--r--tests/ui/unsafe/initializing-ranged-via-ctor.stderr16
-rw-r--r--tests/ui/unsafe/ranged-ctor-as-fn-ptr.rs10
-rw-r--r--tests/ui/unsafe/ranged-ctor-as-fn-ptr.stderr15
-rw-r--r--triagebot.toml2
251 files changed, 3878 insertions, 3081 deletions
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index a4ba1a5c9bf..a6d1ef33f40 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -153,6 +153,7 @@ trait ResolverAstLoweringExt {
     fn get_label_res(&self, id: NodeId) -> Option<NodeId>;
     fn get_lifetime_res(&self, id: NodeId) -> Option<LifetimeRes>;
     fn take_extra_lifetime_params(&mut self, id: NodeId) -> Vec<(Ident, NodeId, LifetimeRes)>;
+    fn remap_extra_lifetime_params(&mut self, from: NodeId, to: NodeId);
     fn decl_macro_kind(&self, def_id: LocalDefId) -> MacroKind;
 }
 
@@ -213,6 +214,11 @@ impl ResolverAstLoweringExt for ResolverAstLowering {
         self.extra_lifetime_params_map.remove(&id).unwrap_or_default()
     }
 
+    fn remap_extra_lifetime_params(&mut self, from: NodeId, to: NodeId) {
+        let lifetimes = self.extra_lifetime_params_map.remove(&from).unwrap_or_default();
+        self.extra_lifetime_params_map.insert(to, lifetimes);
+    }
+
     fn decl_macro_kind(&self, def_id: LocalDefId) -> MacroKind {
         self.builtin_macro_kinds.get(&def_id).copied().unwrap_or(MacroKind::Bang)
     }
@@ -1089,6 +1095,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                         // constructing the HIR for `impl bounds...` and then lowering that.
 
                         let impl_trait_node_id = self.next_node_id();
+                        // Shift `impl Trait` lifetime captures from the associated type bound's
+                        // node id to the opaque node id, so that the opaque can actually use
+                        // these lifetime bounds.
+                        self.resolver
+                            .remap_extra_lifetime_params(constraint.id, impl_trait_node_id);
 
                         self.with_dyn_type_scope(false, |this| {
                             let node_id = this.next_node_id();
diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs
index b8cd94e5422..1049e7a8bbe 100644
--- a/compiler/rustc_borrowck/src/region_infer/mod.rs
+++ b/compiler/rustc_borrowck/src/region_infer/mod.rs
@@ -2249,7 +2249,14 @@ impl<'tcx> RegionInferenceContext<'tcx> {
     }
 
     pub(crate) fn universe_info(&self, universe: ty::UniverseIndex) -> UniverseInfo<'tcx> {
-        self.universe_causes[&universe].clone()
+        // Query canonicalization can create local superuniverses (for example in
+        // `InferCtx::query_response_substitution_guess`), but they don't have an associated
+        // `UniverseInfo` explaining why they were created.
+        // This can cause ICEs if these causes are accessed in diagnostics, for example in issue
+        // #114907 where this happens via liveness and dropck outlives results.
+        // Therefore, we return a default value in case that happens, which should at worst emit a
+        // suboptimal error, instead of the ICE.
+        self.universe_causes.get(&universe).cloned().unwrap_or_else(|| UniverseInfo::other())
     }
 
     /// Tries to find the terminator of the loop in which the region 'r' resides.
diff --git a/compiler/rustc_borrowck/src/type_check/canonical.rs b/compiler/rustc_borrowck/src/type_check/canonical.rs
index 16f5e68a06f..b7adc314f07 100644
--- a/compiler/rustc_borrowck/src/type_check/canonical.rs
+++ b/compiler/rustc_borrowck/src/type_check/canonical.rs
@@ -9,7 +9,7 @@ use rustc_span::Span;
 use rustc_trait_selection::traits::query::type_op::{self, TypeOpOutput};
 use rustc_trait_selection::traits::ObligationCause;
 
-use crate::diagnostics::{ToUniverseInfo, UniverseInfo};
+use crate::diagnostics::ToUniverseInfo;
 
 use super::{Locations, NormalizeLocation, TypeChecker};
 
@@ -46,13 +46,11 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
             self.push_region_constraints(locations, category, data);
         }
 
+        // If the query has created new universes and errors are going to be emitted, register the
+        // cause of these new universes for improved diagnostics.
         let universe = self.infcx.universe();
-
-        if old_universe != universe {
-            let universe_info = match error_info {
-                Some(error_info) => error_info.to_universe_info(old_universe),
-                None => UniverseInfo::other(),
-            };
+        if old_universe != universe && let Some(error_info) = error_info {
+            let universe_info = error_info.to_universe_info(old_universe);
             for u in (old_universe + 1)..=universe {
                 self.borrowck_context.constraints.universe_causes.insert(u, universe_info.clone());
             }
@@ -69,15 +67,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
     where
         T: TypeFoldable<TyCtxt<'tcx>>,
     {
-        let old_universe = self.infcx.universe();
-
         let (instantiated, _) =
             self.infcx.instantiate_canonical_with_fresh_inference_vars(span, canonical);
-
-        for u in (old_universe + 1)..=self.infcx.universe() {
-            self.borrowck_context.constraints.universe_causes.insert(u, UniverseInfo::other());
-        }
-
         instantiated
     }
 
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index 3004291c3e7..28286243e82 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -163,10 +163,6 @@ pub(crate) fn type_check<'mir, 'tcx>(
 
     debug!(?normalized_inputs_and_output);
 
-    for u in ty::UniverseIndex::ROOT..=infcx.universe() {
-        constraints.universe_causes.insert(u, UniverseInfo::other());
-    }
-
     let mut borrowck_context = BorrowCheckContext {
         universal_regions,
         location_table,
diff --git a/compiler/rustc_codegen_llvm/src/back/archive.rs b/compiler/rustc_codegen_llvm/src/back/archive.rs
index a82d2c5771a..f33075a8879 100644
--- a/compiler/rustc_codegen_llvm/src/back/archive.rs
+++ b/compiler/rustc_codegen_llvm/src/back/archive.rs
@@ -367,7 +367,7 @@ impl<'a> LlvmArchiveBuilder<'a> {
                 match addition {
                     Addition::File { path, name_in_archive } => {
                         let path = CString::new(path.to_str().unwrap())?;
-                        let name = CString::new(name_in_archive.clone())?;
+                        let name = CString::new(name_in_archive.as_bytes())?;
                         members.push(llvm::LLVMRustArchiveMemberNew(
                             path.as_ptr(),
                             name.as_ptr(),
diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs
index b2d28cef899..c1d3392386c 100644
--- a/compiler/rustc_codegen_llvm/src/back/lto.rs
+++ b/compiler/rustc_codegen_llvm/src/back/lto.rs
@@ -441,7 +441,7 @@ fn thin_lto(
 
         for (i, (name, buffer)) in modules.into_iter().enumerate() {
             info!("local module: {} - {}", i, name);
-            let cname = CString::new(name.clone()).unwrap();
+            let cname = CString::new(name.as_bytes()).unwrap();
             thin_modules.push(llvm::ThinLTOModule {
                 identifier: cname.as_ptr(),
                 data: buffer.data().as_ptr(),
diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs
index a016bfa5cf8..ca66c4cfb63 100644
--- a/compiler/rustc_const_eval/src/interpret/terminator.rs
+++ b/compiler/rustc_const_eval/src/interpret/terminator.rs
@@ -254,6 +254,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
     }
 
     /// Find the wrapped inner type of a transparent wrapper.
+    /// Must not be called on 1-ZST (as they don't have a uniquely defined "wrapped field").
     fn unfold_transparent(&self, layout: TyAndLayout<'tcx>) -> TyAndLayout<'tcx> {
         match layout.ty.kind() {
             ty::Adt(adt_def, _) if adt_def.repr().transparent() => {
@@ -263,11 +264,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                     let field = layout.field(self, idx);
                     if field.is_1zst() { None } else { Some(field) }
                 });
-                let Some(first) = non_1zst_fields.next() else {
-                    // All fields are 1-ZST, so this is basically the same as `()`.
-                    // (We still also compare the `PassMode`, so if this target does something strange with 1-ZST there, we'll know.)
-                    return self.layout_of(self.tcx.types.unit).unwrap();
-                };
+                let first = non_1zst_fields.next().expect("`unfold_transparent` called on 1-ZST");
                 assert!(
                     non_1zst_fields.next().is_none(),
                     "more than one non-1-ZST field in a transparent type"
@@ -289,17 +286,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         caller_layout: TyAndLayout<'tcx>,
         callee_layout: TyAndLayout<'tcx>,
     ) -> bool {
-        fn primitive_abi_compat(a1: abi::Primitive, a2: abi::Primitive) -> bool {
-            match (a1, a2) {
-                // For integers, ignore the sign.
-                (abi::Primitive::Int(int_ty1, _sign1), abi::Primitive::Int(int_ty2, _sign2)) => {
-                    int_ty1 == int_ty2
-                }
-                // For everything else we require full equality.
-                _ => a1 == a2,
-            }
-        }
-
         if caller_layout.ty == callee_layout.ty {
             // Fast path: equal types are definitely compatible.
             return true;
@@ -308,27 +294,40 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         match (caller_layout.abi, callee_layout.abi) {
             // If both sides have Scalar/Vector/ScalarPair ABI, we can easily directly compare them.
             // Different valid ranges are okay (the validity check will complain if this leads to
-            // invalid transmutes).
+            // invalid transmutes). Different signs are *not* okay on some targets (e.g. `extern
+            // "C"` on `s390x` where small integers are passed zero/sign-extended in large
+            // registers), so we generally reject them to increase portability.
+            // NOTE: this is *not* a stable guarantee! It just reflects a property of our current
+            // ABIs. It's also fragile; the same pair of types might be considered ABI-compatible
+            // when used directly by-value but not considered compatible as a struct field or array
+            // element.
             (abi::Abi::Scalar(caller), abi::Abi::Scalar(callee)) => {
-                primitive_abi_compat(caller.primitive(), callee.primitive())
+                caller.primitive() == callee.primitive()
             }
             (
                 abi::Abi::Vector { element: caller_element, count: caller_count },
                 abi::Abi::Vector { element: callee_element, count: callee_count },
             ) => {
-                primitive_abi_compat(caller_element.primitive(), callee_element.primitive())
+                caller_element.primitive() == callee_element.primitive()
                     && caller_count == callee_count
             }
             (abi::Abi::ScalarPair(caller1, caller2), abi::Abi::ScalarPair(callee1, callee2)) => {
-                primitive_abi_compat(caller1.primitive(), callee1.primitive())
-                    && primitive_abi_compat(caller2.primitive(), callee2.primitive())
+                caller1.primitive() == callee1.primitive()
+                    && caller2.primitive() == callee2.primitive()
             }
             (abi::Abi::Aggregate { .. }, abi::Abi::Aggregate { .. }) => {
-                // Aggregates are compatible only if they newtype-wrap the same type.
+                // Aggregates are compatible only if they newtype-wrap the same type, or if they are both 1-ZST.
+                // (The latter part is needed to ensure e.g. that `struct Zst` is compatible with `struct Wrap((), Zst)`.)
                 // This is conservative, but also means that our check isn't quite so heavily dependent on the `PassMode`,
                 // which means having ABI-compatibility on one target is much more likely to imply compatibility for other targets.
-                self.unfold_transparent(caller_layout).ty
-                    == self.unfold_transparent(callee_layout).ty
+                if caller_layout.is_1zst() || callee_layout.is_1zst() {
+                    // If either is a 1-ZST, both must be.
+                    caller_layout.is_1zst() && callee_layout.is_1zst()
+                } else {
+                    // Neither is a 1-ZST, so we can check what they are wrapping.
+                    self.unfold_transparent(caller_layout).ty
+                        == self.unfold_transparent(callee_layout).ty
+                }
             }
             // What remains is `Abi::Uninhabited` (which can never be passed anyway) and
             // mismatching ABIs, that should all be rejected.
diff --git a/compiler/rustc_data_structures/src/sync.rs b/compiler/rustc_data_structures/src/sync.rs
index 2ec509b9118..e82b0f6d496 100644
--- a/compiler/rustc_data_structures/src/sync.rs
+++ b/compiler/rustc_data_structures/src/sync.rs
@@ -273,7 +273,7 @@ cfg_if! {
         pub use std::cell::RefMut as MappedWriteGuard;
         pub use std::cell::RefMut as MappedLockGuard;
 
-        pub use std::cell::OnceCell;
+        pub use std::cell::OnceCell as OnceLock;
 
         use std::cell::RefCell as InnerRwLock;
 
@@ -327,7 +327,7 @@ cfg_if! {
 
         pub use parking_lot::MappedMutexGuard as MappedLockGuard;
 
-        pub use std::sync::OnceLock as OnceCell;
+        pub use std::sync::OnceLock;
 
         pub use std::sync::atomic::{AtomicBool, AtomicUsize, AtomicU32, AtomicU64};
 
diff --git a/compiler/rustc_error_codes/src/error_codes.rs b/compiler/rustc_error_codes/src/error_codes.rs
index 2daf591bd65..89c44c6ec8a 100644
--- a/compiler/rustc_error_codes/src/error_codes.rs
+++ b/compiler/rustc_error_codes/src/error_codes.rs
@@ -608,6 +608,7 @@ E0794: include_str!("./error_codes/E0794.md"),
 //  E0420, // merged into 532
 //  E0421, // merged into 531
 //  E0427, // merged into 530
+//  E0445, // merged into 446 and type privacy lints
 //  E0456, // plugin `..` is not available for triple `..`
 //  E0465, // removed: merged with E0464
 //  E0467, // removed
diff --git a/compiler/rustc_error_codes/src/error_codes/E0445.md b/compiler/rustc_error_codes/src/error_codes/E0445.md
index e6a28a9c2c4..d47393194c5 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0445.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0445.md
@@ -1,10 +1,10 @@
-A private trait was used on a public type parameter bound.
+#### Note: this error code is no longer emitted by the compiler.
 
-Erroneous code examples:
+A private trait was used on a public type parameter bound.
 
-```compile_fail,E0445
-#![deny(private_in_public)]
+Previously erroneous code examples:
 
+```
 trait Foo {
     fn dummy(&self) { }
 }
diff --git a/compiler/rustc_error_codes/src/error_codes/E0446.md b/compiler/rustc_error_codes/src/error_codes/E0446.md
index 6ec47c4962c..ebbd83c683c 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0446.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0446.md
@@ -1,16 +1,16 @@
-A private type was used in a public type signature.
+A private type or trait was used in a public associated type signature.
 
 Erroneous code example:
 
 ```compile_fail,E0446
-#![deny(private_in_public)]
-struct Bar(u32);
-
-mod foo {
-    use crate::Bar;
-    pub fn bar() -> Bar { // error: private type in public interface
-        Bar(0)
-    }
+struct Bar;
+
+pub trait PubTr {
+    type Alias;
+}
+
+impl PubTr for u8 {
+    type Alias = Bar; // error private type in public interface
 }
 
 fn main() {}
@@ -22,13 +22,14 @@ This is done by using pub(crate) or pub(in crate::my_mod::etc)
 Example:
 
 ```
-struct Bar(u32);
+struct Bar;
+
+pub(crate) trait PubTr { // only public to crate root
+    type Alias;
+}
 
-mod foo {
-    use crate::Bar;
-    pub(crate) fn bar() -> Bar { // only public to crate root
-        Bar(0)
-    }
+impl PubTr for u8 {
+    type Alias = Bar;
 }
 
 fn main() {}
@@ -38,12 +39,15 @@ The other way to solve this error is to make the private type public.
 Example:
 
 ```
-pub struct Bar(u32); // we set the Bar type public
-mod foo {
-    use crate::Bar;
-    pub fn bar() -> Bar { // ok!
-        Bar(0)
-    }
+
+pub struct Bar; // we set the Bar trait public
+
+pub trait PubTr {
+    type Alias;
+}
+
+impl PubTr for u8 {
+    type Alias = Bar;
 }
 
 fn main() {}
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index c2fe942fe37..9bb1a6a2b14 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -55,6 +55,8 @@ use std::num::NonZeroUsize;
 use std::panic;
 use std::path::{Path, PathBuf};
 
+// Used by external projects such as `rust-gpu`.
+// See https://github.com/rust-lang/rust/pull/115393.
 pub use termcolor::{Color, ColorSpec, WriteColor};
 
 pub mod annotate_snippet_emitter_writer;
diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs
index b1f74643b69..afcf30d0b29 100644
--- a/compiler/rustc_feature/src/accepted.rs
+++ b/compiler/rustc_feature/src/accepted.rs
@@ -54,7 +54,7 @@ declare_features! (
     /// instead of just the platforms on which it is the C ABI.
     (accepted, abi_sysv64, "1.24.0", Some(36167), None),
     /// Allows using the `thiscall` ABI.
-    (accepted, abi_thiscall, "1.19.0", None, None),
+    (accepted, abi_thiscall, "1.73.0", None, None),
     /// Allows using ADX intrinsics from `core::arch::{x86, x86_64}`.
     (accepted, adx_target_feature, "1.61.0", Some(44839), None),
     /// Allows explicit discriminants on non-unit enum variants.
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 0bfd62d68b2..a9b25a390b3 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -3729,6 +3729,8 @@ impl<'hir> Node<'hir> {
             Node::Lifetime(lt) => Some(lt.ident),
             Node::GenericParam(p) => Some(p.name.ident()),
             Node::TypeBinding(b) => Some(b.ident),
+            Node::PatField(f) => Some(f.ident),
+            Node::ExprField(f) => Some(f.ident),
             Node::Param(..)
             | Node::AnonConst(..)
             | Node::ConstBlock(..)
@@ -3737,8 +3739,6 @@ impl<'hir> Node<'hir> {
             | Node::Block(..)
             | Node::Ctor(..)
             | Node::Pat(..)
-            | Node::PatField(..)
-            | Node::ExprField(..)
             | Node::Arm(..)
             | Node::Local(..)
             | Node::Crate(..)
diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs
index 668763f9bf6..7a6856fb1f4 100644
--- a/compiler/rustc_hir_analysis/src/astconv/mod.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs
@@ -910,19 +910,24 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
     ) -> Ty<'tcx> {
         let tcx = self.tcx();
         let args = self.ast_path_args_for_ty(span, did, item_segment);
-        let ty = tcx.at(span).type_of(did);
 
-        if let DefKind::TyAlias { lazy } = tcx.def_kind(did)
-            && (lazy || ty.skip_binder().has_opaque_types())
-        {
-            // Type aliases referring to types that contain opaque types (but aren't just directly
-            // referencing a single opaque type) as well as those defined in crates that have the
+        if let DefKind::TyAlias { lazy: true } = tcx.def_kind(did) {
+            // Type aliases defined in crates that have the
             // feature `lazy_type_alias` enabled get encoded as a type alias that normalization will
             // then actually instantiate the where bounds of.
             let alias_ty = tcx.mk_alias_ty(did, args);
             Ty::new_alias(tcx, ty::Weak, alias_ty)
         } else {
-            ty.instantiate(tcx, args)
+            let ty = tcx.at(span).type_of(did);
+            if ty.skip_binder().has_opaque_types() {
+                // Type aliases referring to types that contain opaque types (but aren't just directly
+                // referencing a single opaque type) get encoded as a type alias that normalization will
+                // then actually instantiate the where bounds of.
+                let alias_ty = tcx.mk_alias_ty(did, args);
+                Ty::new_alias(tcx, ty::Weak, alias_ty)
+            } else {
+                ty.instantiate(tcx, args)
+            }
         }
     }
 
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index 334e0541c76..01e40c62a8b 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -38,6 +38,7 @@ use rustc_trait_selection::infer::InferCtxtExt;
 use rustc_trait_selection::traits::error_reporting::suggestions::NextTypeParamName;
 use rustc_trait_selection::traits::ObligationCtxt;
 use std::iter;
+use std::ops::Bound;
 
 mod generics_of;
 mod item_bounds;
@@ -1144,15 +1145,15 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<ty::PolyFnSig<
         }
 
         Ctor(data) | Variant(hir::Variant { data, .. }) if data.ctor().is_some() => {
-            let ty = tcx.type_of(tcx.hir().get_parent_item(hir_id)).instantiate_identity();
+            let adt_def_id = tcx.hir().get_parent_item(hir_id).def_id.to_def_id();
+            let ty = tcx.type_of(adt_def_id).instantiate_identity();
             let inputs = data.fields().iter().map(|f| tcx.type_of(f.def_id).instantiate_identity());
-            ty::Binder::dummy(tcx.mk_fn_sig(
-                inputs,
-                ty,
-                false,
-                hir::Unsafety::Normal,
-                abi::Abi::Rust,
-            ))
+            // constructors for structs with `layout_scalar_valid_range` are unsafe to call
+            let safety = match tcx.layout_scalar_valid_range(adt_def_id) {
+                (Bound::Unbounded, Bound::Unbounded) => hir::Unsafety::Normal,
+                _ => hir::Unsafety::Unsafe,
+            };
+            ty::Binder::dummy(tcx.mk_fn_sig(inputs, ty, false, safety, abi::Abi::Rust))
         }
 
         Expr(&hir::Expr { kind: hir::ExprKind::Closure { .. }, .. }) => {
diff --git a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs
index 372539d73b1..445f68160d2 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs
@@ -266,12 +266,10 @@ impl<T> Trait<T> for X {
                             }
                         }
                     }
-                    (ty::FnPtr(_), ty::FnDef(def, _))
-                    if let hir::def::DefKind::Fn = tcx.def_kind(def) => {
-                        diag.note(
-                            "when the arguments and return types match, functions can be coerced \
-                             to function pointers",
-                        );
+                    (ty::FnPtr(sig), ty::FnDef(def_id, _)) | (ty::FnDef(def_id, _), ty::FnPtr(sig)) => {
+                        if tcx.fn_sig(*def_id).skip_binder().unsafety() < sig.unsafety() {
+                            diag.note("unsafe functions cannot be coerced into safe function pointers");
+                        }
                     }
                     _ => {}
                 }
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index c8b1ba5694e..9fcaf643179 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -8,7 +8,7 @@ use rustc_borrowck as mir_borrowck;
 use rustc_codegen_ssa::traits::CodegenBackend;
 use rustc_data_structures::parallel;
 use rustc_data_structures::steal::Steal;
-use rustc_data_structures::sync::{Lrc, OnceCell, WorkerLocal};
+use rustc_data_structures::sync::{Lrc, OnceLock, WorkerLocal};
 use rustc_errors::PResult;
 use rustc_expand::base::{ExtCtxt, LintStoreExpand};
 use rustc_feature::Features;
@@ -689,7 +689,7 @@ pub fn create_global_ctxt<'tcx>(
     lint_store: Lrc<LintStore>,
     dep_graph: DepGraph,
     untracked: Untracked,
-    gcx_cell: &'tcx OnceCell<GlobalCtxt<'tcx>>,
+    gcx_cell: &'tcx OnceLock<GlobalCtxt<'tcx>>,
     arena: &'tcx WorkerLocal<Arena<'tcx>>,
     hir_arena: &'tcx WorkerLocal<rustc_hir::Arena<'tcx>>,
 ) -> &'tcx GlobalCtxt<'tcx> {
diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs
index fc71c6c7e9a..2db7aa0e367 100644
--- a/compiler/rustc_interface/src/queries.rs
+++ b/compiler/rustc_interface/src/queries.rs
@@ -7,7 +7,7 @@ use rustc_codegen_ssa::traits::CodegenBackend;
 use rustc_codegen_ssa::CodegenResults;
 use rustc_data_structures::steal::Steal;
 use rustc_data_structures::svh::Svh;
-use rustc_data_structures::sync::{AppendOnlyIndexVec, Lrc, OnceCell, RwLock, WorkerLocal};
+use rustc_data_structures::sync::{AppendOnlyIndexVec, Lrc, OnceLock, RwLock, WorkerLocal};
 use rustc_hir::def_id::{StableCrateId, CRATE_DEF_ID, LOCAL_CRATE};
 use rustc_hir::definitions::Definitions;
 use rustc_incremental::DepGraphFuture;
@@ -78,7 +78,7 @@ impl<T> Default for Query<T> {
 
 pub struct Queries<'tcx> {
     compiler: &'tcx Compiler,
-    gcx_cell: OnceCell<GlobalCtxt<'tcx>>,
+    gcx_cell: OnceLock<GlobalCtxt<'tcx>>,
 
     arena: WorkerLocal<Arena<'tcx>>,
     hir_arena: WorkerLocal<rustc_hir::Arena<'tcx>>,
@@ -93,7 +93,7 @@ impl<'tcx> Queries<'tcx> {
     pub fn new(compiler: &'tcx Compiler) -> Queries<'tcx> {
         Queries {
             compiler,
-            gcx_cell: OnceCell::new(),
+            gcx_cell: OnceLock::new(),
             arena: WorkerLocal::new(|_| Arena::default()),
             hir_arena: WorkerLocal::new(|_| rustc_hir::Arena::default()),
             parse: Default::default(),
diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs
index 211ea8f4347..d102e3a6c15 100644
--- a/compiler/rustc_lint/src/early.rs
+++ b/compiler/rustc_lint/src/early.rs
@@ -228,6 +228,7 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T>
             }) => self.check_id(closure_id),
             _ => {}
         }
+        lint_callback!(self, check_expr_post, e);
     }
 
     fn visit_generic_arg(&mut self, arg: &'a ast::GenericArg) {
diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs
index e578f09b58f..84434d585d3 100644
--- a/compiler/rustc_lint/src/lib.rs
+++ b/compiler/rustc_lint/src/lib.rs
@@ -500,6 +500,11 @@ fn register_builtins(store: &mut LintStore) {
         "converted into hard error, see issue #82523 \
          <https://github.com/rust-lang/rust/issues/82523> for more information",
     );
+    store.register_removed(
+        "private_in_public",
+        "replaced with another group of lints, see RFC \
+         <https://rust-lang.github.io/rfcs/2145-type-privacy.html> for more information",
+    );
 }
 
 fn register_internals(store: &mut LintStore) {
diff --git a/compiler/rustc_lint/src/passes.rs b/compiler/rustc_lint/src/passes.rs
index 16964565b01..fca0eeeecc4 100644
--- a/compiler/rustc_lint/src/passes.rs
+++ b/compiler/rustc_lint/src/passes.rs
@@ -153,6 +153,7 @@ macro_rules! early_lint_methods {
             fn check_pat(a: &ast::Pat);
             fn check_pat_post(a: &ast::Pat);
             fn check_expr(a: &ast::Expr);
+            fn check_expr_post(a: &ast::Expr);
             fn check_ty(a: &ast::Ty);
             fn check_generic_arg(a: &ast::GenericArg);
             fn check_generic_param(a: &ast::GenericParam);
diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs
index 6041f80753b..39e6fb805ae 100644
--- a/compiler/rustc_lint/src/unused.rs
+++ b/compiler/rustc_lint/src/unused.rs
@@ -955,11 +955,14 @@ declare_lint! {
 
 pub struct UnusedParens {
     with_self_ty_parens: bool,
+    /// `1 as (i32) < 2` parses to ExprKind::Lt
+    /// `1 as i32 < 2` parses to i32::<2[missing angle bracket]
+    parens_in_cast_in_lt: Vec<ast::NodeId>,
 }
 
 impl UnusedParens {
     pub fn new() -> Self {
-        Self { with_self_ty_parens: false }
+        Self { with_self_ty_parens: false, parens_in_cast_in_lt: Vec::new() }
     }
 }
 
@@ -1055,6 +1058,14 @@ impl UnusedParens {
 impl EarlyLintPass for UnusedParens {
     #[inline]
     fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) {
+        if let ExprKind::Binary(op, lhs, _rhs) = &e.kind &&
+            (op.node == ast::BinOpKind::Lt || op.node == ast::BinOpKind::Shl) &&
+            let ExprKind::Cast(_expr, ty) = &lhs.kind &&
+            let ast::TyKind::Paren(_) = &ty.kind
+        {
+            self.parens_in_cast_in_lt.push(ty.id);
+        }
+
         match e.kind {
             ExprKind::Let(ref pat, _, _) | ExprKind::ForLoop(ref pat, ..) => {
                 self.check_unused_parens_pat(cx, pat, false, false, (true, true));
@@ -1101,6 +1112,17 @@ impl EarlyLintPass for UnusedParens {
         <Self as UnusedDelimLint>::check_expr(self, cx, e)
     }
 
+    fn check_expr_post(&mut self, _cx: &EarlyContext<'_>, e: &ast::Expr) {
+        if let ExprKind::Binary(op, lhs, _rhs) = &e.kind &&
+            (op.node == ast::BinOpKind::Lt || op.node == ast::BinOpKind::Shl) &&
+            let ExprKind::Cast(_expr, ty) = &lhs.kind &&
+            let ast::TyKind::Paren(_) = &ty.kind
+        {
+            let id = self.parens_in_cast_in_lt.pop().expect("check_expr and check_expr_post must balance");
+            assert_eq!(id, ty.id, "check_expr, check_ty, and check_expr_post are called, in that order, by the visitor");
+        }
+    }
+
     fn check_pat(&mut self, cx: &EarlyContext<'_>, p: &ast::Pat) {
         use ast::{Mutability, PatKind::*};
         let keep_space = (false, false);
@@ -1141,6 +1163,11 @@ impl EarlyLintPass for UnusedParens {
     }
 
     fn check_ty(&mut self, cx: &EarlyContext<'_>, ty: &ast::Ty) {
+        if let ast::TyKind::Paren(_) = ty.kind &&
+            Some(&ty.id) == self.parens_in_cast_in_lt.last()
+        {
+            return;
+        }
         match &ty.kind {
             ast::TyKind::Array(_, len) => {
                 self.check_unused_delims_expr(
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index 0aa37642b74..7e745de4f1a 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -983,44 +983,6 @@ declare_lint! {
 }
 
 declare_lint! {
-    /// The `private_in_public` lint detects private items in public
-    /// interfaces not caught by the old implementation.
-    ///
-    /// ### Example
-    ///
-    /// ```rust
-    /// # #![allow(unused)]
-    /// struct SemiPriv;
-    ///
-    /// mod m1 {
-    ///     struct Priv;
-    ///     impl super::SemiPriv {
-    ///         pub fn f(_: Priv) {}
-    ///     }
-    /// }
-    /// # fn main() {}
-    /// ```
-    ///
-    /// {{produces}}
-    ///
-    /// ### Explanation
-    ///
-    /// The visibility rules are intended to prevent exposing private items in
-    /// public interfaces. This is a [future-incompatible] lint to transition
-    /// this to a hard error in the future. See [issue #34537] for more
-    /// details.
-    ///
-    /// [issue #34537]: https://github.com/rust-lang/rust/issues/34537
-    /// [future-incompatible]: ../index.md#future-incompatible-lints
-    pub PRIVATE_IN_PUBLIC,
-    Warn,
-    "detect private items in public interfaces not caught by the old implementation",
-    @future_incompatible = FutureIncompatibleInfo {
-        reference: "issue #34537 <https://github.com/rust-lang/rust/issues/34537>",
-    };
-}
-
-declare_lint! {
     /// The `invalid_alignment` lint detects dereferences of misaligned pointers during
     /// constant evaluation.
     ///
@@ -3415,7 +3377,6 @@ declare_lint_pass! {
         PATTERNS_IN_FNS_WITHOUT_BODY,
         POINTER_STRUCTURAL_MATCH,
         PRIVATE_BOUNDS,
-        PRIVATE_IN_PUBLIC,
         PRIVATE_INTERFACES,
         PROC_MACRO_BACK_COMPAT,
         PROC_MACRO_DERIVE_RESOLUTION_FALLBACK,
@@ -4334,9 +4295,7 @@ declare_lint! {
     /// ### Example
     ///
     /// ```rust,compile_fail
-    /// # #![feature(type_privacy_lints)]
     /// # #![allow(unused)]
-    /// # #![allow(private_in_public)]
     /// #![deny(private_interfaces)]
     /// struct SemiPriv;
     ///
@@ -4357,9 +4316,8 @@ declare_lint! {
     /// Having something private in primary interface guarantees that
     /// the item will be unusable from outer modules due to type privacy.
     pub PRIVATE_INTERFACES,
-    Allow,
+    Warn,
     "private type in primary interface of an item",
-    @feature_gate = sym::type_privacy_lints;
 }
 
 declare_lint! {
@@ -4370,8 +4328,6 @@ declare_lint! {
     /// ### Example
     ///
     /// ```rust,compile_fail
-    /// # #![feature(type_privacy_lints)]
-    /// # #![allow(private_in_public)]
     /// # #![allow(unused)]
     /// #![deny(private_bounds)]
     ///
@@ -4389,9 +4345,8 @@ declare_lint! {
     /// Having private types or traits in item bounds makes it less clear what interface
     /// the item actually provides.
     pub PRIVATE_BOUNDS,
-    Allow,
+    Warn,
     "private type in secondary interface of an item",
-    @feature_gate = sym::type_privacy_lints;
 }
 
 declare_lint! {
diff --git a/compiler/rustc_llvm/build.rs b/compiler/rustc_llvm/build.rs
index 4302b161833..f606fa483ca 100644
--- a/compiler/rustc_llvm/build.rs
+++ b/compiler/rustc_llvm/build.rs
@@ -252,7 +252,10 @@ fn main() {
     } else if target.contains("windows-gnu") {
         println!("cargo:rustc-link-lib=shell32");
         println!("cargo:rustc-link-lib=uuid");
-    } else if target.contains("haiku") || target.contains("darwin") {
+    } else if target.contains("haiku")
+        || target.contains("darwin")
+        || (is_crossed && (target.contains("dragonfly") || target.contains("solaris")))
+    {
         println!("cargo:rustc-link-lib=z");
     } else if target.contains("netbsd") {
         println!("cargo:rustc-link-lib=z");
diff --git a/compiler/rustc_metadata/src/lib.rs b/compiler/rustc_metadata/src/lib.rs
index 87373d99743..99fef84931e 100644
--- a/compiler/rustc_metadata/src/lib.rs
+++ b/compiler/rustc_metadata/src/lib.rs
@@ -42,6 +42,6 @@ pub mod locator;
 
 pub use fs::{emit_wrapper_file, METADATA_FILENAME};
 pub use native_libs::find_native_static_library;
-pub use rmeta::{encode_metadata, EncodedMetadata, METADATA_HEADER};
+pub use rmeta::{encode_metadata, rendered_const, EncodedMetadata, METADATA_HEADER};
 
 fluent_messages! { "../messages.ftl" }
diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs
index 05e608c0d1a..43c1d321f81 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder.rs
@@ -9,7 +9,7 @@ use rustc_data_structures::captures::Captures;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::owned_slice::OwnedSlice;
 use rustc_data_structures::svh::Svh;
-use rustc_data_structures::sync::{AppendOnlyVec, AtomicBool, Lock, Lrc, OnceCell};
+use rustc_data_structures::sync::{AppendOnlyVec, AtomicBool, Lock, Lrc, OnceLock};
 use rustc_data_structures::unhash::UnhashMap;
 use rustc_expand::base::{SyntaxExtension, SyntaxExtensionKind};
 use rustc_expand::proc_macro::{AttrProcMacro, BangProcMacro, DeriveProcMacro};
@@ -93,7 +93,7 @@ pub(crate) struct CrateMetadata {
     /// For every definition in this crate, maps its `DefPathHash` to its `DefIndex`.
     def_path_hash_map: DefPathHashMapRef<'static>,
     /// Likewise for ExpnHash.
-    expn_hash_map: OnceCell<UnhashMap<ExpnHash, ExpnIndex>>,
+    expn_hash_map: OnceLock<UnhashMap<ExpnHash, ExpnIndex>>,
     /// Used for decoding interpret::AllocIds in a cached & thread-safe manner.
     alloc_decoding_state: AllocDecodingState,
     /// Caches decoded `DefKey`s.
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index ecb15c41eef..4f4351633a2 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -17,8 +17,8 @@ use rustc_hir::def_id::{
     CrateNum, DefId, DefIndex, LocalDefId, CRATE_DEF_ID, CRATE_DEF_INDEX, LOCAL_CRATE,
 };
 use rustc_hir::definitions::DefPathData;
-use rustc_hir::intravisit;
 use rustc_hir::lang_items::LangItem;
+use rustc_hir_pretty::id_to_string;
 use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile;
 use rustc_middle::middle::dependency_format::Linkage;
 use rustc_middle::middle::exported_symbols::{
@@ -1615,7 +1615,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                     record!(self.tables.mir_const_qualif[def_id.to_def_id()] <- qualifs);
                     let body_id = tcx.hir().maybe_body_owned_by(def_id);
                     if let Some(body_id) = body_id {
-                        let const_data = self.encode_rendered_const_for_body(body_id);
+                        let const_data = rendered_const(self.tcx, body_id);
                         record!(self.tables.rendered_const[def_id.to_def_id()] <- const_data);
                     }
                 }
@@ -1683,14 +1683,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
         }
     }
 
-    fn encode_rendered_const_for_body(&mut self, body_id: hir::BodyId) -> String {
-        let hir = self.tcx.hir();
-        let body = hir.body(body_id);
-        rustc_hir_pretty::to_string(&(&hir as &dyn intravisit::Map<'_>), |s| {
-            s.print_expr(&body.value)
-        })
-    }
-
     #[instrument(level = "debug", skip(self))]
     fn encode_info_for_macro(&mut self, def_id: LocalDefId) {
         let tcx = self.tcx;
@@ -2292,3 +2284,97 @@ pub fn provide(providers: &mut Providers) {
         ..*providers
     }
 }
+
+/// Build a textual representation of an unevaluated constant expression.
+///
+/// If the const expression is too complex, an underscore `_` is returned.
+/// For const arguments, it's `{ _ }` to be precise.
+/// This means that the output is not necessarily valid Rust code.
+///
+/// Currently, only
+///
+/// * literals (optionally with a leading `-`)
+/// * unit `()`
+/// * blocks (`{ … }`) around simple expressions and
+/// * paths without arguments
+///
+/// are considered simple enough. Simple blocks are included since they are
+/// necessary to disambiguate unit from the unit type.
+/// This list might get extended in the future.
+///
+/// Without this censoring, in a lot of cases the output would get too large
+/// and verbose. Consider `match` expressions, blocks and deeply nested ADTs.
+/// Further, private and `doc(hidden)` fields of structs would get leaked
+/// since HIR datatypes like the `body` parameter do not contain enough
+/// semantic information for this function to be able to hide them –
+/// at least not without significant performance overhead.
+///
+/// Whenever possible, prefer to evaluate the constant first and try to
+/// use a different method for pretty-printing. Ideally this function
+/// should only ever be used as a fallback.
+pub fn rendered_const<'tcx>(tcx: TyCtxt<'tcx>, body: hir::BodyId) -> String {
+    let hir = tcx.hir();
+    let value = &hir.body(body).value;
+
+    #[derive(PartialEq, Eq)]
+    enum Classification {
+        Literal,
+        Simple,
+        Complex,
+    }
+
+    use Classification::*;
+
+    fn classify(expr: &hir::Expr<'_>) -> Classification {
+        match &expr.kind {
+            hir::ExprKind::Unary(hir::UnOp::Neg, expr) => {
+                if matches!(expr.kind, hir::ExprKind::Lit(_)) { Literal } else { Complex }
+            }
+            hir::ExprKind::Lit(_) => Literal,
+            hir::ExprKind::Tup([]) => Simple,
+            hir::ExprKind::Block(hir::Block { stmts: [], expr: Some(expr), .. }, _) => {
+                if classify(expr) == Complex { Complex } else { Simple }
+            }
+            // Paths with a self-type or arguments are too “complex” following our measure since
+            // they may leak private fields of structs (with feature `adt_const_params`).
+            // Consider: `<Self as Trait<{ Struct { private: () } }>>::CONSTANT`.
+            // Paths without arguments are definitely harmless though.
+            hir::ExprKind::Path(hir::QPath::Resolved(_, hir::Path { segments, .. })) => {
+                if segments.iter().all(|segment| segment.args.is_none()) { Simple } else { Complex }
+            }
+            // FIXME: Claiming that those kinds of QPaths are simple is probably not true if the Ty
+            //        contains const arguments. Is there a *concise* way to check for this?
+            hir::ExprKind::Path(hir::QPath::TypeRelative(..)) => Simple,
+            // FIXME: Can they contain const arguments and thus leak private struct fields?
+            hir::ExprKind::Path(hir::QPath::LangItem(..)) => Simple,
+            _ => Complex,
+        }
+    }
+
+    let classification = classify(value);
+
+    if classification == Literal
+    && !value.span.from_expansion()
+    && let Ok(snippet) = tcx.sess.source_map().span_to_snippet(value.span) {
+        // For literals, we avoid invoking the pretty-printer and use the source snippet instead to
+        // preserve certain stylistic choices the user likely made for the sake legibility like
+        //
+        // * hexadecimal notation
+        // * underscores
+        // * character escapes
+        //
+        // FIXME: This passes through `-/*spacer*/0` verbatim.
+        snippet
+    } else if classification == Simple {
+        // Otherwise we prefer pretty-printing to get rid of extraneous whitespace, comments and
+        // other formatting artifacts.
+        id_to_string(&hir, body.hir_id)
+    } else if tcx.def_kind(hir.body_owner_def_id(body).to_def_id()) == DefKind::AnonConst {
+        // FIXME: Omit the curly braces if the enclosing expression is an array literal
+        //        with a repeated element (an `ExprKind::Repeat`) as in such case it
+        //        would not actually need any disambiguation.
+        "{ _ }".to_owned()
+    } else {
+        "_".to_owned()
+    }
+}
diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs
index 1f68e83e0ab..71269779d42 100644
--- a/compiler/rustc_metadata/src/rmeta/mod.rs
+++ b/compiler/rustc_metadata/src/rmeta/mod.rs
@@ -42,7 +42,7 @@ pub use decoder::provide_extern;
 use decoder::DecodeContext;
 pub(crate) use decoder::{CrateMetadata, CrateNumMap, MetadataBlob};
 use encoder::EncodeContext;
-pub use encoder::{encode_metadata, EncodedMetadata};
+pub use encoder::{encode_metadata, rendered_const, EncodedMetadata};
 use rustc_span::hygiene::SyntaxContextData;
 
 mod decoder;
diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs
index 81de70c03d4..3e8f07ed233 100644
--- a/compiler/rustc_middle/src/hir/map/mod.rs
+++ b/compiler/rustc_middle/src/hir/map/mod.rs
@@ -1226,7 +1226,6 @@ pub(super) fn crate_hash(tcx: TyCtxt<'_>, _: LocalCrate) -> Svh {
         tcx.stable_crate_id(LOCAL_CRATE).hash_stable(&mut hcx, &mut stable_hasher);
         // Hash visibility information since it does not appear in HIR.
         resolutions.visibilities.hash_stable(&mut hcx, &mut stable_hasher);
-        resolutions.has_pub_restricted.hash_stable(&mut hcx, &mut stable_hasher);
         stable_hasher.finish()
     });
 
diff --git a/compiler/rustc_middle/src/mir/basic_blocks.rs b/compiler/rustc_middle/src/mir/basic_blocks.rs
index 0ad17e819c7..70d8f3bd54b 100644
--- a/compiler/rustc_middle/src/mir/basic_blocks.rs
+++ b/compiler/rustc_middle/src/mir/basic_blocks.rs
@@ -5,7 +5,7 @@ use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::graph;
 use rustc_data_structures::graph::dominators::{dominators, Dominators};
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
-use rustc_data_structures::sync::OnceCell;
+use rustc_data_structures::sync::OnceLock;
 use rustc_index::{IndexSlice, IndexVec};
 use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
 use smallvec::SmallVec;
@@ -23,11 +23,11 @@ pub type SwitchSources = FxHashMap<(BasicBlock, BasicBlock), SmallVec<[Option<u1
 
 #[derive(Clone, Default, Debug)]
 struct Cache {
-    predecessors: OnceCell<Predecessors>,
-    switch_sources: OnceCell<SwitchSources>,
-    is_cyclic: OnceCell<bool>,
-    reverse_postorder: OnceCell<Vec<BasicBlock>>,
-    dominators: OnceCell<Dominators<BasicBlock>>,
+    predecessors: OnceLock<Predecessors>,
+    switch_sources: OnceLock<SwitchSources>,
+    is_cyclic: OnceLock<bool>,
+    reverse_postorder: OnceLock<Vec<BasicBlock>>,
+    dominators: OnceLock<Dominators<BasicBlock>>,
 }
 
 impl<'tcx> BasicBlocks<'tcx> {
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 283c52a5538..1fdc4f7500f 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -162,8 +162,6 @@ pub struct ResolverOutputs {
 #[derive(Debug)]
 pub struct ResolverGlobalCtxt {
     pub visibilities: FxHashMap<LocalDefId, Visibility>,
-    /// This field is used to decide whether we should make `PRIVATE_IN_PUBLIC` a hard error.
-    pub has_pub_restricted: bool,
     /// Item with a given `LocalDefId` was defined during macro expansion with ID `ExpnId`.
     pub expn_that_defined: FxHashMap<LocalDefId, ExpnId>,
     pub effective_visibilities: EffectiveVisibilities,
diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs
index a5c86e31a29..1e0a47ead8c 100644
--- a/compiler/rustc_mir_build/src/build/expr/into.rs
+++ b/compiler/rustc_mir_build/src/build/expr/into.rs
@@ -159,52 +159,44 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 }
             }
             ExprKind::LogicalOp { op, lhs, rhs } => {
-                // And:
-                //
-                // [block: If(lhs)] -true-> [else_block: dest = (rhs)]
-                //        | (false)
-                //  [shortcircuit_block: dest = false]
-                //
-                // Or:
-                //
-                // [block: If(lhs)] -false-> [else_block: dest = (rhs)]
-                //        | (true)
-                //  [shortcircuit_block: dest = true]
-
-                let (shortcircuit_block, mut else_block, join_block) = (
-                    this.cfg.start_new_block(),
-                    this.cfg.start_new_block(),
-                    this.cfg.start_new_block(),
-                );
-
-                let lhs = unpack!(block = this.as_local_operand(block, &this.thir[lhs]));
-                let blocks = match op {
-                    LogicalOp::And => (else_block, shortcircuit_block),
-                    LogicalOp::Or => (shortcircuit_block, else_block),
+                let condition_scope = this.local_scope();
+                let source_info = this.source_info(expr.span);
+                // We first evaluate the left-hand side of the predicate ...
+                let (then_block, else_block) =
+                    this.in_if_then_scope(condition_scope, expr.span, |this| {
+                        this.then_else_break(
+                            block,
+                            &this.thir[lhs],
+                            Some(condition_scope),
+                            condition_scope,
+                            source_info,
+                        )
+                    });
+                let (short_circuit, continuation, constant) = match op {
+                    LogicalOp::And => (else_block, then_block, false),
+                    LogicalOp::Or => (then_block, else_block, true),
                 };
-                let term = TerminatorKind::if_(lhs, blocks.0, blocks.1);
-                this.cfg.terminate(block, source_info, term);
-
+                // At this point, the control flow splits into a short-circuiting path
+                // and a continuation path.
+                // - If the operator is `&&`, passing `lhs` leads to continuation of evaluation on `rhs`;
+                //   failing it leads to the short-circuting path which assigns `false` to the place.
+                // - If the operator is `||`, failing `lhs` leads to continuation of evaluation on `rhs`;
+                //   passing it leads to the short-circuting path which assigns `true` to the place.
                 this.cfg.push_assign_constant(
-                    shortcircuit_block,
+                    short_circuit,
                     source_info,
                     destination,
                     Constant {
-                        span: expr_span,
+                        span: expr.span,
                         user_ty: None,
-                        literal: match op {
-                            LogicalOp::And => ConstantKind::from_bool(this.tcx, false),
-                            LogicalOp::Or => ConstantKind::from_bool(this.tcx, true),
-                        },
+                        literal: ConstantKind::from_bool(this.tcx, constant),
                     },
                 );
-                this.cfg.goto(shortcircuit_block, source_info, join_block);
-
-                let rhs = unpack!(else_block = this.as_local_operand(else_block, &this.thir[rhs]));
-                this.cfg.push_assign(else_block, source_info, destination, Rvalue::Use(rhs));
-                this.cfg.goto(else_block, source_info, join_block);
-
-                join_block.unit()
+                let rhs = unpack!(this.expr_into_dest(destination, continuation, &this.thir[rhs]));
+                let target = this.cfg.start_new_block();
+                this.cfg.goto(rhs, source_info, target);
+                this.cfg.goto(short_circuit, source_info, target);
+                target.unit()
             }
             ExprKind::Loop { body } => {
                 // [block]
diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs
index 3c450740712..5ec216cea61 100644
--- a/compiler/rustc_mir_build/src/build/matches/mod.rs
+++ b/compiler/rustc_mir_build/src/build/matches/mod.rs
@@ -64,6 +64,43 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
 
                 rhs_then_block.unit()
             }
+            ExprKind::LogicalOp { op: LogicalOp::Or, lhs, rhs } => {
+                let local_scope = this.local_scope();
+                let (lhs_success_block, failure_block) =
+                    this.in_if_then_scope(local_scope, expr_span, |this| {
+                        this.then_else_break(
+                            block,
+                            &this.thir[lhs],
+                            temp_scope_override,
+                            local_scope,
+                            variable_source_info,
+                        )
+                    });
+                let rhs_success_block = unpack!(this.then_else_break(
+                    failure_block,
+                    &this.thir[rhs],
+                    temp_scope_override,
+                    break_scope,
+                    variable_source_info,
+                ));
+                this.cfg.goto(lhs_success_block, variable_source_info, rhs_success_block);
+                rhs_success_block.unit()
+            }
+            ExprKind::Unary { op: UnOp::Not, arg } => {
+                let local_scope = this.local_scope();
+                let (success_block, failure_block) =
+                    this.in_if_then_scope(local_scope, expr_span, |this| {
+                        this.then_else_break(
+                            block,
+                            &this.thir[arg],
+                            temp_scope_override,
+                            local_scope,
+                            variable_source_info,
+                        )
+                    });
+                this.break_for_else(success_block, break_scope, variable_source_info);
+                failure_block.unit()
+            }
             ExprKind::Scope { region_scope, lint_level, value } => {
                 let region_scope = (region_scope, this.source_info(expr_span));
                 this.in_scope(region_scope, lint_level, |this| {
@@ -76,6 +113,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     )
                 })
             }
+            ExprKind::Use { source } => this.then_else_break(
+                block,
+                &this.thir[source],
+                temp_scope_override,
+                break_scope,
+                variable_source_info,
+            ),
             ExprKind::Let { expr, ref pat } => this.lower_let_expr(
                 block,
                 &this.thir[expr],
diff --git a/compiler/rustc_privacy/messages.ftl b/compiler/rustc_privacy/messages.ftl
index b91e0d18a80..7785f1a7f81 100644
--- a/compiler/rustc_privacy/messages.ftl
+++ b/compiler/rustc_privacy/messages.ftl
@@ -11,11 +11,6 @@ privacy_in_public_interface = {$vis_descr} {$kind} `{$descr}` in public interfac
 
 privacy_item_is_private = {$kind} `{$descr}` is private
     .label = private {$kind}
-privacy_private_in_public_lint =
-    {$vis_descr} {$kind} `{$descr}` in public interface (error {$kind ->
-        [trait] E0445
-        *[other] E0446
-    })
 
 privacy_private_interface_or_bounds_lint = {$ty_kind} `{$ty_descr}` is more private than the item `{$item_descr}`
     .item_label = {$item_kind} `{$item_descr}` is reachable at visibility `{$item_vis_descr}`
diff --git a/compiler/rustc_privacy/src/errors.rs b/compiler/rustc_privacy/src/errors.rs
index da18f0c8268..b1242f82f4f 100644
--- a/compiler/rustc_privacy/src/errors.rs
+++ b/compiler/rustc_privacy/src/errors.rs
@@ -47,21 +47,6 @@ pub struct UnnamedItemIsPrivate {
     pub kind: &'static str,
 }
 
-// Duplicate of `InPublicInterface` but with a different error code, shares the same slug.
-#[derive(Diagnostic)]
-#[diag(privacy_in_public_interface, code = "E0445")]
-pub struct InPublicInterfaceTraits<'a> {
-    #[primary_span]
-    #[label]
-    pub span: Span,
-    pub vis_descr: &'static str,
-    pub kind: &'a str,
-    pub descr: DiagnosticArgFromDisplay<'a>,
-    #[label(privacy_visibility_label)]
-    pub vis_span: Span,
-}
-
-// Duplicate of `InPublicInterfaceTraits` but with a different error code, shares the same slug.
 #[derive(Diagnostic)]
 #[diag(privacy_in_public_interface, code = "E0446")]
 pub struct InPublicInterface<'a> {
@@ -92,14 +77,6 @@ pub struct FromPrivateDependencyInPublicInterface<'a> {
 }
 
 #[derive(LintDiagnostic)]
-#[diag(privacy_private_in_public_lint)]
-pub struct PrivateInPublicLint<'a> {
-    pub vis_descr: &'static str,
-    pub kind: &'a str,
-    pub descr: DiagnosticArgFromDisplay<'a>,
-}
-
-#[derive(LintDiagnostic)]
 #[diag(privacy_unnameable_types_lint)]
 pub struct UnnameableTypesLint<'a> {
     #[label]
diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs
index 0eb344ba690..906a36cdb25 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, LocalModDefId, CRATE_DEF_ID};
 use rustc_hir::intravisit::{self, Visitor};
-use rustc_hir::{AssocItemKind, ForeignItemKind, HirIdSet, ItemId, Node, PatKind};
+use rustc_hir::{AssocItemKind, ForeignItemKind, 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, PrivateInterfacesOrBoundsLint,
-    ReportEffectiveVisibility, UnnameableTypesLint, UnnamedItemIsPrivate,
+    ItemIsPrivate, PrivateInterfacesOrBoundsLint, ReportEffectiveVisibility, UnnameableTypesLint,
+    UnnamedItemIsPrivate,
 };
 
 fluent_messages! { "../messages.ftl" }
@@ -364,6 +364,7 @@ trait VisibilityLike: Sized {
         find.min
     }
 }
+
 impl VisibilityLike for ty::Visibility {
     const MAX: Self = ty::Visibility::Public;
     fn new_min<const SHALLOW: bool>(
@@ -1383,345 +1384,6 @@ impl<'tcx> DefIdVisitor<'tcx> for TypePrivacyVisitor<'tcx> {
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-/// Obsolete visitors for checking for private items in public interfaces.
-/// These visitors are supposed to be kept in frozen state and produce an
-/// "old error node set". For backward compatibility the new visitor reports
-/// warnings instead of hard errors when the erroneous node is not in this old set.
-///////////////////////////////////////////////////////////////////////////////
-
-struct ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
-    tcx: TyCtxt<'tcx>,
-    effective_visibilities: &'a EffectiveVisibilities,
-    in_variant: bool,
-    // Set of errors produced by this obsolete visitor.
-    old_error_set: HirIdSet,
-}
-
-struct ObsoleteCheckTypeForPrivatenessVisitor<'a, 'b, 'tcx> {
-    inner: &'a ObsoleteVisiblePrivateTypesVisitor<'b, 'tcx>,
-    /// Whether the type refers to private types.
-    contains_private: bool,
-    /// Whether we've recurred at all (i.e., if we're pointing at the
-    /// first type on which `visit_ty` was called).
-    at_outer_type: bool,
-    /// Whether that first type is a public path.
-    outer_type_is_public_path: bool,
-}
-
-impl<'a, 'tcx> ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
-    fn path_is_private_type(&self, path: &hir::Path<'_>) -> bool {
-        let did = match path.res {
-            Res::PrimTy(..) | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } | Res::Err => {
-                return false;
-            }
-            res => res.def_id(),
-        };
-
-        // A path can only be private if:
-        // it's in this crate...
-        if let Some(did) = did.as_local() {
-            // .. and it corresponds to a private type in the AST (this returns
-            // `None` for type parameters).
-            match self.tcx.hir().find(self.tcx.hir().local_def_id_to_hir_id(did)) {
-                Some(Node::Item(_)) => !self.tcx.visibility(did).is_public(),
-                Some(_) | None => false,
-            }
-        } else {
-            false
-        }
-    }
-
-    fn trait_is_public(&self, trait_id: LocalDefId) -> bool {
-        // FIXME: this would preferably be using `exported_items`, but all
-        // traits are exported currently (see `EmbargoVisitor.exported_trait`).
-        self.effective_visibilities.is_directly_public(trait_id)
-    }
-
-    fn check_generic_bound(&mut self, bound: &hir::GenericBound<'_>) {
-        if let hir::GenericBound::Trait(ref trait_ref, _) = *bound {
-            if self.path_is_private_type(trait_ref.trait_ref.path) {
-                self.old_error_set.insert(trait_ref.trait_ref.hir_ref_id);
-            }
-        }
-    }
-
-    fn item_is_public(&self, def_id: LocalDefId) -> bool {
-        self.effective_visibilities.is_reachable(def_id) || self.tcx.visibility(def_id).is_public()
-    }
-}
-
-impl<'a, 'b, 'tcx, 'v> Visitor<'v> for ObsoleteCheckTypeForPrivatenessVisitor<'a, 'b, 'tcx> {
-    fn visit_generic_arg(&mut self, generic_arg: &'v hir::GenericArg<'v>) {
-        match generic_arg {
-            hir::GenericArg::Type(t) => self.visit_ty(t),
-            hir::GenericArg::Infer(inf) => self.visit_ty(&inf.to_ty()),
-            hir::GenericArg::Lifetime(_) | hir::GenericArg::Const(_) => {}
-        }
-    }
-
-    fn visit_ty(&mut self, ty: &hir::Ty<'_>) {
-        if let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = ty.kind {
-            if self.inner.path_is_private_type(path) {
-                self.contains_private = true;
-                // Found what we're looking for, so let's stop working.
-                return;
-            }
-        }
-        if let hir::TyKind::Path(_) = ty.kind {
-            if self.at_outer_type {
-                self.outer_type_is_public_path = true;
-            }
-        }
-        self.at_outer_type = false;
-        intravisit::walk_ty(self, ty)
-    }
-
-    // Don't want to recurse into `[, .. expr]`.
-    fn visit_expr(&mut self, _: &hir::Expr<'_>) {}
-}
-
-impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
-    type NestedFilter = nested_filter::All;
-
-    /// We want to visit items in the context of their containing
-    /// module and so forth, so supply a crate for doing a deep walk.
-    fn nested_visit_map(&mut self) -> Self::Map {
-        self.tcx.hir()
-    }
-
-    fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
-        match item.kind {
-            // Contents of a private mod can be re-exported, so we need
-            // to check internals.
-            hir::ItemKind::Mod(_) => {}
-
-            // An `extern {}` doesn't introduce a new privacy
-            // namespace (the contents have their own privacies).
-            hir::ItemKind::ForeignMod { .. } => {}
-
-            hir::ItemKind::Trait(.., bounds, _) => {
-                if !self.trait_is_public(item.owner_id.def_id) {
-                    return;
-                }
-
-                for bound in bounds.iter() {
-                    self.check_generic_bound(bound)
-                }
-            }
-
-            // Impls need some special handling to try to offer useful
-            // error messages without (too many) false positives
-            // (i.e., we could just return here to not check them at
-            // all, or some worse estimation of whether an impl is
-            // publicly visible).
-            hir::ItemKind::Impl(ref impl_) => {
-                // `impl [... for] Private` is never visible.
-                let self_contains_private;
-                // `impl [... for] Public<...>`, but not `impl [... for]
-                // Vec<Public>` or `(Public,)`, etc.
-                let self_is_public_path;
-
-                // Check the properties of the `Self` type:
-                {
-                    let mut visitor = ObsoleteCheckTypeForPrivatenessVisitor {
-                        inner: self,
-                        contains_private: false,
-                        at_outer_type: true,
-                        outer_type_is_public_path: false,
-                    };
-                    visitor.visit_ty(impl_.self_ty);
-                    self_contains_private = visitor.contains_private;
-                    self_is_public_path = visitor.outer_type_is_public_path;
-                }
-
-                // Miscellaneous info about the impl:
-
-                // `true` iff this is `impl Private for ...`.
-                let not_private_trait = impl_.of_trait.as_ref().map_or(
-                    true, // no trait counts as public trait
-                    |tr| {
-                        if let Some(def_id) = tr.path.res.def_id().as_local() {
-                            self.trait_is_public(def_id)
-                        } else {
-                            true // external traits must be public
-                        }
-                    },
-                );
-
-                // `true` iff this is a trait impl or at least one method is public.
-                //
-                // `impl Public { $( fn ...() {} )* }` is not visible.
-                //
-                // This is required over just using the methods' privacy
-                // directly because we might have `impl<T: Foo<Private>> ...`,
-                // and we shouldn't warn about the generics if all the methods
-                // are private (because `T` won't be visible externally).
-                let trait_or_some_public_method = impl_.of_trait.is_some()
-                    || impl_.items.iter().any(|impl_item_ref| {
-                        let impl_item = self.tcx.hir().impl_item(impl_item_ref.id);
-                        match impl_item.kind {
-                            hir::ImplItemKind::Const(..) | hir::ImplItemKind::Fn(..) => self
-                                .effective_visibilities
-                                .is_reachable(impl_item_ref.id.owner_id.def_id),
-                            hir::ImplItemKind::Type(_) => false,
-                        }
-                    });
-
-                if !self_contains_private && not_private_trait && trait_or_some_public_method {
-                    intravisit::walk_generics(self, &impl_.generics);
-
-                    match impl_.of_trait {
-                        None => {
-                            for impl_item_ref in impl_.items {
-                                // This is where we choose whether to walk down
-                                // further into the impl to check its items. We
-                                // should only walk into public items so that we
-                                // don't erroneously report errors for private
-                                // types in private items.
-                                let impl_item = self.tcx.hir().impl_item(impl_item_ref.id);
-                                match impl_item.kind {
-                                    hir::ImplItemKind::Const(..) | hir::ImplItemKind::Fn(..)
-                                        if self.item_is_public(impl_item.owner_id.def_id) =>
-                                    {
-                                        intravisit::walk_impl_item(self, impl_item)
-                                    }
-                                    hir::ImplItemKind::Type(..) => {
-                                        intravisit::walk_impl_item(self, impl_item)
-                                    }
-                                    _ => {}
-                                }
-                            }
-                        }
-                        Some(ref tr) => {
-                            // Any private types in a trait impl fall into three
-                            // categories.
-                            // 1. mentioned in the trait definition
-                            // 2. mentioned in the type params/generics
-                            // 3. mentioned in the associated types of the impl
-                            //
-                            // Those in 1. can only occur if the trait is in
-                            // this crate and will have been warned about on the
-                            // trait definition (there's no need to warn twice
-                            // so we don't check the methods).
-                            //
-                            // Those in 2. are warned via walk_generics and this
-                            // call here.
-                            intravisit::walk_path(self, tr.path);
-
-                            // Those in 3. are warned with this call.
-                            for impl_item_ref in impl_.items {
-                                let impl_item = self.tcx.hir().impl_item(impl_item_ref.id);
-                                if let hir::ImplItemKind::Type(ty) = impl_item.kind {
-                                    self.visit_ty(ty);
-                                }
-                            }
-                        }
-                    }
-                } else if impl_.of_trait.is_none() && self_is_public_path {
-                    // `impl Public<Private> { ... }`. Any public static
-                    // methods will be visible as `Public::foo`.
-                    let mut found_pub_static = false;
-                    for impl_item_ref in impl_.items {
-                        if self
-                            .effective_visibilities
-                            .is_reachable(impl_item_ref.id.owner_id.def_id)
-                            || self.tcx.visibility(impl_item_ref.id.owner_id).is_public()
-                        {
-                            let impl_item = self.tcx.hir().impl_item(impl_item_ref.id);
-                            match impl_item_ref.kind {
-                                AssocItemKind::Const => {
-                                    found_pub_static = true;
-                                    intravisit::walk_impl_item(self, impl_item);
-                                }
-                                AssocItemKind::Fn { has_self: false } => {
-                                    found_pub_static = true;
-                                    intravisit::walk_impl_item(self, impl_item);
-                                }
-                                _ => {}
-                            }
-                        }
-                    }
-                    if found_pub_static {
-                        intravisit::walk_generics(self, &impl_.generics)
-                    }
-                }
-                return;
-            }
-
-            // `type ... = ...;` can contain private types, because
-            // we're introducing a new name.
-            hir::ItemKind::TyAlias(..) => return,
-
-            // Not at all public, so we don't care.
-            _ if !self.item_is_public(item.owner_id.def_id) => {
-                return;
-            }
-
-            _ => {}
-        }
-
-        // We've carefully constructed it so that if we're here, then
-        // any `visit_ty`'s will be called on things that are in
-        // public signatures, i.e., things that we're interested in for
-        // this visitor.
-        intravisit::walk_item(self, item);
-    }
-
-    fn visit_generics(&mut self, generics: &'tcx hir::Generics<'tcx>) {
-        for predicate in generics.predicates {
-            match predicate {
-                hir::WherePredicate::BoundPredicate(bound_pred) => {
-                    for bound in bound_pred.bounds.iter() {
-                        self.check_generic_bound(bound)
-                    }
-                }
-                hir::WherePredicate::RegionPredicate(_) => {}
-                hir::WherePredicate::EqPredicate(eq_pred) => {
-                    self.visit_ty(eq_pred.rhs_ty);
-                }
-            }
-        }
-    }
-
-    fn visit_foreign_item(&mut self, item: &'tcx hir::ForeignItem<'tcx>) {
-        if self.effective_visibilities.is_reachable(item.owner_id.def_id) {
-            intravisit::walk_foreign_item(self, item)
-        }
-    }
-
-    fn visit_ty(&mut self, t: &'tcx hir::Ty<'tcx>) {
-        if let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = t.kind {
-            if self.path_is_private_type(path) {
-                self.old_error_set.insert(t.hir_id);
-            }
-        }
-        intravisit::walk_ty(self, t)
-    }
-
-    fn visit_variant(&mut self, v: &'tcx hir::Variant<'tcx>) {
-        if self.effective_visibilities.is_reachable(v.def_id) {
-            self.in_variant = true;
-            intravisit::walk_variant(self, v);
-            self.in_variant = false;
-        }
-    }
-
-    fn visit_field_def(&mut self, s: &'tcx hir::FieldDef<'tcx>) {
-        let vis = self.tcx.visibility(s.def_id);
-        if vis.is_public() || self.in_variant {
-            intravisit::walk_field_def(self, s);
-        }
-    }
-
-    // We don't need to introspect into these at all: an
-    // expression/block context can't possibly contain exported things.
-    // (Making them no-ops stops us from traversing the whole AST without
-    // having to be super careful about our `walk_...` calls above.)
-    fn visit_block(&mut self, _: &'tcx hir::Block<'tcx>) {}
-    fn visit_expr(&mut self, _: &'tcx hir::Expr<'tcx>) {}
-}
-
-///////////////////////////////////////////////////////////////////////////////
 /// SearchInterfaceForPrivateItemsVisitor traverses an item's interface and
 /// finds any private components in it.
 /// PrivateItemsInPublicInterfacesVisitor ensures there are no private types
@@ -1734,7 +1396,6 @@ struct SearchInterfaceForPrivateItemsVisitor<'tcx> {
     /// 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,
 }
@@ -1805,7 +1466,7 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> {
         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) {
+        if self.in_assoc_ty && !vis.is_at_least(self.required_visibility, self.tcx) {
             let vis_descr = match vis {
                 ty::Visibility::Public => "public",
                 ty::Visibility::Restricted(vis_def_id) => {
@@ -1819,35 +1480,14 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> {
                 }
             };
 
-            if self.has_old_errors
-                || self.in_assoc_ty
-                || self.tcx.resolutions(()).has_pub_restricted
-            {
-                if kind == "trait" {
-                    self.tcx.sess.emit_err(InPublicInterfaceTraits {
-                        span,
-                        vis_descr,
-                        kind,
-                        descr: descr.into(),
-                        vis_span,
-                    });
-                } else {
-                    self.tcx.sess.emit_err(InPublicInterface {
-                        span,
-                        vis_descr,
-                        kind,
-                        descr: descr.into(),
-                        vis_span,
-                    });
-                }
-            } else {
-                self.tcx.emit_spanned_lint(
-                    lint::builtin::PRIVATE_IN_PUBLIC,
-                    hir_id,
-                    span,
-                    PrivateInPublicLint { vis_descr, kind, descr: descr.into() },
-                );
-            }
+            self.tcx.sess.emit_err(InPublicInterface {
+                span,
+                vis_descr,
+                kind,
+                descr: descr.into(),
+                vis_span,
+            });
+            return false;
         }
 
         let Some(effective_vis) = self.required_effective_vis else {
@@ -1918,7 +1558,6 @@ impl<'tcx> DefIdVisitor<'tcx> for SearchInterfaceForPrivateItemsVisitor<'tcx> {
 
 struct PrivateItemsInPublicInterfacesChecker<'tcx, 'a> {
     tcx: TyCtxt<'tcx>,
-    old_error_set_ancestry: HirIdSet,
     effective_visibilities: &'a EffectiveVisibilities,
 }
 
@@ -1934,9 +1573,6 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'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,
         }
@@ -2298,35 +1934,8 @@ fn effective_visibilities(tcx: TyCtxt<'_>, (): ()) -> &EffectiveVisibilities {
 
 fn check_private_in_public(tcx: TyCtxt<'_>, (): ()) {
     let effective_visibilities = tcx.effective_visibilities(());
-
-    let mut visitor = ObsoleteVisiblePrivateTypesVisitor {
-        tcx,
-        effective_visibilities,
-        in_variant: false,
-        old_error_set: Default::default(),
-    };
-    tcx.hir().walk_toplevel_module(&mut visitor);
-
-    let mut old_error_set_ancestry = HirIdSet::default();
-    for mut id in visitor.old_error_set.iter().copied() {
-        loop {
-            if !old_error_set_ancestry.insert(id) {
-                break;
-            }
-            let parent = tcx.hir().parent_id(id);
-            if parent == id {
-                break;
-            }
-            id = parent;
-        }
-    }
-
-    // Check for private types and traits in public interfaces.
-    let mut checker = PrivateItemsInPublicInterfacesChecker {
-        tcx,
-        old_error_set_ancestry,
-        effective_visibilities,
-    };
+    // Check for private types in public interfaces.
+    let mut checker = PrivateItemsInPublicInterfacesChecker { tcx, effective_visibilities };
 
     for id in tcx.hir().items() {
         checker.check_item(id);
diff --git a/compiler/rustc_query_system/src/query/caches.rs b/compiler/rustc_query_system/src/query/caches.rs
index a96230fdc94..d8aa377af42 100644
--- a/compiler/rustc_query_system/src/query/caches.rs
+++ b/compiler/rustc_query_system/src/query/caches.rs
@@ -2,7 +2,7 @@ use crate::dep_graph::DepNodeIndex;
 
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::sharded::{self, Sharded};
-use rustc_data_structures::sync::Lock;
+use rustc_data_structures::sync::OnceLock;
 use rustc_index::{Idx, IndexVec};
 use std::fmt::Debug;
 use std::hash::Hash;
@@ -87,12 +87,12 @@ impl<'tcx, V: 'tcx> CacheSelector<'tcx, V> for SingleCacheSelector {
 }
 
 pub struct SingleCache<V> {
-    cache: Lock<Option<(V, DepNodeIndex)>>,
+    cache: OnceLock<(V, DepNodeIndex)>,
 }
 
 impl<V> Default for SingleCache<V> {
     fn default() -> Self {
-        SingleCache { cache: Lock::new(None) }
+        SingleCache { cache: OnceLock::new() }
     }
 }
 
@@ -105,16 +105,16 @@ where
 
     #[inline(always)]
     fn lookup(&self, _key: &()) -> Option<(V, DepNodeIndex)> {
-        *self.cache.lock()
+        self.cache.get().copied()
     }
 
     #[inline]
     fn complete(&self, _key: (), value: V, index: DepNodeIndex) {
-        *self.cache.lock() = Some((value, index));
+        self.cache.set((value, index)).ok();
     }
 
     fn iter(&self, f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex)) {
-        if let Some(value) = self.cache.lock().as_ref() {
+        if let Some(value) = self.cache.get() {
             f(&(), &value.0, value.1)
         }
     }
diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs
index 476b5f733a6..30db450870b 100644
--- a/compiler/rustc_resolve/src/build_reduced_graph.rs
+++ b/compiler/rustc_resolve/src/build_reduced_graph.rs
@@ -247,8 +247,6 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
                 })
             }
             ast::VisibilityKind::Restricted { ref path, id, .. } => {
-                // Make `PRIVATE_IN_PUBLIC` lint a hard error.
-                self.r.has_pub_restricted = true;
                 // For visibilities we are not ready to provide correct implementation of "uniform
                 // paths" right now, so on 2018 edition we only allow module-relative paths for now.
                 // On 2015 edition visibilities are resolved as crate-relative by default,
diff --git a/compiler/rustc_resolve/src/effective_visibilities.rs b/compiler/rustc_resolve/src/effective_visibilities.rs
index eb210532f51..46f5df5ca6f 100644
--- a/compiler/rustc_resolve/src/effective_visibilities.rs
+++ b/compiler/rustc_resolve/src/effective_visibilities.rs
@@ -128,11 +128,14 @@ impl<'r, 'a, 'tcx> EffectiveVisibilitiesVisitor<'r, 'a, 'tcx> {
                 // If the binding is ambiguous, put the root ambiguity binding and all reexports
                 // leading to it into the table. They are used by the `ambiguous_glob_reexports`
                 // lint. For all bindings added to the table this way `is_ambiguity` returns true.
+                let is_ambiguity =
+                    |binding: NameBinding<'a>, warn: bool| binding.ambiguity.is_some() && !warn;
                 let mut parent_id = ParentId::Def(module_id);
+                let mut warn_ambiguity = binding.warn_ambiguity;
                 while let NameBindingKind::Import { binding: nested_binding, .. } = binding.kind {
                     self.update_import(binding, parent_id);
 
-                    if binding.ambiguity.is_some() {
+                    if is_ambiguity(binding, warn_ambiguity) {
                         // Stop at the root ambiguity, further bindings in the chain should not
                         // be reexported because the root ambiguity blocks any access to them.
                         // (Those further bindings are most likely not ambiguities themselves.)
@@ -141,9 +144,9 @@ impl<'r, 'a, 'tcx> EffectiveVisibilitiesVisitor<'r, 'a, 'tcx> {
 
                     parent_id = ParentId::Import(binding);
                     binding = nested_binding;
+                    warn_ambiguity |= nested_binding.warn_ambiguity;
                 }
-
-                if binding.ambiguity.is_none()
+                if !is_ambiguity(binding, warn_ambiguity)
                     && let Some(def_id) = binding.res().opt_def_id().and_then(|id| id.as_local()) {
                     self.update_def(def_id, binding.vis.expect_local(), parent_id);
                 }
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 500004269c9..486d60eab21 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -313,7 +313,7 @@ enum LifetimeRibKind {
 
     /// Resolves elided lifetimes to `'static`, but gives a warning that this behavior
     /// is a bug and will be reverted soon.
-    AnonymousWarnToStatic(NodeId),
+    AnonymousWarn(NodeId),
 
     /// Signal we cannot find which should be the anonymous lifetime.
     ElisionFailure,
@@ -1109,6 +1109,7 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
                 }
             },
             AssocConstraintKind::Bound { ref bounds } => {
+                self.record_lifetime_params_for_impl_trait(constraint.id);
                 walk_list!(self, visit_param_bound, bounds, BoundKind::Bound);
             }
         }
@@ -1153,7 +1154,7 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
                             }
                             LifetimeRibKind::AnonymousCreateParameter { .. }
                             | LifetimeRibKind::AnonymousReportError
-                            | LifetimeRibKind::AnonymousWarnToStatic(_)
+                            | LifetimeRibKind::AnonymousWarn(_)
                             | LifetimeRibKind::Elided(_)
                             | LifetimeRibKind::ElisionFailure
                             | LifetimeRibKind::ConcreteAnonConst(_)
@@ -1521,7 +1522,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
                                     // lifetime would be illegal.
                                     LifetimeRibKind::Item
                                     | LifetimeRibKind::AnonymousReportError
-                                    | LifetimeRibKind::AnonymousWarnToStatic(_)
+                                    | LifetimeRibKind::AnonymousWarn(_)
                                     | LifetimeRibKind::ElisionFailure => Some(LifetimeUseSet::Many),
                                     // An anonymous lifetime is legal here, and bound to the right
                                     // place, go ahead.
@@ -1584,7 +1585,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
                 | LifetimeRibKind::Generics { .. }
                 | LifetimeRibKind::ElisionFailure
                 | LifetimeRibKind::AnonymousReportError
-                | LifetimeRibKind::AnonymousWarnToStatic(_) => {}
+                | LifetimeRibKind::AnonymousWarn(_) => {}
             }
         }
 
@@ -1624,8 +1625,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
                     self.record_lifetime_res(lifetime.id, res, elision_candidate);
                     return;
                 }
-                LifetimeRibKind::AnonymousWarnToStatic(node_id) => {
-                    self.record_lifetime_res(lifetime.id, LifetimeRes::Static, elision_candidate);
+                LifetimeRibKind::AnonymousWarn(node_id) => {
                     let msg = if elided {
                         "`&` without an explicit lifetime name cannot be used here"
                     } else {
@@ -1641,7 +1641,6 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
                             span: lifetime.ident.span,
                         },
                     );
-                    return;
                 }
                 LifetimeRibKind::AnonymousReportError => {
                     let (msg, note) = if elided {
@@ -1839,7 +1838,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
                     //     impl Foo for std::cell::Ref<u32> // note lack of '_
                     //     async fn foo(_: std::cell::Ref<u32>) { ... }
                     LifetimeRibKind::AnonymousCreateParameter { report_in_path: true, .. }
-                    | LifetimeRibKind::AnonymousWarnToStatic(_) => {
+                    | LifetimeRibKind::AnonymousWarn(_) => {
                         let sess = self.r.tcx.sess;
                         let mut err = rustc_errors::struct_span_err!(
                             sess,
@@ -2935,33 +2934,30 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
                         kind: LifetimeBinderKind::ConstItem,
                     },
                     |this| {
-                        this.with_lifetime_rib(
-                            LifetimeRibKind::AnonymousWarnToStatic(item.id),
-                            |this| {
-                                // If this is a trait impl, ensure the const
-                                // exists in trait
-                                this.check_trait_item(
-                                    item.id,
-                                    item.ident,
-                                    &item.kind,
-                                    ValueNS,
-                                    item.span,
-                                    seen_trait_items,
-                                    |i, s, c| ConstNotMemberOfTrait(i, s, c),
-                                );
+                        this.with_lifetime_rib(LifetimeRibKind::AnonymousWarn(item.id), |this| {
+                            // If this is a trait impl, ensure the const
+                            // exists in trait
+                            this.check_trait_item(
+                                item.id,
+                                item.ident,
+                                &item.kind,
+                                ValueNS,
+                                item.span,
+                                seen_trait_items,
+                                |i, s, c| ConstNotMemberOfTrait(i, s, c),
+                            );
 
-                                this.visit_generics(generics);
-                                this.visit_ty(ty);
-                                if let Some(expr) = expr {
-                                    // We allow arbitrary const expressions inside of associated consts,
-                                    // even if they are potentially not const evaluatable.
-                                    //
-                                    // Type parameters can already be used and as associated consts are
-                                    // not used as part of the type system, this is far less surprising.
-                                    this.resolve_const_body(expr, None);
-                                }
-                            },
-                        );
+                            this.visit_generics(generics);
+                            this.visit_ty(ty);
+                            if let Some(expr) = expr {
+                                // We allow arbitrary const expressions inside of associated consts,
+                                // even if they are potentially not const evaluatable.
+                                //
+                                // Type parameters can already be used and as associated consts are
+                                // not used as part of the type system, this is far less surprising.
+                                this.resolve_const_body(expr, None);
+                            }
+                        });
                     },
                 );
             }
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index 6d3a1d69ef0..b757f42eaa0 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -989,7 +989,6 @@ pub struct Resolver<'a, 'tcx> {
     glob_map: FxHashMap<LocalDefId, FxHashSet<Symbol>>,
     /// Visibilities in "lowered" form, for all entities that have them.
     visibilities: FxHashMap<LocalDefId, ty::Visibility>,
-    has_pub_restricted: bool,
     used_imports: FxHashSet<NodeId>,
     maybe_unused_trait_imports: FxIndexSet<LocalDefId>,
 
@@ -1342,7 +1341,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
 
             glob_map: Default::default(),
             visibilities,
-            has_pub_restricted: false,
             used_imports: FxHashSet::default(),
             maybe_unused_trait_imports: Default::default(),
 
@@ -1486,7 +1484,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         let proc_macros = self.proc_macros.iter().map(|id| self.local_def_id(*id)).collect();
         let expn_that_defined = self.expn_that_defined;
         let visibilities = self.visibilities;
-        let has_pub_restricted = self.has_pub_restricted;
         let extern_crate_map = self.extern_crate_map;
         let maybe_unused_trait_imports = self.maybe_unused_trait_imports;
         let glob_map = self.glob_map;
@@ -1504,7 +1501,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         let global_ctxt = ResolverGlobalCtxt {
             expn_that_defined,
             visibilities,
-            has_pub_restricted,
             effective_visibilities,
             extern_crate_map,
             module_children: self.module_children,
diff --git a/compiler/rustc_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs
index 5334a75dc06..d8e1f0877bf 100644
--- a/compiler/rustc_smir/src/rustc_internal/mod.rs
+++ b/compiler/rustc_smir/src/rustc_internal/mod.rs
@@ -5,7 +5,6 @@
 
 use std::fmt::Debug;
 use std::ops::Index;
-use std::string::ToString;
 
 use crate::rustc_internal;
 use crate::{
@@ -156,10 +155,23 @@ pub fn run(tcx: TyCtxt<'_>, f: impl FnOnce()) {
 }
 
 /// A type that provides internal information but that can still be used for debug purpose.
-pub type Opaque = impl Debug + ToString + Clone;
+#[derive(Clone)]
+pub struct Opaque(String);
+
+impl std::fmt::Display for Opaque {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        write!(f, "{}", self.0)
+    }
+}
+
+impl std::fmt::Debug for Opaque {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        write!(f, "{:?}", self.0)
+    }
+}
 
 pub(crate) fn opaque<T: Debug>(value: &T) -> Opaque {
-    format!("{value:?}")
+    Opaque(format!("{value:?}"))
 }
 
 pub struct StableMir {
diff --git a/compiler/rustc_smir/src/rustc_smir/alloc.rs b/compiler/rustc_smir/src/rustc_smir/alloc.rs
new file mode 100644
index 00000000000..33c75250adc
--- /dev/null
+++ b/compiler/rustc_smir/src/rustc_smir/alloc.rs
@@ -0,0 +1,124 @@
+use rustc_middle::mir::interpret::{alloc_range, AllocRange, ConstValue, Pointer};
+
+use crate::{
+    rustc_internal::opaque,
+    rustc_smir::{Stable, Tables},
+    stable_mir::mir::Mutability,
+    stable_mir::ty::{Allocation, ProvenanceMap},
+};
+
+/// Creates new empty `Allocation` from given `Align`.
+fn new_empty_allocation(align: rustc_target::abi::Align) -> Allocation {
+    Allocation {
+        bytes: Vec::new(),
+        provenance: ProvenanceMap { ptrs: Vec::new() },
+        align: align.bytes(),
+        mutability: Mutability::Not,
+    }
+}
+
+// We need this method instead of a Stable implementation
+// because we need to get `Ty` of the const we are trying to create, to do that
+// we need to have access to `ConstantKind` but we can't access that inside Stable impl.
+#[allow(rustc::usage_of_qualified_ty)]
+pub fn new_allocation<'tcx>(
+    ty: rustc_middle::ty::Ty<'tcx>,
+    const_value: ConstValue<'tcx>,
+    tables: &mut Tables<'tcx>,
+) -> Allocation {
+    match const_value {
+        ConstValue::Scalar(scalar) => {
+            let size = scalar.size();
+            let align = tables
+                .tcx
+                .layout_of(rustc_middle::ty::ParamEnv::reveal_all().and(ty))
+                .unwrap()
+                .align;
+            let mut allocation = rustc_middle::mir::interpret::Allocation::uninit(size, align.abi);
+            allocation
+                .write_scalar(&tables.tcx, alloc_range(rustc_target::abi::Size::ZERO, size), scalar)
+                .unwrap();
+            allocation.stable(tables)
+        }
+        ConstValue::ZeroSized => {
+            let align =
+                tables.tcx.layout_of(rustc_middle::ty::ParamEnv::empty().and(ty)).unwrap().align;
+            new_empty_allocation(align.abi)
+        }
+        ConstValue::Slice { data, start, end } => {
+            let alloc_id = tables.tcx.create_memory_alloc(data);
+            let ptr = Pointer::new(alloc_id, rustc_target::abi::Size::from_bytes(start));
+            let scalar_ptr = rustc_middle::mir::interpret::Scalar::from_pointer(ptr, &tables.tcx);
+            let scalar_len = rustc_middle::mir::interpret::Scalar::from_target_usize(
+                (end - start) as u64,
+                &tables.tcx,
+            );
+            let layout =
+                tables.tcx.layout_of(rustc_middle::ty::ParamEnv::reveal_all().and(ty)).unwrap();
+            let mut allocation =
+                rustc_middle::mir::interpret::Allocation::uninit(layout.size, layout.align.abi);
+            allocation
+                .write_scalar(
+                    &tables.tcx,
+                    alloc_range(rustc_target::abi::Size::ZERO, tables.tcx.data_layout.pointer_size),
+                    scalar_ptr,
+                )
+                .unwrap();
+            allocation
+                .write_scalar(
+                    &tables.tcx,
+                    alloc_range(tables.tcx.data_layout.pointer_size, scalar_len.size()),
+                    scalar_len,
+                )
+                .unwrap();
+            allocation.stable(tables)
+        }
+        ConstValue::ByRef { alloc, offset } => {
+            let ty_size = tables
+                .tcx
+                .layout_of(rustc_middle::ty::ParamEnv::reveal_all().and(ty))
+                .unwrap()
+                .size;
+            allocation_filter(&alloc.0, alloc_range(offset, ty_size), tables)
+        }
+    }
+}
+
+/// Creates an `Allocation` only from information within the `AllocRange`.
+pub(super) fn allocation_filter<'tcx>(
+    alloc: &rustc_middle::mir::interpret::Allocation,
+    alloc_range: AllocRange,
+    tables: &mut Tables<'tcx>,
+) -> Allocation {
+    let mut bytes: Vec<Option<u8>> = alloc
+        .inspect_with_uninit_and_ptr_outside_interpreter(
+            alloc_range.start.bytes_usize()..alloc_range.end().bytes_usize(),
+        )
+        .iter()
+        .copied()
+        .map(Some)
+        .collect();
+    for (i, b) in bytes.iter_mut().enumerate() {
+        if !alloc
+            .init_mask()
+            .get(rustc_target::abi::Size::from_bytes(i + alloc_range.start.bytes_usize()))
+        {
+            *b = None;
+        }
+    }
+    let mut ptrs = Vec::new();
+    for (offset, prov) in alloc
+        .provenance()
+        .ptrs()
+        .iter()
+        .filter(|a| a.0 >= alloc_range.start && a.0 <= alloc_range.end())
+    {
+        ptrs.push((offset.bytes_usize() - alloc_range.start.bytes_usize(), opaque(prov)));
+    }
+    Allocation {
+        bytes: bytes,
+        provenance: ProvenanceMap { ptrs },
+        align: alloc.align.bytes(),
+        mutability: alloc.mutability.stable(tables),
+    }
+}
diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs
index 7877c91c2cf..d36835d37f5 100644
--- a/compiler/rustc_smir/src/rustc_smir/mod.rs
+++ b/compiler/rustc_smir/src/rustc_smir/mod.rs
@@ -9,10 +9,7 @@
 
 use crate::rustc_internal::{self, opaque};
 use crate::stable_mir::mir::{CopyNonOverlapping, UserTypeProjection, VariantIdx};
-use crate::stable_mir::ty::{
-    allocation_filter, new_allocation, Const, FloatTy, GenericParamDef, IntTy, Movability, RigidTy,
-    TyKind, UintTy,
-};
+use crate::stable_mir::ty::{FloatTy, GenericParamDef, IntTy, Movability, RigidTy, TyKind, UintTy};
 use crate::stable_mir::{self, Context};
 use rustc_hir as hir;
 use rustc_middle::mir::interpret::alloc_range;
@@ -22,6 +19,8 @@ use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE};
 use rustc_target::abi::FieldIdx;
 use tracing::debug;
 
+mod alloc;
+
 impl<'tcx> Context for Tables<'tcx> {
     fn local_crate(&self) -> stable_mir::Crate {
         smir_crate(self.tcx, LOCAL_CRATE)
@@ -205,8 +204,7 @@ impl<'tcx> Stable<'tcx> for mir::Rvalue<'tcx> {
         match self {
             Use(op) => stable_mir::mir::Rvalue::Use(op.stable(tables)),
             Repeat(op, len) => {
-                let cnst = ConstantKind::from_const(*len, tables.tcx);
-                let len = Const { literal: cnst.stable(tables) };
+                let len = len.stable(tables);
                 stable_mir::mir::Rvalue::Repeat(op.stable(tables), len)
             }
             Ref(region, kind, place) => stable_mir::mir::Rvalue::Ref(
@@ -394,8 +392,7 @@ impl<'tcx> Stable<'tcx> for ty::TermKind<'tcx> {
         match self {
             ty::TermKind::Ty(ty) => TermKind::Type(tables.intern_ty(*ty)),
             ty::TermKind::Const(cnst) => {
-                let cnst = ConstantKind::from_const(*cnst, tables.tcx);
-                let cnst = Const { literal: cnst.stable(tables) };
+                let cnst = cnst.stable(tables);
                 TermKind::Const(cnst)
             }
         }
@@ -1083,8 +1080,32 @@ impl<'tcx> Stable<'tcx> for ty::Const<'tcx> {
     type T = stable_mir::ty::Const;
 
     fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
-        let cnst = ConstantKind::from_const(*self, tables.tcx);
-        stable_mir::ty::Const { literal: cnst.stable(tables) }
+        stable_mir::ty::Const {
+            literal: match self.kind() {
+                ty::Value(val) => {
+                    let const_val = tables.tcx.valtree_to_const_val((self.ty(), val));
+                    stable_mir::ty::ConstantKind::Allocated(alloc::new_allocation(
+                        self.ty(),
+                        const_val,
+                        tables,
+                    ))
+                }
+                ty::ParamCt(param) => stable_mir::ty::ConstantKind::ParamCt(opaque(&param)),
+                ty::ErrorCt(_) => unreachable!(),
+                ty::InferCt(_) => unreachable!(),
+                ty::BoundCt(_, _) => unimplemented!(),
+                ty::PlaceholderCt(_) => unimplemented!(),
+                ty::Unevaluated(uv) => {
+                    stable_mir::ty::ConstantKind::Unevaluated(stable_mir::ty::UnevaluatedConst {
+                        ty: tables.intern_ty(self.ty()),
+                        def: tables.const_def(uv.def),
+                        args: uv.args.stable(tables),
+                        promoted: None,
+                    })
+                }
+                ty::ExprCt(_) => unimplemented!(),
+            },
+        }
     }
 }
 
@@ -1108,7 +1129,11 @@ impl<'tcx> Stable<'tcx> for mir::interpret::Allocation {
     type T = stable_mir::ty::Allocation;
 
     fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
-        allocation_filter(self, alloc_range(rustc_target::abi::Size::ZERO, self.size()), tables)
+        alloc::allocation_filter(
+            self,
+            alloc_range(rustc_target::abi::Size::ZERO, self.size()),
+            tables,
+        )
     }
 }
 
@@ -1155,26 +1180,18 @@ impl<'tcx> Stable<'tcx> for rustc_middle::mir::ConstantKind<'tcx> {
     type T = stable_mir::ty::ConstantKind;
 
     fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
-        match self {
-            ConstantKind::Ty(c) => match c.kind() {
-                ty::Value(val) => {
-                    let const_val = tables.tcx.valtree_to_const_val((c.ty(), val));
-                    stable_mir::ty::ConstantKind::Allocated(new_allocation(self, const_val, tables))
-                }
-                ty::ParamCt(param) => stable_mir::ty::ConstantKind::ParamCt(opaque(&param)),
-                ty::ErrorCt(_) => unreachable!(),
-                _ => unimplemented!(),
-            },
+        match *self {
+            ConstantKind::Ty(c) => c.stable(tables).literal,
             ConstantKind::Unevaluated(unev_const, ty) => {
                 stable_mir::ty::ConstantKind::Unevaluated(stable_mir::ty::UnevaluatedConst {
-                    ty: tables.intern_ty(*ty),
+                    ty: tables.intern_ty(ty),
                     def: tables.const_def(unev_const.def),
                     args: unev_const.args.stable(tables),
                     promoted: unev_const.promoted.map(|u| u.as_u32()),
                 })
             }
-            ConstantKind::Val(val, _) => {
-                stable_mir::ty::ConstantKind::Allocated(new_allocation(self, *val, tables))
+            ConstantKind::Val(val, ty) => {
+                stable_mir::ty::ConstantKind::Allocated(alloc::new_allocation(ty, val, tables))
             }
         }
     }
diff --git a/compiler/rustc_smir/src/stable_mir/mod.rs b/compiler/rustc_smir/src/stable_mir/mod.rs
index 1b834628175..2d43e62e97a 100644
--- a/compiler/rustc_smir/src/stable_mir/mod.rs
+++ b/compiler/rustc_smir/src/stable_mir/mod.rs
@@ -20,6 +20,7 @@ use crate::rustc_smir::Tables;
 
 pub mod mir;
 pub mod ty;
+pub mod visitor;
 
 /// Use String for now but we should replace it.
 pub type Symbol = String;
diff --git a/compiler/rustc_smir/src/stable_mir/ty.rs b/compiler/rustc_smir/src/stable_mir/ty.rs
index fce5375f848..d49f3243777 100644
--- a/compiler/rustc_smir/src/stable_mir/ty.rs
+++ b/compiler/rustc_smir/src/stable_mir/ty.rs
@@ -1,10 +1,5 @@
-use rustc_middle::mir::interpret::{alloc_range, AllocRange, ConstValue, Pointer};
-
 use super::{mir::Mutability, mir::Safety, with, DefId};
-use crate::{
-    rustc_internal::{opaque, Opaque},
-    rustc_smir::{Stable, Tables},
-};
+use crate::rustc_internal::Opaque;
 
 #[derive(Copy, Clone, Debug)]
 pub struct Ty(pub usize);
@@ -286,128 +281,6 @@ pub struct Allocation {
     pub mutability: Mutability,
 }
 
-impl Allocation {
-    /// Creates new empty `Allocation` from given `Align`.
-    fn new_empty_allocation(align: rustc_target::abi::Align) -> Allocation {
-        Allocation {
-            bytes: Vec::new(),
-            provenance: ProvenanceMap { ptrs: Vec::new() },
-            align: align.bytes(),
-            mutability: Mutability::Not,
-        }
-    }
-}
-
-// We need this method instead of a Stable implementation
-// because we need to get `Ty` of the const we are trying to create, to do that
-// we need to have access to `ConstantKind` but we can't access that inside Stable impl.
-pub fn new_allocation<'tcx>(
-    const_kind: &rustc_middle::mir::ConstantKind<'tcx>,
-    const_value: ConstValue<'tcx>,
-    tables: &mut Tables<'tcx>,
-) -> Allocation {
-    match const_value {
-        ConstValue::Scalar(scalar) => {
-            let size = scalar.size();
-            let align = tables
-                .tcx
-                .layout_of(rustc_middle::ty::ParamEnv::reveal_all().and(const_kind.ty()))
-                .unwrap()
-                .align;
-            let mut allocation = rustc_middle::mir::interpret::Allocation::uninit(size, align.abi);
-            allocation
-                .write_scalar(&tables.tcx, alloc_range(rustc_target::abi::Size::ZERO, size), scalar)
-                .unwrap();
-            allocation.stable(tables)
-        }
-        ConstValue::ZeroSized => {
-            let align = tables
-                .tcx
-                .layout_of(rustc_middle::ty::ParamEnv::empty().and(const_kind.ty()))
-                .unwrap()
-                .align;
-            Allocation::new_empty_allocation(align.abi)
-        }
-        ConstValue::Slice { data, start, end } => {
-            let alloc_id = tables.tcx.create_memory_alloc(data);
-            let ptr = Pointer::new(alloc_id, rustc_target::abi::Size::from_bytes(start));
-            let scalar_ptr = rustc_middle::mir::interpret::Scalar::from_pointer(ptr, &tables.tcx);
-            let scalar_len = rustc_middle::mir::interpret::Scalar::from_target_usize(
-                (end - start) as u64,
-                &tables.tcx,
-            );
-            let layout = tables
-                .tcx
-                .layout_of(rustc_middle::ty::ParamEnv::reveal_all().and(const_kind.ty()))
-                .unwrap();
-            let mut allocation =
-                rustc_middle::mir::interpret::Allocation::uninit(layout.size, layout.align.abi);
-            allocation
-                .write_scalar(
-                    &tables.tcx,
-                    alloc_range(rustc_target::abi::Size::ZERO, tables.tcx.data_layout.pointer_size),
-                    scalar_ptr,
-                )
-                .unwrap();
-            allocation
-                .write_scalar(
-                    &tables.tcx,
-                    alloc_range(tables.tcx.data_layout.pointer_size, scalar_len.size()),
-                    scalar_len,
-                )
-                .unwrap();
-            allocation.stable(tables)
-        }
-        ConstValue::ByRef { alloc, offset } => {
-            let ty_size = tables
-                .tcx
-                .layout_of(rustc_middle::ty::ParamEnv::reveal_all().and(const_kind.ty()))
-                .unwrap()
-                .size;
-            allocation_filter(&alloc.0, alloc_range(offset, ty_size), tables)
-        }
-    }
-}
-
-/// Creates an `Allocation` only from information within the `AllocRange`.
-pub fn allocation_filter<'tcx>(
-    alloc: &rustc_middle::mir::interpret::Allocation,
-    alloc_range: AllocRange,
-    tables: &mut Tables<'tcx>,
-) -> Allocation {
-    let mut bytes: Vec<Option<u8>> = alloc
-        .inspect_with_uninit_and_ptr_outside_interpreter(
-            alloc_range.start.bytes_usize()..alloc_range.end().bytes_usize(),
-        )
-        .iter()
-        .copied()
-        .map(Some)
-        .collect();
-    for (i, b) in bytes.iter_mut().enumerate() {
-        if !alloc
-            .init_mask()
-            .get(rustc_target::abi::Size::from_bytes(i + alloc_range.start.bytes_usize()))
-        {
-            *b = None;
-        }
-    }
-    let mut ptrs = Vec::new();
-    for (offset, prov) in alloc
-        .provenance()
-        .ptrs()
-        .iter()
-        .filter(|a| a.0 >= alloc_range.start && a.0 <= alloc_range.end())
-    {
-        ptrs.push((offset.bytes_usize() - alloc_range.start.bytes_usize(), opaque(prov)));
-    }
-    Allocation {
-        bytes: bytes,
-        provenance: ProvenanceMap { ptrs },
-        align: alloc.align.bytes(),
-        mutability: alloc.mutability.stable(tables),
-    }
-}
-
 #[derive(Clone, Debug)]
 pub enum ConstantKind {
     Allocated(Allocation),
diff --git a/compiler/rustc_smir/src/stable_mir/visitor.rs b/compiler/rustc_smir/src/stable_mir/visitor.rs
new file mode 100644
index 00000000000..c928eb1381f
--- /dev/null
+++ b/compiler/rustc_smir/src/stable_mir/visitor.rs
@@ -0,0 +1,186 @@
+use std::ops::ControlFlow;
+
+use crate::rustc_internal::Opaque;
+
+use super::ty::{
+    Allocation, Binder, Const, ConstDef, ExistentialPredicate, FnSig, GenericArgKind, GenericArgs,
+    Promoted, RigidTy, TermKind, Ty, UnevaluatedConst,
+};
+
+pub trait Visitor: Sized {
+    type Break;
+    fn visit_ty(&mut self, ty: &Ty) -> ControlFlow<Self::Break> {
+        ty.super_visit(self)
+    }
+    fn visit_const(&mut self, c: &Const) -> ControlFlow<Self::Break> {
+        c.super_visit(self)
+    }
+}
+
+pub trait Visitable {
+    fn visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
+        self.super_visit(visitor)
+    }
+    fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break>;
+}
+
+impl Visitable for Ty {
+    fn visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
+        visitor.visit_ty(self)
+    }
+    fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
+        match self.kind() {
+            super::ty::TyKind::RigidTy(ty) => ty.visit(visitor),
+            super::ty::TyKind::Alias(_, alias) => alias.args.visit(visitor),
+            super::ty::TyKind::Param(_) => todo!(),
+            super::ty::TyKind::Bound(_, _) => todo!(),
+        }
+    }
+}
+
+impl Visitable for Const {
+    fn visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
+        visitor.visit_const(self)
+    }
+    fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
+        match &self.literal {
+            super::ty::ConstantKind::Allocated(alloc) => alloc.visit(visitor),
+            super::ty::ConstantKind::Unevaluated(uv) => uv.visit(visitor),
+            super::ty::ConstantKind::ParamCt(param) => param.visit(visitor),
+        }
+    }
+}
+
+impl Visitable for Opaque {
+    fn super_visit<V: Visitor>(&self, _visitor: &mut V) -> ControlFlow<V::Break> {
+        ControlFlow::Continue(())
+    }
+}
+
+impl Visitable for Allocation {
+    fn super_visit<V: Visitor>(&self, _visitor: &mut V) -> ControlFlow<V::Break> {
+        ControlFlow::Continue(())
+    }
+}
+
+impl Visitable for UnevaluatedConst {
+    fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
+        let UnevaluatedConst { ty, def, args, promoted } = self;
+        ty.visit(visitor)?;
+        def.visit(visitor)?;
+        args.visit(visitor)?;
+        promoted.visit(visitor)
+    }
+}
+
+impl Visitable for ConstDef {
+    fn super_visit<V: Visitor>(&self, _visitor: &mut V) -> ControlFlow<V::Break> {
+        ControlFlow::Continue(())
+    }
+}
+
+impl<T: Visitable> Visitable for Option<T> {
+    fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
+        match self {
+            Some(val) => val.visit(visitor),
+            None => ControlFlow::Continue(()),
+        }
+    }
+}
+
+impl Visitable for Promoted {
+    fn super_visit<V: Visitor>(&self, _visitor: &mut V) -> ControlFlow<V::Break> {
+        ControlFlow::Continue(())
+    }
+}
+
+impl Visitable for GenericArgs {
+    fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
+        self.0.visit(visitor)
+    }
+}
+
+impl Visitable for GenericArgKind {
+    fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
+        match self {
+            GenericArgKind::Lifetime(lt) => lt.visit(visitor),
+            GenericArgKind::Type(t) => t.visit(visitor),
+            GenericArgKind::Const(c) => c.visit(visitor),
+        }
+    }
+}
+
+impl Visitable for RigidTy {
+    fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
+        match self {
+            RigidTy::Bool
+            | RigidTy::Char
+            | RigidTy::Int(_)
+            | RigidTy::Uint(_)
+            | RigidTy::Float(_)
+            | RigidTy::Never
+            | RigidTy::Foreign(_)
+            | RigidTy::Str => ControlFlow::Continue(()),
+            RigidTy::Array(t, c) => {
+                t.visit(visitor)?;
+                c.visit(visitor)
+            }
+            RigidTy::Slice(inner) => inner.visit(visitor),
+            RigidTy::RawPtr(ty, _) => ty.visit(visitor),
+            RigidTy::Ref(_, ty, _) => ty.visit(visitor),
+            RigidTy::FnDef(_, args) => args.visit(visitor),
+            RigidTy::FnPtr(sig) => sig.visit(visitor),
+            RigidTy::Closure(_, args) => args.visit(visitor),
+            RigidTy::Generator(_, args, _) => args.visit(visitor),
+            RigidTy::Dynamic(pred, r, _) => {
+                pred.visit(visitor)?;
+                r.visit(visitor)
+            }
+            RigidTy::Tuple(fields) => fields.visit(visitor),
+            RigidTy::Adt(_, args) => args.visit(visitor),
+        }
+    }
+}
+
+impl<T: Visitable> Visitable for Vec<T> {
+    fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
+        for arg in self {
+            arg.visit(visitor)?;
+        }
+        ControlFlow::Continue(())
+    }
+}
+
+impl<T: Visitable> Visitable for Binder<T> {
+    fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
+        self.value.visit(visitor)
+    }
+}
+
+impl Visitable for ExistentialPredicate {
+    fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
+        match self {
+            ExistentialPredicate::Trait(tr) => tr.generic_args.visit(visitor),
+            ExistentialPredicate::Projection(p) => {
+                p.term.visit(visitor)?;
+                p.generic_args.visit(visitor)
+            }
+            ExistentialPredicate::AutoTrait(_) => ControlFlow::Continue(()),
+        }
+    }
+}
+
+impl Visitable for TermKind {
+    fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
+        match self {
+            TermKind::Type(t) => t.visit(visitor),
+            TermKind::Const(c) => c.visit(visitor),
+        }
+    }
+}
+
+impl Visitable for FnSig {
+    fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
+        self.inputs_and_output.visit(visitor)
+    }
+}
diff --git a/compiler/rustc_trait_selection/messages.ftl b/compiler/rustc_trait_selection/messages.ftl
index f4c9dfa3488..2a09a7dcd89 100644
--- a/compiler/rustc_trait_selection/messages.ftl
+++ b/compiler/rustc_trait_selection/messages.ftl
@@ -40,4 +40,5 @@ trait_selection_no_value_in_rustc_on_unimplemented = this attribute must have a
     .label = expected value here
     .note = eg `#[rustc_on_unimplemented(message="foo")]`
 
+trait_selection_ty_alias_overflow = in case this is a recursive type alias, consider using a struct, enum, or union instead
 trait_selection_unable_to_construct_constant_value = unable to construct a constant value for the unevaluated constant {$unevaluated}
diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs
index 5c2cbe39953..63ae83c8ef4 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs
@@ -537,7 +537,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
 
     /// Iterate over all added goals: returning `Ok(Some(_))` in case we can stop rerunning.
     ///
-    /// Goals for the next step get directly added the the nested goals of the `EvalCtxt`.
+    /// Goals for the next step get directly added to the nested goals of the `EvalCtxt`.
     fn evaluate_added_goals_step(&mut self) -> Result<Option<Certainty>, NoSolution> {
         let tcx = self.tcx();
         let mut goals = core::mem::replace(&mut self.nested_goals, NestedGoals::new());
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index 06a1027e5df..b31c0e655fb 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -659,6 +659,18 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
                 normalized_ty
             }
             ty::Weak => {
+                let recursion_limit = self.interner().recursion_limit();
+                if !recursion_limit.value_within_limit(self.depth) {
+                    self.selcx.infcx.err_ctxt().report_overflow_error(
+                        &ty,
+                        self.cause.span,
+                        false,
+                        |diag| {
+                            diag.note(crate::fluent_generated::trait_selection_ty_alias_overflow);
+                        },
+                    );
+                }
+
                 let infcx = self.selcx.infcx;
                 self.obligations.extend(
                     infcx.tcx.predicates_of(data.def_id).instantiate_own(infcx.tcx, data.args).map(
@@ -678,7 +690,14 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
                         },
                     ),
                 );
-                infcx.tcx.type_of(data.def_id).instantiate(infcx.tcx, data.args).fold_with(self)
+                self.depth += 1;
+                let res = infcx
+                    .tcx
+                    .type_of(data.def_id)
+                    .instantiate(infcx.tcx, data.args)
+                    .fold_with(self);
+                self.depth -= 1;
+                res
             }
 
             ty::Inherent if !data.has_escaping_bound_vars() => {
diff --git a/library/core/src/char/convert.rs b/library/core/src/char/convert.rs
index b84e4b35b1c..b6b36886604 100644
--- a/library/core/src/char/convert.rs
+++ b/library/core/src/char/convert.rs
@@ -87,20 +87,54 @@ impl From<char> for u128 {
     }
 }
 
-/// Map `char` with code point in U+0000..=U+00FF to byte in 0x00..=0xFF with same value, failing
-/// if the code point is greater than U+00FF.
+/// Maps a `char` with code point in U+0000..=U+00FF to a byte in 0x00..=0xFF with same value,
+/// failing if the code point is greater than U+00FF.
 ///
 /// See [`impl From<u8> for char`](char#impl-From<u8>-for-char) for details on the encoding.
 #[stable(feature = "u8_from_char", since = "1.59.0")]
 impl TryFrom<char> for u8 {
     type Error = TryFromCharError;
 
+    /// Tries to convert a [`char`] into a [`u8`].
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let a = 'ÿ'; // U+00FF
+    /// let b = 'Ā'; // U+0100
+    /// assert_eq!(u8::try_from(a), Ok(0xFF_u8));
+    /// assert!(u8::try_from(b).is_err());
+    /// ```
     #[inline]
     fn try_from(c: char) -> Result<u8, Self::Error> {
         u8::try_from(u32::from(c)).map_err(|_| TryFromCharError(()))
     }
 }
 
+/// Maps a `char` with code point in U+0000..=U+FFFF to a `u16` in 0x0000..=0xFFFF with same value,
+/// failing if the code point is greater than U+FFFF.
+///
+/// This corresponds to the UCS-2 encoding, as specified in ISO/IEC 10646:2003.
+#[stable(feature = "u16_from_char", since = "CURRENT_RUSTC_VERSION")]
+impl TryFrom<char> for u16 {
+    type Error = TryFromCharError;
+
+    /// Tries to convert a [`char`] into a [`u16`].
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let trans_rights = '⚧'; // U+26A7
+    /// let ninjas = '🥷'; // U+1F977
+    /// assert_eq!(u16::try_from(trans_rights), Ok(0x26A7_u16));
+    /// assert!(u16::try_from(ninjas).is_err());
+    /// ```
+    #[inline]
+    fn try_from(c: char) -> Result<u16, Self::Error> {
+        u16::try_from(u32::from(c)).map_err(|_| TryFromCharError(()))
+    }
+}
+
 /// Maps a byte in 0x00..=0xFF to a `char` whose code point has the same value, in U+0000..=U+00FF.
 ///
 /// Unicode is designed such that this effectively decodes bytes
diff --git a/library/core/src/iter/adapters/take.rs b/library/core/src/iter/adapters/take.rs
index ce18bffe714..c1d8cc4ff57 100644
--- a/library/core/src/iter/adapters/take.rs
+++ b/library/core/src/iter/adapters/take.rs
@@ -1,5 +1,7 @@
 use crate::cmp;
-use crate::iter::{adapters::SourceIter, FusedIterator, InPlaceIterable, TrustedLen};
+use crate::iter::{
+    adapters::SourceIter, FusedIterator, InPlaceIterable, TrustedLen, TrustedRandomAccess,
+};
 use crate::num::NonZeroUsize;
 use crate::ops::{ControlFlow, Try};
 
@@ -98,26 +100,18 @@ where
         }
     }
 
-    impl_fold_via_try_fold! { fold -> try_fold }
-
     #[inline]
-    fn for_each<F: FnMut(Self::Item)>(mut self, f: F) {
-        // The default implementation would use a unit accumulator, so we can
-        // avoid a stateful closure by folding over the remaining number
-        // of items we wish to return instead.
-        fn check<'a, Item>(
-            mut action: impl FnMut(Item) + 'a,
-        ) -> impl FnMut(usize, Item) -> Option<usize> + 'a {
-            move |more, x| {
-                action(x);
-                more.checked_sub(1)
-            }
-        }
+    fn fold<B, F>(self, init: B, f: F) -> B
+    where
+        Self: Sized,
+        F: FnMut(B, Self::Item) -> B,
+    {
+        Self::spec_fold(self, init, f)
+    }
 
-        let remaining = self.n;
-        if remaining > 0 {
-            self.iter.try_fold(remaining - 1, check(f));
-        }
+    #[inline]
+    fn for_each<F: FnMut(Self::Item)>(self, f: F) {
+        Self::spec_for_each(self, f)
     }
 
     #[inline]
@@ -249,3 +243,72 @@ impl<I> FusedIterator for Take<I> where I: FusedIterator {}
 
 #[unstable(feature = "trusted_len", issue = "37572")]
 unsafe impl<I: TrustedLen> TrustedLen for Take<I> {}
+
+trait SpecTake: Iterator {
+    fn spec_fold<B, F>(self, init: B, f: F) -> B
+    where
+        Self: Sized,
+        F: FnMut(B, Self::Item) -> B;
+
+    fn spec_for_each<F: FnMut(Self::Item)>(self, f: F);
+}
+
+impl<I: Iterator> SpecTake for Take<I> {
+    #[inline]
+    default fn spec_fold<B, F>(mut self, init: B, f: F) -> B
+    where
+        Self: Sized,
+        F: FnMut(B, Self::Item) -> B,
+    {
+        use crate::ops::NeverShortCircuit;
+        self.try_fold(init, NeverShortCircuit::wrap_mut_2(f)).0
+    }
+
+    #[inline]
+    default fn spec_for_each<F: FnMut(Self::Item)>(mut self, f: F) {
+        // The default implementation would use a unit accumulator, so we can
+        // avoid a stateful closure by folding over the remaining number
+        // of items we wish to return instead.
+        fn check<'a, Item>(
+            mut action: impl FnMut(Item) + 'a,
+        ) -> impl FnMut(usize, Item) -> Option<usize> + 'a {
+            move |more, x| {
+                action(x);
+                more.checked_sub(1)
+            }
+        }
+
+        let remaining = self.n;
+        if remaining > 0 {
+            self.iter.try_fold(remaining - 1, check(f));
+        }
+    }
+}
+
+impl<I: Iterator + TrustedRandomAccess> SpecTake for Take<I> {
+    #[inline]
+    fn spec_fold<B, F>(mut self, init: B, mut f: F) -> B
+    where
+        Self: Sized,
+        F: FnMut(B, Self::Item) -> B,
+    {
+        let mut acc = init;
+        let end = self.n.min(self.iter.size());
+        for i in 0..end {
+            // SAFETY: i < end <= self.iter.size() and we discard the iterator at the end
+            let val = unsafe { self.iter.__iterator_get_unchecked(i) };
+            acc = f(acc, val);
+        }
+        acc
+    }
+
+    #[inline]
+    fn spec_for_each<F: FnMut(Self::Item)>(mut self, mut f: F) {
+        let end = self.n.min(self.iter.size());
+        for i in 0..end {
+            // SAFETY: i < end <= self.iter.size() and we discard the iterator at the end
+            let val = unsafe { self.iter.__iterator_get_unchecked(i) };
+            f(val);
+        }
+    }
+}
diff --git a/library/core/src/iter/range.rs b/library/core/src/iter/range.rs
index 462f7170a55..44feb0a5638 100644
--- a/library/core/src/iter/range.rs
+++ b/library/core/src/iter/range.rs
@@ -1,3 +1,4 @@
+use crate::ascii::Char as AsciiChar;
 use crate::convert::TryFrom;
 use crate::mem;
 use crate::num::NonZeroUsize;
@@ -14,7 +15,7 @@ macro_rules! unsafe_impl_trusted_step {
         unsafe impl TrustedStep for $type {}
     )*};
 }
-unsafe_impl_trusted_step![char i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize];
+unsafe_impl_trusted_step![AsciiChar char i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize];
 
 /// Objects that have a notion of *successor* and *predecessor* operations.
 ///
@@ -484,6 +485,48 @@ impl Step for char {
     }
 }
 
+#[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")]
+impl Step for AsciiChar {
+    #[inline]
+    fn steps_between(&start: &AsciiChar, &end: &AsciiChar) -> Option<usize> {
+        Step::steps_between(&start.to_u8(), &end.to_u8())
+    }
+
+    #[inline]
+    fn forward_checked(start: AsciiChar, count: usize) -> Option<AsciiChar> {
+        let end = Step::forward_checked(start.to_u8(), count)?;
+        AsciiChar::from_u8(end)
+    }
+
+    #[inline]
+    fn backward_checked(start: AsciiChar, count: usize) -> Option<AsciiChar> {
+        let end = Step::backward_checked(start.to_u8(), count)?;
+
+        // SAFETY: Values below that of a valid ASCII character are also valid ASCII
+        Some(unsafe { AsciiChar::from_u8_unchecked(end) })
+    }
+
+    #[inline]
+    unsafe fn forward_unchecked(start: AsciiChar, count: usize) -> AsciiChar {
+        // SAFETY: Caller asserts that result is a valid ASCII character,
+        // and therefore it is a valid u8.
+        let end = unsafe { Step::forward_unchecked(start.to_u8(), count) };
+
+        // SAFETY: Caller asserts that result is a valid ASCII character.
+        unsafe { AsciiChar::from_u8_unchecked(end) }
+    }
+
+    #[inline]
+    unsafe fn backward_unchecked(start: AsciiChar, count: usize) -> AsciiChar {
+        // SAFETY: Caller asserts that result is a valid ASCII character,
+        // and therefore it is a valid u8.
+        let end = unsafe { Step::backward_unchecked(start.to_u8(), count) };
+
+        // SAFETY: Caller asserts that result is a valid ASCII character.
+        unsafe { AsciiChar::from_u8_unchecked(end) }
+    }
+}
+
 macro_rules! range_exact_iter_impl {
     ($($t:ty)*) => ($(
         #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index f39c4176440..b97cb652076 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -152,7 +152,6 @@
 #![feature(const_slice_from_raw_parts_mut)]
 #![feature(const_slice_from_ref)]
 #![feature(const_slice_index)]
-#![feature(const_slice_is_ascii)]
 #![feature(const_slice_ptr_len)]
 #![feature(const_slice_split_at_mut)]
 #![feature(const_str_from_utf8_unchecked_mut)]
diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs
index 5939dedbd1d..7f8d673c179 100644
--- a/library/core/src/num/nonzero.rs
+++ b/library/core/src/num/nonzero.rs
@@ -41,6 +41,20 @@ macro_rules! nonzero_integers {
             /// with the exception that `0` is not a valid instance.
             #[doc = concat!("`Option<", stringify!($Ty), ">` is guaranteed to be compatible with `", stringify!($Int), "`,")]
             /// including in FFI.
+            ///
+            /// Thanks to the [null pointer optimization],
+            #[doc = concat!("`", stringify!($Ty), "` and `Option<", stringify!($Ty), ">`")]
+            /// are guaranteed to have the same size and alignment:
+            ///
+            /// ```
+            /// # use std::mem::{size_of, align_of};
+            #[doc = concat!("use std::num::", stringify!($Ty), ";")]
+            ///
+            #[doc = concat!("assert_eq!(size_of::<", stringify!($Ty), ">(), size_of::<Option<", stringify!($Ty), ">>());")]
+            #[doc = concat!("assert_eq!(align_of::<", stringify!($Ty), ">(), align_of::<Option<", stringify!($Ty), ">>());")]
+            /// ```
+            ///
+            /// [null pointer optimization]: crate::option#representation
             #[$stability]
             #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
             #[repr(transparent)]
diff --git a/library/core/src/num/saturating.rs b/library/core/src/num/saturating.rs
index 8982473b2dc..e9f794e7d62 100644
--- a/library/core/src/num/saturating.rs
+++ b/library/core/src/num/saturating.rs
@@ -35,6 +35,7 @@ use crate::ops::{Shl, ShlAssign, Shr, ShrAssign, Sub, SubAssign};
 #[unstable(feature = "saturating_int_impl", issue = "87920")]
 #[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Default, Hash)]
 #[repr(transparent)]
+#[rustc_diagnostic_item = "Saturating"]
 pub struct Saturating<T>(#[unstable(feature = "saturating_int_impl", issue = "87920")] pub T);
 
 #[unstable(feature = "saturating_int_impl", issue = "87920")]
diff --git a/library/core/src/num/wrapping.rs b/library/core/src/num/wrapping.rs
index ed354a2e50b..16f0b6d913d 100644
--- a/library/core/src/num/wrapping.rs
+++ b/library/core/src/num/wrapping.rs
@@ -39,6 +39,7 @@ use crate::ops::{Shl, ShlAssign, Shr, ShrAssign, Sub, SubAssign};
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Default, Hash)]
 #[repr(transparent)]
+#[rustc_diagnostic_item = "Wrapping"]
 pub struct Wrapping<T>(#[stable(feature = "rust1", since = "1.0.0")] pub T);
 
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/library/core/src/option.rs b/library/core/src/option.rs
index becb6330997..f2909a81d49 100644
--- a/library/core/src/option.rs
+++ b/library/core/src/option.rs
@@ -119,7 +119,7 @@
 //! # Representation
 //!
 //! Rust guarantees to optimize the following types `T` such that
-//! [`Option<T>`] has the same size as `T`:
+//! [`Option<T>`] has the same size and alignment as `T`:
 //!
 //! * [`Box<U>`]
 //! * `&U`
diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs
index e0fd347a049..6b3c4343ed3 100644
--- a/library/core/src/ptr/non_null.rs
+++ b/library/core/src/ptr/non_null.rs
@@ -43,9 +43,27 @@ use crate::slice::{self, SliceIndex};
 /// it is your responsibility to ensure that `as_mut` is never called, and `as_ptr`
 /// is never used for mutation.
 ///
+/// # Representation
+///
+/// Thanks to the [null pointer optimization],
+/// `NonNull<T>` and `Option<NonNull<T>>`
+/// are guaranteed to have the same size and alignment:
+///
+/// ```
+/// # use std::mem::{size_of, align_of};
+/// use std::ptr::NonNull;
+///
+/// assert_eq!(size_of::<NonNull<i16>>(), size_of::<Option<NonNull<i16>>>());
+/// assert_eq!(align_of::<NonNull<i16>>(), align_of::<Option<NonNull<i16>>>());
+///
+/// assert_eq!(size_of::<NonNull<str>>(), size_of::<Option<NonNull<str>>>());
+/// assert_eq!(align_of::<NonNull<str>>(), align_of::<Option<NonNull<str>>>());
+/// ```
+///
 /// [covariant]: https://doc.rust-lang.org/reference/subtyping.html
 /// [`PhantomData`]: crate::marker::PhantomData
 /// [`UnsafeCell<T>`]: crate::cell::UnsafeCell
+/// [null pointer optimization]: crate::option#representation
 #[stable(feature = "nonnull", since = "1.25.0")]
 #[repr(transparent)]
 #[rustc_layout_scalar_valid_range_start(1)]
diff --git a/library/core/src/slice/ascii.rs b/library/core/src/slice/ascii.rs
index f3311f76a7f..5dc53caba0d 100644
--- a/library/core/src/slice/ascii.rs
+++ b/library/core/src/slice/ascii.rs
@@ -10,7 +10,7 @@ use crate::ops;
 impl [u8] {
     /// Checks if all bytes in this slice are within the ASCII range.
     #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
-    #[rustc_const_unstable(feature = "const_slice_is_ascii", issue = "111090")]
+    #[rustc_const_stable(feature = "const_slice_is_ascii", since = "CURRENT_RUSTC_VERSION")]
     #[must_use]
     #[inline]
     pub const fn is_ascii(&self) -> bool {
diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs
index 23cebdb6c3b..d5b0ab92c09 100644
--- a/library/core/src/str/mod.rs
+++ b/library/core/src/str/mod.rs
@@ -2322,7 +2322,7 @@ impl str {
     /// assert!(!non_ascii.is_ascii());
     /// ```
     #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
-    #[rustc_const_unstable(feature = "const_slice_is_ascii", issue = "111090")]
+    #[rustc_const_stable(feature = "const_slice_is_ascii", since = "CURRENT_RUSTC_VERSION")]
     #[must_use]
     #[inline]
     pub const fn is_ascii(&self) -> bool {
diff --git a/library/core/tests/iter/range.rs b/library/core/tests/iter/range.rs
index 0a77ecddb84..5b87d6c1fa0 100644
--- a/library/core/tests/iter/range.rs
+++ b/library/core/tests/iter/range.rs
@@ -1,5 +1,6 @@
-use core::num::NonZeroUsize;
 use super::*;
+use core::ascii::Char as AsciiChar;
+use core::num::NonZeroUsize;
 
 #[test]
 fn test_range() {
@@ -40,6 +41,21 @@ fn test_char_range() {
 }
 
 #[test]
+fn test_ascii_char_range() {
+    let from = AsciiChar::Null;
+    let to = AsciiChar::Delete;
+    assert!((from..=to).eq((from as u8..=to as u8).filter_map(AsciiChar::from_u8)));
+    assert!((from..=to).rev().eq((from as u8..=to as u8).filter_map(AsciiChar::from_u8).rev()));
+
+    assert_eq!((AsciiChar::CapitalA..=AsciiChar::CapitalZ).count(), 26);
+    assert_eq!((AsciiChar::CapitalA..=AsciiChar::CapitalZ).size_hint(), (26, Some(26)));
+    assert_eq!((AsciiChar::SmallA..=AsciiChar::SmallZ).count(), 26);
+    assert_eq!((AsciiChar::SmallA..=AsciiChar::SmallZ).size_hint(), (26, Some(26)));
+    assert_eq!((AsciiChar::Digit0..=AsciiChar::Digit9).count(), 10);
+    assert_eq!((AsciiChar::Digit0..=AsciiChar::Digit9).size_hint(), (10, Some(10)));
+}
+
+#[test]
 fn test_range_exhaustion() {
     let mut r = 10..10;
     assert!(r.is_empty());
diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs
index 7a6def37a55..17011b845cf 100644
--- a/library/core/tests/lib.rs
+++ b/library/core/tests/lib.rs
@@ -2,6 +2,8 @@
 #![feature(array_chunks)]
 #![feature(array_methods)]
 #![feature(array_windows)]
+#![feature(ascii_char)]
+#![feature(ascii_char_variants)]
 #![feature(bigint_helper_methods)]
 #![feature(cell_update)]
 #![feature(const_align_offset)]
diff --git a/library/std/src/ffi/mod.rs b/library/std/src/ffi/mod.rs
index ee9f6ed087c..97e78d17786 100644
--- a/library/std/src/ffi/mod.rs
+++ b/library/std/src/ffi/mod.rs
@@ -132,8 +132,8 @@
 //! On all platforms, [`OsStr`] consists of a sequence of bytes that is encoded as a superset of
 //! UTF-8; see [`OsString`] for more details on its encoding on different platforms.
 //!
-//! For limited, inexpensive conversions from and to bytes, see [`OsStr::as_os_str_bytes`] and
-//! [`OsStr::from_os_str_bytes_unchecked`].
+//! For limited, inexpensive conversions from and to bytes, see [`OsStr::as_encoded_bytes`] and
+//! [`OsStr::from_encoded_bytes_unchecked`].
 //!
 //! [Unicode scalar value]: https://www.unicode.org/glossary/#unicode_scalar_value
 //! [Unicode code point]: https://www.unicode.org/glossary/#code_point
diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs
index 43cecb19b14..93b9bf0cc20 100644
--- a/library/std/src/ffi/os_str.rs
+++ b/library/std/src/ffi/os_str.rs
@@ -154,36 +154,34 @@ impl OsString {
     /// # Safety
     ///
     /// As the encoding is unspecified, callers must pass in bytes that originated as a mixture of
-    /// validated UTF-8 and bytes from [`OsStr::as_os_str_bytes`] from within the same rust version
+    /// validated UTF-8 and bytes from [`OsStr::as_encoded_bytes`] from within the same rust version
     /// built for the same target platform.  For example, reconstructing an `OsString` from bytes sent
     /// over the network or stored in a file will likely violate these safety rules.
     ///
-    /// Due to the encoding being self-synchronizing, the bytes from [`OsStr::as_os_str_bytes`] can be
+    /// Due to the encoding being self-synchronizing, the bytes from [`OsStr::as_encoded_bytes`] can be
     /// split either immediately before or immediately after any valid non-empty UTF-8 substring.
     ///
     /// # Example
     ///
     /// ```
-    /// #![feature(os_str_bytes)]
-    ///
     /// use std::ffi::OsStr;
     ///
     /// let os_str = OsStr::new("Mary had a little lamb");
-    /// let bytes = os_str.as_os_str_bytes();
+    /// let bytes = os_str.as_encoded_bytes();
     /// let words = bytes.split(|b| *b == b' ');
     /// let words: Vec<&OsStr> = words.map(|word| {
     ///     // SAFETY:
-    ///     // - Each `word` only contains content that originated from `OsStr::as_os_str_bytes`
+    ///     // - Each `word` only contains content that originated from `OsStr::as_encoded_bytes`
     ///     // - Only split with ASCII whitespace which is a non-empty UTF-8 substring
-    ///     unsafe { OsStr::from_os_str_bytes_unchecked(word) }
+    ///     unsafe { OsStr::from_encoded_bytes_unchecked(word) }
     /// }).collect();
     /// ```
     ///
     /// [conversions]: super#conversions
     #[inline]
-    #[unstable(feature = "os_str_bytes", issue = "111544")]
-    pub unsafe fn from_os_str_bytes_unchecked(bytes: Vec<u8>) -> Self {
-        OsString { inner: Buf::from_os_str_bytes_unchecked(bytes) }
+    #[stable(feature = "os_str_bytes", since = "CURRENT_RUSTC_VERSION")]
+    pub unsafe fn from_encoded_bytes_unchecked(bytes: Vec<u8>) -> Self {
+        OsString { inner: Buf::from_encoded_bytes_unchecked(bytes) }
     }
 
     /// Converts to an [`OsStr`] slice.
@@ -205,7 +203,7 @@ impl OsString {
     }
 
     /// Converts the `OsString` into a byte slice.  To convert the byte slice back into an
-    /// `OsString`, use the [`OsStr::from_os_str_bytes_unchecked`] function.
+    /// `OsString`, use the [`OsStr::from_encoded_bytes_unchecked`] function.
     ///
     /// The byte encoding is an unspecified, platform-specific, self-synchronizing superset of UTF-8.
     /// By being a self-synchronizing superset of UTF-8, this encoding is also a superset of 7-bit
@@ -219,9 +217,9 @@ impl OsString {
     ///
     /// [`std::ffi`]: crate::ffi
     #[inline]
-    #[unstable(feature = "os_str_bytes", issue = "111544")]
-    pub fn into_os_str_bytes(self) -> Vec<u8> {
-        self.inner.into_os_str_bytes()
+    #[stable(feature = "os_str_bytes", since = "CURRENT_RUSTC_VERSION")]
+    pub fn into_encoded_bytes(self) -> Vec<u8> {
+        self.inner.into_encoded_bytes()
     }
 
     /// Converts the `OsString` into a [`String`] if it contains valid Unicode data.
@@ -745,36 +743,34 @@ impl OsStr {
     /// # Safety
     ///
     /// As the encoding is unspecified, callers must pass in bytes that originated as a mixture of
-    /// validated UTF-8 and bytes from [`OsStr::as_os_str_bytes`] from within the same rust version
+    /// validated UTF-8 and bytes from [`OsStr::as_encoded_bytes`] from within the same rust version
     /// built for the same target platform.  For example, reconstructing an `OsStr` from bytes sent
     /// over the network or stored in a file will likely violate these safety rules.
     ///
-    /// Due to the encoding being self-synchronizing, the bytes from [`OsStr::as_os_str_bytes`] can be
+    /// Due to the encoding being self-synchronizing, the bytes from [`OsStr::as_encoded_bytes`] can be
     /// split either immediately before or immediately after any valid non-empty UTF-8 substring.
     ///
     /// # Example
     ///
     /// ```
-    /// #![feature(os_str_bytes)]
-    ///
     /// use std::ffi::OsStr;
     ///
     /// let os_str = OsStr::new("Mary had a little lamb");
-    /// let bytes = os_str.as_os_str_bytes();
+    /// let bytes = os_str.as_encoded_bytes();
     /// let words = bytes.split(|b| *b == b' ');
     /// let words: Vec<&OsStr> = words.map(|word| {
     ///     // SAFETY:
-    ///     // - Each `word` only contains content that originated from `OsStr::as_os_str_bytes`
+    ///     // - Each `word` only contains content that originated from `OsStr::as_encoded_bytes`
     ///     // - Only split with ASCII whitespace which is a non-empty UTF-8 substring
-    ///     unsafe { OsStr::from_os_str_bytes_unchecked(word) }
+    ///     unsafe { OsStr::from_encoded_bytes_unchecked(word) }
     /// }).collect();
     /// ```
     ///
     /// [conversions]: super#conversions
     #[inline]
-    #[unstable(feature = "os_str_bytes", issue = "111544")]
-    pub unsafe fn from_os_str_bytes_unchecked(bytes: &[u8]) -> &Self {
-        Self::from_inner(Slice::from_os_str_bytes_unchecked(bytes))
+    #[stable(feature = "os_str_bytes", since = "CURRENT_RUSTC_VERSION")]
+    pub unsafe fn from_encoded_bytes_unchecked(bytes: &[u8]) -> &Self {
+        Self::from_inner(Slice::from_encoded_bytes_unchecked(bytes))
     }
 
     #[inline]
@@ -948,7 +944,7 @@ impl OsStr {
     }
 
     /// Converts an OS string slice to a byte slice.  To convert the byte slice back into an OS
-    /// string slice, use the [`OsStr::from_os_str_bytes_unchecked`] function.
+    /// string slice, use the [`OsStr::from_encoded_bytes_unchecked`] function.
     ///
     /// The byte encoding is an unspecified, platform-specific, self-synchronizing superset of UTF-8.
     /// By being a self-synchronizing superset of UTF-8, this encoding is also a superset of 7-bit
@@ -962,9 +958,9 @@ impl OsStr {
     ///
     /// [`std::ffi`]: crate::ffi
     #[inline]
-    #[unstable(feature = "os_str_bytes", issue = "111544")]
-    pub fn as_os_str_bytes(&self) -> &[u8] {
-        self.inner.as_os_str_bytes()
+    #[stable(feature = "os_str_bytes", since = "CURRENT_RUSTC_VERSION")]
+    pub fn as_encoded_bytes(&self) -> &[u8] {
+        self.inner.as_encoded_bytes()
     }
 
     /// Converts this string to its ASCII lower case equivalent in-place.
@@ -1270,7 +1266,7 @@ impl Default for &OsStr {
 impl PartialEq for OsStr {
     #[inline]
     fn eq(&self, other: &OsStr) -> bool {
-        self.as_os_str_bytes().eq(other.as_os_str_bytes())
+        self.as_encoded_bytes().eq(other.as_encoded_bytes())
     }
 }
 
@@ -1297,23 +1293,23 @@ impl Eq for OsStr {}
 impl PartialOrd for OsStr {
     #[inline]
     fn partial_cmp(&self, other: &OsStr) -> Option<cmp::Ordering> {
-        self.as_os_str_bytes().partial_cmp(other.as_os_str_bytes())
+        self.as_encoded_bytes().partial_cmp(other.as_encoded_bytes())
     }
     #[inline]
     fn lt(&self, other: &OsStr) -> bool {
-        self.as_os_str_bytes().lt(other.as_os_str_bytes())
+        self.as_encoded_bytes().lt(other.as_encoded_bytes())
     }
     #[inline]
     fn le(&self, other: &OsStr) -> bool {
-        self.as_os_str_bytes().le(other.as_os_str_bytes())
+        self.as_encoded_bytes().le(other.as_encoded_bytes())
     }
     #[inline]
     fn gt(&self, other: &OsStr) -> bool {
-        self.as_os_str_bytes().gt(other.as_os_str_bytes())
+        self.as_encoded_bytes().gt(other.as_encoded_bytes())
     }
     #[inline]
     fn ge(&self, other: &OsStr) -> bool {
-        self.as_os_str_bytes().ge(other.as_os_str_bytes())
+        self.as_encoded_bytes().ge(other.as_encoded_bytes())
     }
 }
 
@@ -1332,7 +1328,7 @@ impl PartialOrd<str> for OsStr {
 impl Ord for OsStr {
     #[inline]
     fn cmp(&self, other: &OsStr) -> cmp::Ordering {
-        self.as_os_str_bytes().cmp(other.as_os_str_bytes())
+        self.as_encoded_bytes().cmp(other.as_encoded_bytes())
     }
 }
 
@@ -1382,7 +1378,7 @@ impl_cmp!(Cow<'a, OsStr>, OsString);
 impl Hash for OsStr {
     #[inline]
     fn hash<H: Hasher>(&self, state: &mut H) {
-        self.as_os_str_bytes().hash(state)
+        self.as_encoded_bytes().hash(state)
     }
 }
 
diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs
index 3c67bea7a22..adc1b85fd85 100644
--- a/library/std/src/fs.rs
+++ b/library/std/src/fs.rs
@@ -233,8 +233,8 @@ pub struct DirBuilder {
 /// This function will return an error if `path` does not already exist.
 /// Other errors may also be returned according to [`OpenOptions::open`].
 ///
-/// It will also return an error if it encounters while reading an error
-/// of a kind other than [`io::ErrorKind::Interrupted`].
+/// While reading from the file, this function handles [`io::ErrorKind::Interrupted`]
+/// with automatic retries. See [io::Read] documentation for details.
 ///
 /// # Examples
 ///
@@ -271,9 +271,11 @@ pub fn read<P: AsRef<Path>>(path: P) -> io::Result<Vec<u8>> {
 /// This function will return an error if `path` does not already exist.
 /// Other errors may also be returned according to [`OpenOptions::open`].
 ///
-/// It will also return an error if it encounters while reading an error
-/// of a kind other than [`io::ErrorKind::Interrupted`],
-/// or if the contents of the file are not valid UTF-8.
+/// If the contents of the file are not valid UTF-8, then an error will also be
+/// returned.
+///
+/// While reading from the file, this function handles [`io::ErrorKind::Interrupted`]
+/// with automatic retries. See [io::Read] documentation for details.
 ///
 /// # Examples
 ///
diff --git a/library/std/src/path.rs b/library/std/src/path.rs
index 5842c096f1a..60562f64c90 100644
--- a/library/std/src/path.rs
+++ b/library/std/src/path.rs
@@ -193,7 +193,7 @@ impl<'a> Prefix<'a> {
     fn len(&self) -> usize {
         use self::Prefix::*;
         fn os_str_len(s: &OsStr) -> usize {
-            s.as_os_str_bytes().len()
+            s.as_encoded_bytes().len()
         }
         match *self {
             Verbatim(x) => 4 + os_str_len(x),
@@ -316,7 +316,7 @@ fn has_physical_root(s: &[u8], prefix: Option<Prefix<'_>>) -> bool {
 
 // basic workhorse for splitting stem and extension
 fn rsplit_file_at_dot(file: &OsStr) -> (Option<&OsStr>, Option<&OsStr>) {
-    if file.as_os_str_bytes() == b".." {
+    if file.as_encoded_bytes() == b".." {
         return (Some(file), None);
     }
 
@@ -324,7 +324,7 @@ fn rsplit_file_at_dot(file: &OsStr) -> (Option<&OsStr>, Option<&OsStr>) {
     // and back. This is safe to do because (1) we only look at ASCII
     // contents of the encoding and (2) new &OsStr values are produced
     // only from ASCII-bounded slices of existing &OsStr values.
-    let mut iter = file.as_os_str_bytes().rsplitn(2, |b| *b == b'.');
+    let mut iter = file.as_encoded_bytes().rsplitn(2, |b| *b == b'.');
     let after = iter.next();
     let before = iter.next();
     if before == Some(b"") {
@@ -332,15 +332,15 @@ fn rsplit_file_at_dot(file: &OsStr) -> (Option<&OsStr>, Option<&OsStr>) {
     } else {
         unsafe {
             (
-                before.map(|s| OsStr::from_os_str_bytes_unchecked(s)),
-                after.map(|s| OsStr::from_os_str_bytes_unchecked(s)),
+                before.map(|s| OsStr::from_encoded_bytes_unchecked(s)),
+                after.map(|s| OsStr::from_encoded_bytes_unchecked(s)),
             )
         }
     }
 }
 
 fn split_file_at_dot(file: &OsStr) -> (&OsStr, Option<&OsStr>) {
-    let slice = file.as_os_str_bytes();
+    let slice = file.as_encoded_bytes();
     if slice == b".." {
         return (file, None);
     }
@@ -357,8 +357,8 @@ fn split_file_at_dot(file: &OsStr) -> (&OsStr, Option<&OsStr>) {
     let after = &slice[i + 1..];
     unsafe {
         (
-            OsStr::from_os_str_bytes_unchecked(before),
-            Some(OsStr::from_os_str_bytes_unchecked(after)),
+            OsStr::from_encoded_bytes_unchecked(before),
+            Some(OsStr::from_encoded_bytes_unchecked(after)),
         )
     }
 }
@@ -739,7 +739,7 @@ impl<'a> Components<'a> {
             // separately via `include_cur_dir`
             b".." => Some(Component::ParentDir),
             b"" => None,
-            _ => Some(Component::Normal(unsafe { OsStr::from_os_str_bytes_unchecked(comp) })),
+            _ => Some(Component::Normal(unsafe { OsStr::from_encoded_bytes_unchecked(comp) })),
         }
     }
 
@@ -896,7 +896,7 @@ impl<'a> Iterator for Components<'a> {
                     let raw = &self.path[..self.prefix_len()];
                     self.path = &self.path[self.prefix_len()..];
                     return Some(Component::Prefix(PrefixComponent {
-                        raw: unsafe { OsStr::from_os_str_bytes_unchecked(raw) },
+                        raw: unsafe { OsStr::from_encoded_bytes_unchecked(raw) },
                         parsed: self.prefix.unwrap(),
                     }));
                 }
@@ -968,7 +968,7 @@ impl<'a> DoubleEndedIterator for Components<'a> {
                 State::Prefix if self.prefix_len() > 0 => {
                     self.back = State::Done;
                     return Some(Component::Prefix(PrefixComponent {
-                        raw: unsafe { OsStr::from_os_str_bytes_unchecked(self.path) },
+                        raw: unsafe { OsStr::from_encoded_bytes_unchecked(self.path) },
                         parsed: self.prefix.unwrap(),
                     }));
                 }
@@ -1477,17 +1477,17 @@ impl PathBuf {
     fn _set_extension(&mut self, extension: &OsStr) -> bool {
         let file_stem = match self.file_stem() {
             None => return false,
-            Some(f) => f.as_os_str_bytes(),
+            Some(f) => f.as_encoded_bytes(),
         };
 
         // truncate until right after the file stem
         let end_file_stem = file_stem[file_stem.len()..].as_ptr().addr();
-        let start = self.inner.as_os_str_bytes().as_ptr().addr();
+        let start = self.inner.as_encoded_bytes().as_ptr().addr();
         let v = self.as_mut_vec();
         v.truncate(end_file_stem.wrapping_sub(start));
 
         // add the new extension, if any
-        let new = extension.as_os_str_bytes();
+        let new = extension.as_encoded_bytes();
         if !new.is_empty() {
             v.reserve_exact(new.len() + 1);
             v.push(b'.');
@@ -2007,11 +2007,11 @@ impl Path {
     // The following (private!) function allows construction of a path from a u8
     // slice, which is only safe when it is known to follow the OsStr encoding.
     unsafe fn from_u8_slice(s: &[u8]) -> &Path {
-        unsafe { Path::new(OsStr::from_os_str_bytes_unchecked(s)) }
+        unsafe { Path::new(OsStr::from_encoded_bytes_unchecked(s)) }
     }
     // The following (private!) function reveals the byte encoding used for OsStr.
     fn as_u8_slice(&self) -> &[u8] {
-        self.inner.as_os_str_bytes()
+        self.inner.as_encoded_bytes()
     }
 
     /// Directly wraps a string slice as a `Path` slice.
@@ -2609,7 +2609,7 @@ impl Path {
 
     fn _with_extension(&self, extension: &OsStr) -> PathBuf {
         let self_len = self.as_os_str().len();
-        let self_bytes = self.as_os_str().as_os_str_bytes();
+        let self_bytes = self.as_os_str().as_encoded_bytes();
 
         let (new_capacity, slice_to_copy) = match self.extension() {
             None => {
diff --git a/library/std/src/sys/common/small_c_string.rs b/library/std/src/sys/common/small_c_string.rs
index 963d17a47e4..af9b18e372d 100644
--- a/library/std/src/sys/common/small_c_string.rs
+++ b/library/std/src/sys/common/small_c_string.rs
@@ -19,7 +19,7 @@ pub fn run_path_with_cstr<T, F>(path: &Path, f: F) -> io::Result<T>
 where
     F: FnOnce(&CStr) -> io::Result<T>,
 {
-    run_with_cstr(path.as_os_str().as_os_str_bytes(), f)
+    run_with_cstr(path.as_os_str().as_encoded_bytes(), f)
 }
 
 #[inline]
diff --git a/library/std/src/sys/common/tests.rs b/library/std/src/sys/common/tests.rs
index 0a1cbcbe8ef..32dc18ee1cf 100644
--- a/library/std/src/sys/common/tests.rs
+++ b/library/std/src/sys/common/tests.rs
@@ -8,7 +8,7 @@ use core::iter::repeat;
 fn stack_allocation_works() {
     let path = Path::new("abc");
     let result = run_path_with_cstr(path, |p| {
-        assert_eq!(p, &*CString::new(path.as_os_str().as_os_str_bytes()).unwrap());
+        assert_eq!(p, &*CString::new(path.as_os_str().as_encoded_bytes()).unwrap());
         Ok(42)
     });
     assert_eq!(result.unwrap(), 42);
@@ -25,7 +25,7 @@ fn heap_allocation_works() {
     let path = repeat("a").take(384).collect::<String>();
     let path = Path::new(&path);
     let result = run_path_with_cstr(path, |p| {
-        assert_eq!(p, &*CString::new(path.as_os_str().as_os_str_bytes()).unwrap());
+        assert_eq!(p, &*CString::new(path.as_os_str().as_encoded_bytes()).unwrap());
         Ok(42)
     });
     assert_eq!(result.unwrap(), 42);
diff --git a/library/std/src/sys/solid/error.rs b/library/std/src/sys/solid/error.rs
index d1877a8bcd2..547b4f3a984 100644
--- a/library/std/src/sys/solid/error.rs
+++ b/library/std/src/sys/solid/error.rs
@@ -31,11 +31,6 @@ pub fn error_name(er: abi::ER) -> Option<&'static str> {
     }
 }
 
-#[inline]
-fn is_interrupted(er: abi::ER) -> bool {
-    false
-}
-
 pub fn decode_error_kind(er: abi::ER) -> ErrorKind {
     match er {
         // Success
diff --git a/library/std/src/sys/solid/mod.rs b/library/std/src/sys/solid/mod.rs
index e7029174511..5af83653cf8 100644
--- a/library/std/src/sys/solid/mod.rs
+++ b/library/std/src/sys/solid/mod.rs
@@ -74,7 +74,7 @@ pub fn unsupported_err() -> crate::io::Error {
 
 #[inline]
 pub fn is_interrupted(code: i32) -> bool {
-    error::is_interrupted(code)
+    net::is_interrupted(code)
 }
 
 pub fn decode_error_kind(code: i32) -> crate::io::ErrorKind {
diff --git a/library/std/src/sys/solid/net.rs b/library/std/src/sys/solid/net.rs
index bdd64ab02b7..6adced787f3 100644
--- a/library/std/src/sys/solid/net.rs
+++ b/library/std/src/sys/solid/net.rs
@@ -183,8 +183,7 @@ pub(super) fn error_name(er: abi::ER) -> Option<&'static str> {
 
 #[inline]
 pub fn is_interrupted(er: abi::ER) -> bool {
-    let errno = netc::SOLID_NET_ERR_BASE - er;
-    errno as libc::c_int == libc::EINTR
+    er == netc::SOLID_NET_ERR_BASE - libc::EINTR
 }
 
 pub(super) fn decode_error_kind(er: abi::ER) -> ErrorKind {
diff --git a/library/std/src/sys/unix/os_str.rs b/library/std/src/sys/unix/os_str.rs
index 463b0a27515..7bd2f656a24 100644
--- a/library/std/src/sys/unix/os_str.rs
+++ b/library/std/src/sys/unix/os_str.rs
@@ -97,12 +97,12 @@ impl AsInner<[u8]> for Buf {
 
 impl Buf {
     #[inline]
-    pub fn into_os_str_bytes(self) -> Vec<u8> {
+    pub fn into_encoded_bytes(self) -> Vec<u8> {
         self.inner
     }
 
     #[inline]
-    pub unsafe fn from_os_str_bytes_unchecked(s: Vec<u8>) -> Self {
+    pub unsafe fn from_encoded_bytes_unchecked(s: Vec<u8>) -> Self {
         Self { inner: s }
     }
 
@@ -203,18 +203,18 @@ impl Buf {
 
 impl Slice {
     #[inline]
-    pub fn as_os_str_bytes(&self) -> &[u8] {
+    pub fn as_encoded_bytes(&self) -> &[u8] {
         &self.inner
     }
 
     #[inline]
-    pub unsafe fn from_os_str_bytes_unchecked(s: &[u8]) -> &Slice {
+    pub unsafe fn from_encoded_bytes_unchecked(s: &[u8]) -> &Slice {
         unsafe { mem::transmute(s) }
     }
 
     #[inline]
     pub fn from_str(s: &str) -> &Slice {
-        unsafe { Slice::from_os_str_bytes_unchecked(s.as_bytes()) }
+        unsafe { Slice::from_encoded_bytes_unchecked(s.as_bytes()) }
     }
 
     pub fn to_str(&self) -> Result<&str, crate::str::Utf8Error> {
diff --git a/library/std/src/sys/unix/os_str/tests.rs b/library/std/src/sys/unix/os_str/tests.rs
index 91bc0e61a4a..e2a99045e41 100644
--- a/library/std/src/sys/unix/os_str/tests.rs
+++ b/library/std/src/sys/unix/os_str/tests.rs
@@ -2,7 +2,7 @@ use super::*;
 
 #[test]
 fn slice_debug_output() {
-    let input = unsafe { Slice::from_os_str_bytes_unchecked(b"\xF0hello,\tworld") };
+    let input = unsafe { Slice::from_encoded_bytes_unchecked(b"\xF0hello,\tworld") };
     let expected = r#""\xF0hello,\tworld""#;
     let output = format!("{input:?}");
 
@@ -12,6 +12,6 @@ fn slice_debug_output() {
 #[test]
 fn display() {
     assert_eq!("Hello\u{FFFD}\u{FFFD} There\u{FFFD} Goodbye", unsafe {
-        Slice::from_os_str_bytes_unchecked(b"Hello\xC0\x80 There\xE6\x83 Goodbye").to_string()
+        Slice::from_encoded_bytes_unchecked(b"Hello\xC0\x80 There\xE6\x83 Goodbye").to_string()
     },);
 }
diff --git a/library/std/src/sys/unix/path.rs b/library/std/src/sys/unix/path.rs
index 935245f637b..837f68d3eaf 100644
--- a/library/std/src/sys/unix/path.rs
+++ b/library/std/src/sys/unix/path.rs
@@ -30,7 +30,7 @@ pub(crate) fn absolute(path: &Path) -> io::Result<PathBuf> {
 
     // Get the components, skipping the redundant leading "." component if it exists.
     let mut components = path.strip_prefix(".").unwrap_or(path).components();
-    let path_os = path.as_os_str().as_os_str_bytes();
+    let path_os = path.as_os_str().as_encoded_bytes();
 
     let mut normalized = if path.is_absolute() {
         // "If a pathname begins with two successive <slash> characters, the
diff --git a/library/std/src/sys/unix/process/process_common.rs b/library/std/src/sys/unix/process/process_common.rs
index 640648e8707..e7d1533f122 100644
--- a/library/std/src/sys/unix/process/process_common.rs
+++ b/library/std/src/sys/unix/process/process_common.rs
@@ -164,9 +164,9 @@ pub enum ProgramKind {
 
 impl ProgramKind {
     fn new(program: &OsStr) -> Self {
-        if program.as_os_str_bytes().starts_with(b"/") {
+        if program.as_encoded_bytes().starts_with(b"/") {
             Self::Absolute
-        } else if program.as_os_str_bytes().contains(&b'/') {
+        } else if program.as_encoded_bytes().contains(&b'/') {
             // If the program has more than one component in it, it is a relative path.
             Self::Relative
         } else {
diff --git a/library/std/src/sys/windows/args.rs b/library/std/src/sys/windows/args.rs
index 6b597f499bc..ee7dba6e5b3 100644
--- a/library/std/src/sys/windows/args.rs
+++ b/library/std/src/sys/windows/args.rs
@@ -226,7 +226,7 @@ pub(crate) fn append_arg(cmd: &mut Vec<u16>, arg: &Arg, force_quotes: bool) -> i
     // that it actually gets passed through on the command line or otherwise
     // it will be dropped entirely when parsed on the other end.
     ensure_no_nuls(arg)?;
-    let arg_bytes = arg.as_os_str_bytes();
+    let arg_bytes = arg.as_encoded_bytes();
     let (quote, escape) = match quote {
         Quote::Always => (true, true),
         Quote::Auto => {
@@ -298,7 +298,7 @@ pub(crate) fn make_bat_command_line(
         const SPECIAL: &[u8] = b"\t &()[]{}^=;!'+,`~%|<>";
         let force_quotes = match arg {
             Arg::Regular(arg) if !force_quotes => {
-                arg.as_os_str_bytes().iter().any(|c| SPECIAL.contains(c))
+                arg.as_encoded_bytes().iter().any(|c| SPECIAL.contains(c))
             }
             _ => force_quotes,
         };
diff --git a/library/std/src/sys/windows/os_str.rs b/library/std/src/sys/windows/os_str.rs
index 4708657a907..237854fac4e 100644
--- a/library/std/src/sys/windows/os_str.rs
+++ b/library/std/src/sys/windows/os_str.rs
@@ -64,12 +64,12 @@ impl fmt::Display for Slice {
 
 impl Buf {
     #[inline]
-    pub fn into_os_str_bytes(self) -> Vec<u8> {
+    pub fn into_encoded_bytes(self) -> Vec<u8> {
         self.inner.into_bytes()
     }
 
     #[inline]
-    pub unsafe fn from_os_str_bytes_unchecked(s: Vec<u8>) -> Self {
+    pub unsafe fn from_encoded_bytes_unchecked(s: Vec<u8>) -> Self {
         Self { inner: Wtf8Buf::from_bytes_unchecked(s) }
     }
 
@@ -162,12 +162,12 @@ impl Buf {
 
 impl Slice {
     #[inline]
-    pub fn as_os_str_bytes(&self) -> &[u8] {
+    pub fn as_encoded_bytes(&self) -> &[u8] {
         self.inner.as_bytes()
     }
 
     #[inline]
-    pub unsafe fn from_os_str_bytes_unchecked(s: &[u8]) -> &Slice {
+    pub unsafe fn from_encoded_bytes_unchecked(s: &[u8]) -> &Slice {
         mem::transmute(Wtf8::from_bytes_unchecked(s))
     }
 
diff --git a/library/std/src/sys/windows/path.rs b/library/std/src/sys/windows/path.rs
index c9c2d10e6c4..8c0e07b3566 100644
--- a/library/std/src/sys/windows/path.rs
+++ b/library/std/src/sys/windows/path.rs
@@ -22,12 +22,12 @@ pub fn is_verbatim_sep(b: u8) -> bool {
 
 /// Returns true if `path` looks like a lone filename.
 pub(crate) fn is_file_name(path: &OsStr) -> bool {
-    !path.as_os_str_bytes().iter().copied().any(is_sep_byte)
+    !path.as_encoded_bytes().iter().copied().any(is_sep_byte)
 }
 pub(crate) fn has_trailing_slash(path: &OsStr) -> bool {
-    let is_verbatim = path.as_os_str_bytes().starts_with(br"\\?\");
+    let is_verbatim = path.as_encoded_bytes().starts_with(br"\\?\");
     let is_separator = if is_verbatim { is_verbatim_sep } else { is_sep_byte };
-    if let Some(&c) = path.as_os_str_bytes().last() { is_separator(c) } else { false }
+    if let Some(&c) = path.as_encoded_bytes().last() { is_separator(c) } else { false }
 }
 
 /// Appends a suffix to a path.
@@ -49,7 +49,7 @@ impl<'a, const LEN: usize> PrefixParser<'a, LEN> {
     fn get_prefix(path: &OsStr) -> [u8; LEN] {
         let mut prefix = [0; LEN];
         // SAFETY: Only ASCII characters are modified.
-        for (i, &ch) in path.as_os_str_bytes().iter().take(LEN).enumerate() {
+        for (i, &ch) in path.as_encoded_bytes().iter().take(LEN).enumerate() {
             prefix[i] = if ch == b'/' { b'\\' } else { ch };
         }
         prefix
@@ -82,7 +82,7 @@ impl<'a> PrefixParserSlice<'a, '_> {
     }
 
     fn prefix_bytes(&self) -> &'a [u8] {
-        &self.path.as_os_str_bytes()[..self.index]
+        &self.path.as_encoded_bytes()[..self.index]
     }
 
     fn finish(self) -> &'a OsStr {
@@ -90,7 +90,7 @@ impl<'a> PrefixParserSlice<'a, '_> {
         // &[u8] and back. This is safe to do because (1) we only look at ASCII
         // contents of the encoding and (2) new &OsStr values are produced only
         // from ASCII-bounded slices of existing &OsStr values.
-        unsafe { OsStr::from_os_str_bytes_unchecked(&self.path.as_os_str_bytes()[self.index..]) }
+        unsafe { OsStr::from_encoded_bytes_unchecked(&self.path.as_encoded_bytes()[self.index..]) }
     }
 }
 
@@ -162,7 +162,7 @@ fn parse_drive(path: &OsStr) -> Option<u8> {
         drive.is_ascii_alphabetic()
     }
 
-    match path.as_os_str_bytes() {
+    match path.as_encoded_bytes() {
         [drive, b':', ..] if is_valid_drive_letter(drive) => Some(drive.to_ascii_uppercase()),
         _ => None,
     }
@@ -171,7 +171,7 @@ fn parse_drive(path: &OsStr) -> Option<u8> {
 // Parses a drive prefix exactly, e.g. "C:"
 fn parse_drive_exact(path: &OsStr) -> Option<u8> {
     // only parse two bytes: the drive letter and the drive separator
-    if path.as_os_str_bytes().get(2).map(|&x| is_sep_byte(x)).unwrap_or(true) {
+    if path.as_encoded_bytes().get(2).map(|&x| is_sep_byte(x)).unwrap_or(true) {
         parse_drive(path)
     } else {
         None
@@ -185,15 +185,15 @@ fn parse_drive_exact(path: &OsStr) -> Option<u8> {
 fn parse_next_component(path: &OsStr, verbatim: bool) -> (&OsStr, &OsStr) {
     let separator = if verbatim { is_verbatim_sep } else { is_sep_byte };
 
-    match path.as_os_str_bytes().iter().position(|&x| separator(x)) {
+    match path.as_encoded_bytes().iter().position(|&x| separator(x)) {
         Some(separator_start) => {
             let separator_end = separator_start + 1;
 
-            let component = &path.as_os_str_bytes()[..separator_start];
+            let component = &path.as_encoded_bytes()[..separator_start];
 
             // Panic safe
             // The max `separator_end` is `bytes.len()` and `bytes[bytes.len()..]` is a valid index.
-            let path = &path.as_os_str_bytes()[separator_end..];
+            let path = &path.as_encoded_bytes()[separator_end..];
 
             // SAFETY: `path` is a valid wtf8 encoded slice and each of the separators ('/', '\')
             // is encoded in a single byte, therefore `bytes[separator_start]` and
@@ -201,8 +201,8 @@ fn parse_next_component(path: &OsStr, verbatim: bool) -> (&OsStr, &OsStr) {
             // `bytes[..separator_start]` and `bytes[separator_end..]` are valid wtf8 slices.
             unsafe {
                 (
-                    OsStr::from_os_str_bytes_unchecked(component),
-                    OsStr::from_os_str_bytes_unchecked(path),
+                    OsStr::from_encoded_bytes_unchecked(component),
+                    OsStr::from_encoded_bytes_unchecked(path),
                 )
             }
         }
@@ -323,7 +323,7 @@ pub(crate) fn absolute(path: &Path) -> io::Result<PathBuf> {
     // Verbatim paths should not be modified.
     if prefix.map(|x| x.is_verbatim()).unwrap_or(false) {
         // NULs in verbatim paths are rejected for consistency.
-        if path.as_os_str_bytes().contains(&0) {
+        if path.as_encoded_bytes().contains(&0) {
             return Err(io::const_io_error!(
                 io::ErrorKind::InvalidInput,
                 "strings passed to WinAPI cannot contain NULs",
diff --git a/library/std/src/sys/windows/process.rs b/library/std/src/sys/windows/process.rs
index 92edd2f6112..6f46da1748a 100644
--- a/library/std/src/sys/windows/process.rs
+++ b/library/std/src/sys/windows/process.rs
@@ -429,7 +429,7 @@ fn resolve_exe<'a>(
     // Test if the file name has the `exe` extension.
     // This does a case-insensitive `ends_with`.
     let has_exe_suffix = if exe_path.len() >= EXE_SUFFIX.len() {
-        exe_path.as_os_str_bytes()[exe_path.len() - EXE_SUFFIX.len()..]
+        exe_path.as_encoded_bytes()[exe_path.len() - EXE_SUFFIX.len()..]
             .eq_ignore_ascii_case(EXE_SUFFIX.as_bytes())
     } else {
         false
@@ -459,7 +459,7 @@ fn resolve_exe<'a>(
         // From the `CreateProcessW` docs:
         // > If the file name does not contain an extension, .exe is appended.
         // Note that this rule only applies when searching paths.
-        let has_extension = exe_path.as_os_str_bytes().contains(&b'.');
+        let has_extension = exe_path.as_encoded_bytes().contains(&b'.');
 
         // Search the directories given by `search_paths`.
         let result = search_paths(parent_paths, child_paths, |mut path| {
diff --git a/src/bootstrap/llvm.rs b/src/bootstrap/llvm.rs
index c841cb34036..07502e0e9dd 100644
--- a/src/bootstrap/llvm.rs
+++ b/src/bootstrap/llvm.rs
@@ -24,6 +24,7 @@ use crate::util::{self, exe, output, t, up_to_date};
 use crate::{CLang, GitRepo, Kind};
 
 use build_helper::ci::CiEnv;
+use build_helper::git::get_git_merge_base;
 
 #[derive(Clone)]
 pub struct LlvmResult {
@@ -128,13 +129,19 @@ pub fn prebuilt_llvm_config(
 /// This retrieves the LLVM sha we *want* to use, according to git history.
 pub(crate) fn detect_llvm_sha(config: &Config, is_git: bool) -> String {
     let llvm_sha = if is_git {
+        // We proceed in 2 steps. First we get the closest commit that is actually upstream. Then we
+        // walk back further to the last bors merge commit that actually changed LLVM. The first
+        // step will fail on CI because only the `auto` branch exists; we just fall back to `HEAD`
+        // in that case.
+        let closest_upstream =
+            get_git_merge_base(Some(&config.src)).unwrap_or_else(|_| "HEAD".into());
         let mut rev_list = config.git();
         rev_list.args(&[
             PathBuf::from("rev-list"),
             format!("--author={}", config.stage0_metadata.config.git_merge_commit_email).into(),
             "-n1".into(),
             "--first-parent".into(),
-            "HEAD".into(),
+            closest_upstream.into(),
             "--".into(),
             config.src.join("src/llvm-project"),
             config.src.join("src/bootstrap/download-ci-llvm-stamp"),
diff --git a/src/bootstrap/sanity.rs b/src/bootstrap/sanity.rs
index 7e83b508e94..144e2acd09e 100644
--- a/src/bootstrap/sanity.rs
+++ b/src/bootstrap/sanity.rs
@@ -62,6 +62,9 @@ impl Finder {
 }
 
 pub fn check(build: &mut Build) {
+    let skip_target_sanity =
+        env::var_os("BOOTSTRAP_SKIP_TARGET_SANITY").is_some_and(|s| s == "1" || s == "true");
+
     let path = env::var_os("PATH").unwrap_or_default();
     // On Windows, quotes are invalid characters for filename paths, and if
     // one is present as part of the PATH then that can lead to the system
@@ -166,7 +169,7 @@ than building it.
         // FIXME: it would be better to refactor this code to split necessary setup from pure sanity
         // checks, and have a regular flag for skipping the latter. Also see
         // <https://github.com/rust-lang/rust/pull/103569#discussion_r1008741742>.
-        if env::var_os("BOOTSTRAP_SKIP_TARGET_SANITY").is_some() {
+        if skip_target_sanity {
             continue;
         }
 
@@ -205,7 +208,15 @@ than building it.
             }
         }
 
-        // Make sure musl-root is valid
+        // Some environments don't want or need these tools, such as when testing Miri.
+        // FIXME: it would be better to refactor this code to split necessary setup from pure sanity
+        // checks, and have a regular flag for skipping the latter. Also see
+        // <https://github.com/rust-lang/rust/pull/103569#discussion_r1008741742>.
+        if skip_target_sanity {
+            continue;
+        }
+
+        // Make sure musl-root is valid.
         if target.contains("musl") && !target.contains("unikraft") {
             // If this is a native target (host is also musl) and no musl-root is given,
             // fall back to the system toolchain in /usr before giving up
@@ -227,14 +238,6 @@ than building it.
             }
         }
 
-        // Some environments don't want or need these tools, such as when testing Miri.
-        // FIXME: it would be better to refactor this code to split necessary setup from pure sanity
-        // checks, and have a regular flag for skipping the latter. Also see
-        // <https://github.com/rust-lang/rust/pull/103569#discussion_r1008741742>.
-        if env::var_os("BOOTSTRAP_SKIP_TARGET_SANITY").is_some() {
-            continue;
-        }
-
         if need_cmake && target.contains("msvc") {
             // There are three builds of cmake on windows: MSVC, MinGW, and
             // Cygwin. The Cygwin build does not have generators for Visual
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index c1614d02f34..2cb0a8f3c17 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -63,8 +63,9 @@ Tools](#tier-1-with-host-tools).
 ## Tier 2 with Host Tools
 
 Tier 2 targets can be thought of as "guaranteed to build". The Rust project
-builds official binary releases for each tier 2 target, and automated builds
-ensure that each tier 2 target builds after each change. Automated tests are
+builds official binary releases of the standard library (or, in some cases,
+only the `core` library) for each tier 2 target, and automated builds
+ensure that each tier 2 target can be used as build target after each change. Automated tests are
 not always run so it's not guaranteed to produce a working build, but tier 2
 targets often work to quite a good degree and patches are always welcome!
 
@@ -103,11 +104,12 @@ target | notes
 `x86_64-unknown-linux-musl` | 64-bit Linux with MUSL
 [`x86_64-unknown-netbsd`](platform-support/netbsd.md) | NetBSD/amd64
 
-## Tier 2
+## Tier 2 without Host Tools
 
 Tier 2 targets can be thought of as "guaranteed to build". The Rust project
-builds official binary releases for each tier 2 target, and automated builds
-ensure that each tier 2 target builds after each change. Automated tests are
+builds official binary releases of the standard library (or, in some cases,
+only the `core` library) for each tier 2 target, and automated builds
+ensure that each tier 2 target can be used as build target after each change. Automated tests are
 not always run so it's not guaranteed to produce a working build, but tier 2
 targets often work to quite a good degree and patches are always welcome! For
 the full requirements, see [Tier 2 target
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 1e85284371d..b584c32a4c7 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -1959,31 +1959,44 @@ fn can_elide_trait_object_lifetime_bound<'tcx>(
 #[derive(Debug)]
 pub(crate) enum ContainerTy<'tcx> {
     Ref(ty::Region<'tcx>),
-    Regular { ty: DefId, args: ty::Binder<'tcx, &'tcx [ty::GenericArg<'tcx>]>, arg: usize },
+    Regular {
+        ty: DefId,
+        args: ty::Binder<'tcx, &'tcx [ty::GenericArg<'tcx>]>,
+        has_self: bool,
+        arg: usize,
+    },
 }
 
 impl<'tcx> ContainerTy<'tcx> {
     fn object_lifetime_default(self, tcx: TyCtxt<'tcx>) -> ObjectLifetimeDefault<'tcx> {
         match self {
             Self::Ref(region) => ObjectLifetimeDefault::Arg(region),
-            Self::Regular { ty: container, args, arg: index } => {
+            Self::Regular { ty: container, args, has_self, arg: index } => {
                 let (DefKind::Struct
                 | DefKind::Union
                 | DefKind::Enum
                 | DefKind::TyAlias { .. }
-                | DefKind::Trait
-                | DefKind::AssocTy
-                | DefKind::Variant) = tcx.def_kind(container)
+                | DefKind::Trait) = tcx.def_kind(container)
                 else {
                     return ObjectLifetimeDefault::Empty;
                 };
 
                 let generics = tcx.generics_of(container);
-                let param = generics.params[index].def_id;
-                let default = tcx.object_lifetime_default(param);
+                debug_assert_eq!(generics.parent_count, 0);
+
+                // If the container is a trait object type, the arguments won't contain the self type but the
+                // generics of the corresponding trait will. In such a case, offset the index by one.
+                // For comparison, if the container is a trait inside a bound, the arguments do contain the
+                // self type.
+                let offset =
+                    if !has_self && generics.parent.is_none() && generics.has_self { 1 } else { 0 };
+                let param = generics.params[index + offset].def_id;
 
+                let default = tcx.object_lifetime_default(param);
                 match default {
                     rbv::ObjectLifetimeDefault::Param(lifetime) => {
+                        // The index is relative to the parent generics but since we don't have any,
+                        // we don't need to translate it.
                         let index = generics.param_def_id_to_index[&lifetime];
                         let arg = args.skip_binder()[index as usize].expect_region();
                         ObjectLifetimeDefault::Arg(arg)
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 9cf3c068b60..9134d5268da 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -22,6 +22,7 @@ use rustc_hir::lang_items::LangItem;
 use rustc_hir::{BodyId, Mutability};
 use rustc_hir_analysis::check::intrinsic::intrinsic_operation_unsafety;
 use rustc_index::IndexVec;
+use rustc_metadata::rendered_const;
 use rustc_middle::ty::fast_reject::SimplifiedType;
 use rustc_middle::ty::{self, TyCtxt, Visibility};
 use rustc_resolve::rustdoc::{add_doc_fragment, attrs_to_doc_fragments, inner_docs, DocFragment};
@@ -35,7 +36,7 @@ use rustc_target::spec::abi::Abi;
 use crate::clean::cfg::Cfg;
 use crate::clean::external_path;
 use crate::clean::inline::{self, print_inlined_const};
-use crate::clean::utils::{is_literal_expr, print_const_expr, print_evaluated_const};
+use crate::clean::utils::{is_literal_expr, print_evaluated_const};
 use crate::core::DocContext;
 use crate::formats::cache::Cache;
 use crate::formats::item_type::ItemType;
@@ -2086,7 +2087,7 @@ impl Discriminant {
     /// Will be `None` in the case of cross-crate reexports, and may be
     /// simplified
     pub(crate) fn expr(&self, tcx: TyCtxt<'_>) -> Option<String> {
-        self.expr.map(|body| print_const_expr(tcx, body))
+        self.expr.map(|body| rendered_const(tcx, body))
     }
     /// Will always be a machine readable number, without underscores or suffixes.
     pub(crate) fn value(&self, tcx: TyCtxt<'_>) -> String {
@@ -2326,7 +2327,7 @@ impl ConstantKind {
             ConstantKind::TyConst { ref expr } => expr.to_string(),
             ConstantKind::Extern { def_id } => print_inlined_const(tcx, def_id),
             ConstantKind::Local { body, .. } | ConstantKind::Anonymous { body } => {
-                print_const_expr(tcx, body)
+                rendered_const(tcx, body)
             }
         }
     }
diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs
index 80a7a33d2bd..7696ea0f449 100644
--- a/src/librustdoc/clean/utils.rs
+++ b/src/librustdoc/clean/utils.rs
@@ -14,6 +14,7 @@ use rustc_ast::tokenstream::TokenTree;
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::{DefId, LocalDefId, LOCAL_CRATE};
+use rustc_metadata::rendered_const;
 use rustc_middle::mir;
 use rustc_middle::mir::interpret::ConstValue;
 use rustc_middle::ty::{self, GenericArgKind, GenericArgsRef, TyCtxt};
@@ -77,9 +78,10 @@ pub(crate) fn krate(cx: &mut DocContext<'_>) -> Crate {
 pub(crate) fn ty_args_to_args<'tcx>(
     cx: &mut DocContext<'tcx>,
     args: ty::Binder<'tcx, &'tcx [ty::GenericArg<'tcx>]>,
-    mut skip_first: bool,
+    has_self: bool,
     container: Option<DefId>,
 ) -> Vec<GenericArg> {
+    let mut skip_first = has_self;
     let mut ret_val =
         Vec::with_capacity(args.skip_binder().len().saturating_sub(if skip_first { 1 } else { 0 }));
 
@@ -99,6 +101,7 @@ pub(crate) fn ty_args_to_args<'tcx>(
                 container.map(|container| crate::clean::ContainerTy::Regular {
                     ty: container,
                     args,
+                    has_self,
                     arg: index,
                 }),
             ))),
@@ -253,7 +256,7 @@ pub(crate) fn print_const(cx: &DocContext<'_>, n: ty::Const<'_>) -> String {
     match n.kind() {
         ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, args: _ }) => {
             let s = if let Some(def) = def.as_local() {
-                print_const_expr(cx.tcx, cx.tcx.hir().body_owned_by(def))
+                rendered_const(cx.tcx, cx.tcx.hir().body_owned_by(def))
             } else {
                 inline::print_inlined_const(cx.tcx, def)
             };
@@ -365,100 +368,6 @@ pub(crate) fn is_literal_expr(tcx: TyCtxt<'_>, hir_id: hir::HirId) -> bool {
     false
 }
 
-/// Build a textual representation of an unevaluated constant expression.
-///
-/// If the const expression is too complex, an underscore `_` is returned.
-/// For const arguments, it's `{ _ }` to be precise.
-/// This means that the output is not necessarily valid Rust code.
-///
-/// Currently, only
-///
-/// * literals (optionally with a leading `-`)
-/// * unit `()`
-/// * blocks (`{ … }`) around simple expressions and
-/// * paths without arguments
-///
-/// are considered simple enough. Simple blocks are included since they are
-/// necessary to disambiguate unit from the unit type.
-/// This list might get extended in the future.
-///
-/// Without this censoring, in a lot of cases the output would get too large
-/// and verbose. Consider `match` expressions, blocks and deeply nested ADTs.
-/// Further, private and `doc(hidden)` fields of structs would get leaked
-/// since HIR datatypes like the `body` parameter do not contain enough
-/// semantic information for this function to be able to hide them –
-/// at least not without significant performance overhead.
-///
-/// Whenever possible, prefer to evaluate the constant first and try to
-/// use a different method for pretty-printing. Ideally this function
-/// should only ever be used as a fallback.
-pub(crate) fn print_const_expr(tcx: TyCtxt<'_>, body: hir::BodyId) -> String {
-    let hir = tcx.hir();
-    let value = &hir.body(body).value;
-
-    #[derive(PartialEq, Eq)]
-    enum Classification {
-        Literal,
-        Simple,
-        Complex,
-    }
-
-    use Classification::*;
-
-    fn classify(expr: &hir::Expr<'_>) -> Classification {
-        match &expr.kind {
-            hir::ExprKind::Unary(hir::UnOp::Neg, expr) => {
-                if matches!(expr.kind, hir::ExprKind::Lit(_)) { Literal } else { Complex }
-            }
-            hir::ExprKind::Lit(_) => Literal,
-            hir::ExprKind::Tup([]) => Simple,
-            hir::ExprKind::Block(hir::Block { stmts: [], expr: Some(expr), .. }, _) => {
-                if classify(expr) == Complex { Complex } else { Simple }
-            }
-            // Paths with a self-type or arguments are too “complex” following our measure since
-            // they may leak private fields of structs (with feature `adt_const_params`).
-            // Consider: `<Self as Trait<{ Struct { private: () } }>>::CONSTANT`.
-            // Paths without arguments are definitely harmless though.
-            hir::ExprKind::Path(hir::QPath::Resolved(_, hir::Path { segments, .. })) => {
-                if segments.iter().all(|segment| segment.args.is_none()) { Simple } else { Complex }
-            }
-            // FIXME: Claiming that those kinds of QPaths are simple is probably not true if the Ty
-            //        contains const arguments. Is there a *concise* way to check for this?
-            hir::ExprKind::Path(hir::QPath::TypeRelative(..)) => Simple,
-            // FIXME: Can they contain const arguments and thus leak private struct fields?
-            hir::ExprKind::Path(hir::QPath::LangItem(..)) => Simple,
-            _ => Complex,
-        }
-    }
-
-    let classification = classify(value);
-
-    if classification == Literal
-    && !value.span.from_expansion()
-    && let Ok(snippet) = tcx.sess.source_map().span_to_snippet(value.span) {
-        // For literals, we avoid invoking the pretty-printer and use the source snippet instead to
-        // preserve certain stylistic choices the user likely made for the sake legibility like
-        //
-        // * hexadecimal notation
-        // * underscores
-        // * character escapes
-        //
-        // FIXME: This passes through `-/*spacer*/0` verbatim.
-        snippet
-    } else if classification == Simple {
-        // Otherwise we prefer pretty-printing to get rid of extraneous whitespace, comments and
-        // other formatting artifacts.
-        rustc_hir_pretty::id_to_string(&hir, body.hir_id)
-    } else if tcx.def_kind(hir.body_owner_def_id(body).to_def_id()) == DefKind::AnonConst {
-        // FIXME: Omit the curly braces if the enclosing expression is an array literal
-        //        with a repeated element (an `ExprKind::Repeat`) as in such case it
-        //        would not actually need any disambiguation.
-        "{ _ }".to_owned()
-    } else {
-        "_".to_owned()
-    }
-}
-
 /// Given a type Path, resolve it to a Type using the TyCtxt
 pub(crate) fn resolve_type(cx: &mut DocContext<'_>, path: Path) -> Type {
     debug!("resolve_type({path:?})");
diff --git a/src/librustdoc/html/render/search_index.rs b/src/librustdoc/html/render/search_index.rs
index f34be120d29..145c7d18dd0 100644
--- a/src/librustdoc/html/render/search_index.rs
+++ b/src/librustdoc/html/render/search_index.rs
@@ -1,10 +1,10 @@
 use std::collections::hash_map::Entry;
 use std::collections::BTreeMap;
 
-use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
 use rustc_middle::ty::TyCtxt;
 use rustc_span::symbol::Symbol;
-use serde::ser::{Serialize, SerializeStruct, Serializer};
+use serde::ser::{Serialize, SerializeSeq, SerializeStruct, Serializer};
 
 use crate::clean;
 use crate::clean::types::{Function, Generics, ItemId, Type, WherePredicate};
@@ -78,9 +78,9 @@ pub(crate) fn build_index<'tcx>(
             map: &mut FxHashMap<F, usize>,
             itemid: F,
             lastpathid: &mut usize,
-            crate_paths: &mut Vec<(ItemType, Symbol)>,
+            crate_paths: &mut Vec<(ItemType, Vec<Symbol>)>,
             item_type: ItemType,
-            path: Symbol,
+            path: &[Symbol],
         ) {
             match map.entry(itemid) {
                 Entry::Occupied(entry) => ty.id = Some(RenderTypeId::Index(*entry.get())),
@@ -88,7 +88,7 @@ pub(crate) fn build_index<'tcx>(
                     let pathid = *lastpathid;
                     entry.insert(pathid);
                     *lastpathid += 1;
-                    crate_paths.push((item_type, path));
+                    crate_paths.push((item_type, path.to_vec()));
                     ty.id = Some(RenderTypeId::Index(pathid));
                 }
             }
@@ -100,7 +100,7 @@ pub(crate) fn build_index<'tcx>(
             itemid_to_pathid: &mut FxHashMap<ItemId, usize>,
             primitives: &mut FxHashMap<Symbol, usize>,
             lastpathid: &mut usize,
-            crate_paths: &mut Vec<(ItemType, Symbol)>,
+            crate_paths: &mut Vec<(ItemType, Vec<Symbol>)>,
         ) {
             if let Some(generics) = &mut ty.generics {
                 for item in generics {
@@ -131,7 +131,7 @@ pub(crate) fn build_index<'tcx>(
                             lastpathid,
                             crate_paths,
                             item_type,
-                            *fqp.last().unwrap(),
+                            fqp,
                         );
                     } else {
                         ty.id = None;
@@ -146,7 +146,7 @@ pub(crate) fn build_index<'tcx>(
                         lastpathid,
                         crate_paths,
                         ItemType::Primitive,
-                        sym,
+                        &[sym],
                     );
                 }
                 RenderTypeId::Index(_) => {}
@@ -191,7 +191,7 @@ pub(crate) fn build_index<'tcx>(
                         lastpathid += 1;
 
                         if let Some(&(ref fqp, short)) = paths.get(&defid) {
-                            crate_paths.push((short, *fqp.last().unwrap()));
+                            crate_paths.push((short, fqp.clone()));
                             Some(pathid)
                         } else {
                             None
@@ -213,118 +213,163 @@ pub(crate) fn build_index<'tcx>(
     struct CrateData<'a> {
         doc: String,
         items: Vec<&'a IndexItem>,
-        paths: Vec<(ItemType, Symbol)>,
+        paths: Vec<(ItemType, Vec<Symbol>)>,
         // The String is alias name and the vec is the list of the elements with this alias.
         //
         // To be noted: the `usize` elements are indexes to `items`.
         aliases: &'a BTreeMap<String, Vec<usize>>,
     }
 
+    struct Paths {
+        ty: ItemType,
+        name: Symbol,
+        path: Option<usize>,
+    }
+
+    impl Serialize for Paths {
+        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+        where
+            S: Serializer,
+        {
+            let mut seq = serializer.serialize_seq(None)?;
+            seq.serialize_element(&self.ty)?;
+            seq.serialize_element(self.name.as_str())?;
+            if let Some(ref path) = self.path {
+                seq.serialize_element(path)?;
+            }
+            seq.end()
+        }
+    }
+
     impl<'a> Serialize for CrateData<'a> {
         fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
         where
             S: Serializer,
         {
+            let mut extra_paths = FxHashMap::default();
+            // We need to keep the order of insertion, hence why we use an `IndexMap`. Then we will
+            // insert these "extra paths" (which are paths of items from external crates) into the
+            // `full_paths` list at the end.
+            let mut revert_extra_paths = FxIndexMap::default();
+            let mut mod_paths = FxHashMap::default();
+            for (index, item) in self.items.iter().enumerate() {
+                if item.path.is_empty() {
+                    continue;
+                }
+                mod_paths.insert(&item.path, index);
+            }
+            let mut paths = Vec::with_capacity(self.paths.len());
+            for (ty, path) in &self.paths {
+                if path.len() < 2 {
+                    paths.push(Paths { ty: *ty, name: path[0], path: None });
+                    continue;
+                }
+                let full_path = join_with_double_colon(&path[..path.len() - 1]);
+                if let Some(index) = mod_paths.get(&full_path) {
+                    paths.push(Paths { ty: *ty, name: *path.last().unwrap(), path: Some(*index) });
+                    continue;
+                }
+                // It means it comes from an external crate so the item and its path will be
+                // stored into another array.
+                //
+                // `index` is put after the last `mod_paths`
+                let index = extra_paths.len() + self.items.len();
+                if !revert_extra_paths.contains_key(&index) {
+                    revert_extra_paths.insert(index, full_path.clone());
+                }
+                match extra_paths.entry(full_path) {
+                    Entry::Occupied(entry) => {
+                        paths.push(Paths {
+                            ty: *ty,
+                            name: *path.last().unwrap(),
+                            path: Some(*entry.get()),
+                        });
+                    }
+                    Entry::Vacant(entry) => {
+                        entry.insert(index);
+                        paths.push(Paths {
+                            ty: *ty,
+                            name: *path.last().unwrap(),
+                            path: Some(index),
+                        });
+                    }
+                }
+            }
+
+            let mut names = Vec::with_capacity(self.items.len());
+            let mut types = String::with_capacity(self.items.len());
+            let mut full_paths = Vec::with_capacity(self.items.len());
+            let mut descriptions = Vec::with_capacity(self.items.len());
+            let mut parents = Vec::with_capacity(self.items.len());
+            let mut functions = Vec::with_capacity(self.items.len());
+            let mut deprecated = Vec::with_capacity(self.items.len());
+
+            for (index, item) in self.items.iter().enumerate() {
+                let n = item.ty as u8;
+                let c = char::try_from(n + b'A').expect("item types must fit in ASCII");
+                assert!(c <= 'z', "item types must fit within ASCII printables");
+                types.push(c);
+
+                assert_eq!(
+                    item.parent.is_some(),
+                    item.parent_idx.is_some(),
+                    "`{}` is missing idx",
+                    item.name
+                );
+                // 0 is a sentinel, everything else is one-indexed
+                parents.push(item.parent_idx.map(|x| x + 1).unwrap_or(0));
+
+                names.push(item.name.as_str());
+                descriptions.push(&item.desc);
+
+                if !item.path.is_empty() {
+                    full_paths.push((index, &item.path));
+                }
+
+                // Fake option to get `0` out as a sentinel instead of `null`.
+                // We want to use `0` because it's three less bytes.
+                enum FunctionOption<'a> {
+                    Function(&'a IndexItemFunctionType),
+                    None,
+                }
+                impl<'a> Serialize for FunctionOption<'a> {
+                    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+                    where
+                        S: Serializer,
+                    {
+                        match self {
+                            FunctionOption::None => 0.serialize(serializer),
+                            FunctionOption::Function(ty) => ty.serialize(serializer),
+                        }
+                    }
+                }
+                functions.push(match &item.search_type {
+                    Some(ty) => FunctionOption::Function(ty),
+                    None => FunctionOption::None,
+                });
+
+                if item.deprecation.is_some() {
+                    deprecated.push(index);
+                }
+            }
+
+            for (index, path) in &revert_extra_paths {
+                full_paths.push((*index, path));
+            }
+
             let has_aliases = !self.aliases.is_empty();
             let mut crate_data =
                 serializer.serialize_struct("CrateData", if has_aliases { 9 } else { 8 })?;
             crate_data.serialize_field("doc", &self.doc)?;
-            crate_data.serialize_field(
-                "t",
-                &self
-                    .items
-                    .iter()
-                    .map(|item| {
-                        let n = item.ty as u8;
-                        let c = char::try_from(n + b'A').expect("item types must fit in ASCII");
-                        assert!(c <= 'z', "item types must fit within ASCII printables");
-                        c
-                    })
-                    .collect::<String>(),
-            )?;
-            crate_data.serialize_field(
-                "n",
-                &self.items.iter().map(|item| item.name.as_str()).collect::<Vec<_>>(),
-            )?;
-            crate_data.serialize_field(
-                "q",
-                &self
-                    .items
-                    .iter()
-                    .enumerate()
-                    // Serialize as an array of item indices and full paths
-                    .filter_map(
-                        |(index, item)| {
-                            if item.path.is_empty() { None } else { Some((index, &item.path)) }
-                        },
-                    )
-                    .collect::<Vec<_>>(),
-            )?;
-            crate_data.serialize_field(
-                "d",
-                &self.items.iter().map(|item| &item.desc).collect::<Vec<_>>(),
-            )?;
-            crate_data.serialize_field(
-                "i",
-                &self
-                    .items
-                    .iter()
-                    .map(|item| {
-                        assert_eq!(
-                            item.parent.is_some(),
-                            item.parent_idx.is_some(),
-                            "`{}` is missing idx",
-                            item.name
-                        );
-                        // 0 is a sentinel, everything else is one-indexed
-                        item.parent_idx.map(|x| x + 1).unwrap_or(0)
-                    })
-                    .collect::<Vec<_>>(),
-            )?;
-            crate_data.serialize_field(
-                "f",
-                &self
-                    .items
-                    .iter()
-                    .map(|item| {
-                        // Fake option to get `0` out as a sentinel instead of `null`.
-                        // We want to use `0` because it's three less bytes.
-                        enum FunctionOption<'a> {
-                            Function(&'a IndexItemFunctionType),
-                            None,
-                        }
-                        impl<'a> Serialize for FunctionOption<'a> {
-                            fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
-                            where
-                                S: Serializer,
-                            {
-                                match self {
-                                    FunctionOption::None => 0.serialize(serializer),
-                                    FunctionOption::Function(ty) => ty.serialize(serializer),
-                                }
-                            }
-                        }
-                        match &item.search_type {
-                            Some(ty) => FunctionOption::Function(ty),
-                            None => FunctionOption::None,
-                        }
-                    })
-                    .collect::<Vec<_>>(),
-            )?;
-            crate_data.serialize_field(
-                "c",
-                &self
-                    .items
-                    .iter()
-                    .enumerate()
-                    // Serialize as an array of deprecated item indices
-                    .filter_map(|(index, item)| item.deprecation.map(|_| index))
-                    .collect::<Vec<_>>(),
-            )?;
-            crate_data.serialize_field(
-                "p",
-                &self.paths.iter().map(|(it, s)| (it, s.as_str())).collect::<Vec<_>>(),
-            )?;
+            crate_data.serialize_field("t", &types)?;
+            crate_data.serialize_field("n", &names)?;
+            // Serialize as an array of item indices and full paths
+            crate_data.serialize_field("q", &full_paths)?;
+            crate_data.serialize_field("d", &descriptions)?;
+            crate_data.serialize_field("i", &parents)?;
+            crate_data.serialize_field("f", &functions)?;
+            crate_data.serialize_field("c", &deprecated)?;
+            crate_data.serialize_field("p", &paths)?;
             if has_aliases {
                 crate_data.serialize_field("a", &self.aliases)?;
             }
diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js
index 42088e73554..449168c460b 100644
--- a/src/librustdoc/html/static/js/search.js
+++ b/src/librustdoc/html/static/js/search.js
@@ -263,7 +263,6 @@ function initSearch(rawSearchIndex) {
      * @returns {integer}
      */
     function buildTypeMapIndex(name) {
-
         if (name === "" || name === null) {
             return -1;
         }
@@ -1380,7 +1379,7 @@ function initSearch(rawSearchIndex) {
              * @type Map<integer, QueryElement[]>
              */
             const queryElemSet = new Map();
-            const addQueryElemToQueryElemSet = function addQueryElemToQueryElemSet(queryElem) {
+            const addQueryElemToQueryElemSet = queryElem => {
                 let currentQueryElemList;
                 if (queryElemSet.has(queryElem.id)) {
                     currentQueryElemList = queryElemSet.get(queryElem.id);
@@ -1397,7 +1396,7 @@ function initSearch(rawSearchIndex) {
              * @type Map<integer, FunctionType[]>
              */
             const fnTypeSet = new Map();
-            const addFnTypeToFnTypeSet = function addFnTypeToFnTypeSet(fnType) {
+            const addFnTypeToFnTypeSet = fnType => {
                 // Pure generic, or an item that's not matched by any query elems.
                 // Try [unboxing] it.
                 //
@@ -1463,6 +1462,32 @@ function initSearch(rawSearchIndex) {
                     if (!typePassesFilter(queryElem.typeFilter, fnType.ty)) {
                         continue;
                     }
+                    const queryElemPathLength = queryElem.pathWithoutLast.length;
+                    // If the query element is a path (it contains `::`), we need to check if this
+                    // path is compatible with the target type.
+                    if (queryElemPathLength > 0) {
+                        const fnTypePath = fnType.path !== undefined && fnType.path !== null ?
+                            fnType.path.split("::") : [];
+                        // If the path provided in the query element is longer than this type,
+                        // no need to check it since it won't match in any case.
+                        if (queryElemPathLength > fnTypePath.length) {
+                            continue;
+                        }
+                        let i = 0;
+                        for (const path of fnTypePath) {
+                            if (path === queryElem.pathWithoutLast[i]) {
+                                i += 1;
+                                if (i >= queryElemPathLength) {
+                                    break;
+                                }
+                            }
+                        }
+                        if (i < queryElemPathLength) {
+                            // If we didn't find all parts of the path of the query element inside
+                            // the fn type, then it's not the right one.
+                            continue;
+                        }
+                    }
                     if (queryElem.generics.length === 0 || checkGenerics(fnType, queryElem)) {
                         currentFnTypeList.splice(i, 1);
                         const result = doHandleQueryElemList(currentFnTypeList, queryElemList);
@@ -1863,14 +1888,14 @@ function initSearch(rawSearchIndex) {
              * @param {QueryElement} elem
              */
             function convertNameToId(elem) {
-                if (typeNameIdMap.has(elem.name)) {
-                    elem.id = typeNameIdMap.get(elem.name);
+                if (typeNameIdMap.has(elem.pathLast)) {
+                    elem.id = typeNameIdMap.get(elem.pathLast);
                 } else if (!parsedQuery.literalSearch) {
                     let match = -1;
                     let matchDist = maxEditDistance + 1;
                     let matchName = "";
                     for (const [name, id] of typeNameIdMap) {
-                        const dist = editDistance(name, elem.name, maxEditDistance);
+                        const dist = editDistance(name, elem.pathLast, maxEditDistance);
                         if (dist <= matchDist && dist <= maxEditDistance) {
                             if (dist === matchDist && matchName > name) {
                                 continue;
@@ -2385,12 +2410,20 @@ ${item.displayPath}<span class="${type}">${name}</span>\
                     lowercasePaths
                 );
             }
+            // `0` is used as a sentinel because it's fewer bytes than `null`
+            if (pathIndex === 0) {
+                return {
+                    id: -1,
+                    ty: null,
+                    path: null,
+                    generics: generics,
+                };
+            }
+            const item = lowercasePaths[pathIndex - 1];
             return {
-                // `0` is used as a sentinel because it's fewer bytes than `null`
-                id: pathIndex === 0
-                    ? -1
-                    : buildTypeMapIndex(lowercasePaths[pathIndex - 1].name),
-                ty: pathIndex === 0 ? null : lowercasePaths[pathIndex - 1].ty,
+                id: buildTypeMapIndex(item.name),
+                ty: item.ty,
+                path: item.path,
                 generics: generics,
             };
         });
@@ -2422,13 +2455,22 @@ ${item.displayPath}<span class="${type}">${name}</span>\
         let inputs, output;
         if (typeof functionSearchType[INPUTS_DATA] === "number") {
             const pathIndex = functionSearchType[INPUTS_DATA];
-            inputs = [{
-                id: pathIndex === 0
-                    ? -1
-                    : buildTypeMapIndex(lowercasePaths[pathIndex - 1].name),
-                ty: pathIndex === 0 ? null : lowercasePaths[pathIndex - 1].ty,
-                generics: [],
-            }];
+            if (pathIndex === 0) {
+                inputs = [{
+                    id: -1,
+                    ty: null,
+                    path: null,
+                    generics: [],
+                }];
+            } else {
+                const item = lowercasePaths[pathIndex - 1];
+                inputs = [{
+                    id: buildTypeMapIndex(item.name),
+                    ty: item.ty,
+                    path: item.path,
+                    generics: [],
+                }];
+            }
         } else {
             inputs = buildItemSearchTypeAll(
                 functionSearchType[INPUTS_DATA],
@@ -2438,13 +2480,22 @@ ${item.displayPath}<span class="${type}">${name}</span>\
         if (functionSearchType.length > 1) {
             if (typeof functionSearchType[OUTPUT_DATA] === "number") {
                 const pathIndex = functionSearchType[OUTPUT_DATA];
-                output = [{
-                    id: pathIndex === 0
-                        ? -1
-                        : buildTypeMapIndex(lowercasePaths[pathIndex - 1].name),
-                    ty: pathIndex === 0 ? null : lowercasePaths[pathIndex - 1].ty,
-                    generics: [],
-                }];
+                if (pathIndex === 0) {
+                    output = [{
+                        id: -1,
+                        ty: null,
+                        path: null,
+                        generics: [],
+                    }];
+                } else {
+                    const item = lowercasePaths[pathIndex - 1];
+                    output = [{
+                        id: buildTypeMapIndex(item.name),
+                        ty: item.ty,
+                        path: item.path,
+                        generics: [],
+                    }];
+                }
             } else {
                 output = buildItemSearchTypeAll(
                     functionSearchType[OUTPUT_DATA],
@@ -2577,9 +2628,19 @@ ${item.displayPath}<span class="${type}">${name}</span>\
             // convert `rawPaths` entries into object form
             // generate normalizedPaths for function search mode
             let len = paths.length;
+            let lastPath = itemPaths.get(0);
             for (let i = 0; i < len; ++i) {
-                lowercasePaths.push({ty: paths[i][0], name: paths[i][1].toLowerCase()});
-                paths[i] = {ty: paths[i][0], name: paths[i][1]};
+                const elem = paths[i];
+                const ty = elem[0];
+                const name = elem[1];
+                let path = null;
+                if (elem.length > 2) {
+                    path = itemPaths.has(elem[2]) ? itemPaths.get(elem[2]) : lastPath;
+                    lastPath = path;
+                }
+
+                lowercasePaths.push({ty: ty, name: name.toLowerCase(), path: path});
+                paths[i] = {ty: ty, name: name, path: path};
             }
 
             // convert `item*` into an object form, and construct word indices.
@@ -2589,8 +2650,8 @@ ${item.displayPath}<span class="${type}">${name}</span>\
             // operation that is cached for the life of the page state so that
             // all other search operations have access to this cached data for
             // faster analysis operations
+            lastPath = "";
             len = itemTypes.length;
-            let lastPath = "";
             for (let i = 0; i < len; ++i) {
                 let word = "";
                 // This object should have exactly the same set of fields as the "crateRow"
@@ -2599,11 +2660,12 @@ ${item.displayPath}<span class="${type}">${name}</span>\
                     word = itemNames[i].toLowerCase();
                 }
                 searchWords.push(word);
+                const path = itemPaths.has(i) ? itemPaths.get(i) : lastPath;
                 const row = {
                     crate: crate,
                     ty: itemTypes.charCodeAt(i) - charA,
                     name: itemNames[i],
-                    path: itemPaths.has(i) ? itemPaths.get(i) : lastPath,
+                    path: path,
                     desc: itemDescs[i],
                     parent: itemParentIdxs[i] > 0 ? paths[itemParentIdxs[i] - 1] : undefined,
                     type: buildFunctionSearchType(
diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs
index 66b5798797f..0c18f5687f5 100644
--- a/src/librustdoc/json/conversions.rs
+++ b/src/librustdoc/json/conversions.rs
@@ -8,6 +8,7 @@ use std::fmt;
 
 use rustc_ast::ast;
 use rustc_hir::{def::CtorKind, def::DefKind, def_id::DefId};
+use rustc_metadata::rendered_const;
 use rustc_middle::ty::{self, TyCtxt};
 use rustc_span::symbol::sym;
 use rustc_span::{Pos, Symbol};
@@ -15,7 +16,6 @@ use rustc_target::spec::abi::Abi as RustcAbi;
 
 use rustdoc_json_types::*;
 
-use crate::clean::utils::print_const_expr;
 use crate::clean::{self, ItemId};
 use crate::formats::item_type::ItemType;
 use crate::json::JsonRenderer;
@@ -805,7 +805,7 @@ impl FromWithTcx<clean::Static> for Static {
         Static {
             type_: stat.type_.into_tcx(tcx),
             mutable: stat.mutability == ast::Mutability::Mut,
-            expr: stat.expr.map(|e| print_const_expr(tcx, e)).unwrap_or_default(),
+            expr: stat.expr.map(|e| rendered_const(tcx, e)).unwrap_or_default(),
         }
     }
 }
diff --git a/src/tools/build_helper/src/git.rs b/src/tools/build_helper/src/git.rs
index 66876e02c19..f20b7a2b4d7 100644
--- a/src/tools/build_helper/src/git.rs
+++ b/src/tools/build_helper/src/git.rs
@@ -78,13 +78,22 @@ pub fn rev_exists(rev: &str, git_dir: Option<&Path>) -> Result<bool, String> {
 /// We will then fall back to origin/master in the hope that at least this exists.
 pub fn updated_master_branch(git_dir: Option<&Path>) -> Result<String, String> {
     let upstream_remote = get_rust_lang_rust_remote(git_dir)?;
-    let upstream_master = format!("{upstream_remote}/master");
-    if rev_exists(&upstream_master, git_dir)? {
-        return Ok(upstream_master);
+    for upstream_master in [format!("{upstream_remote}/master"), format!("origin/master")] {
+        if rev_exists(&upstream_master, git_dir)? {
+            return Ok(upstream_master);
+        }
     }
 
-    // We could implement smarter logic here in the future.
-    Ok("origin/master".into())
+    Err(format!("Cannot find any suitable upstream master branch"))
+}
+
+pub fn get_git_merge_base(git_dir: Option<&Path>) -> Result<String, String> {
+    let updated_master = updated_master_branch(git_dir)?;
+    let mut git = Command::new("git");
+    if let Some(git_dir) = git_dir {
+        git.current_dir(git_dir);
+    }
+    Ok(output_result(git.arg("merge-base").arg(&updated_master).arg("HEAD"))?.trim().to_owned())
 }
 
 /// Returns the files that have been modified in the current branch compared to the master branch.
@@ -94,20 +103,13 @@ pub fn get_git_modified_files(
     git_dir: Option<&Path>,
     extensions: &Vec<&str>,
 ) -> Result<Option<Vec<String>>, String> {
-    let Ok(updated_master) = updated_master_branch(git_dir) else {
-        return Ok(None);
-    };
-
-    let git = || {
-        let mut git = Command::new("git");
-        if let Some(git_dir) = git_dir {
-            git.current_dir(git_dir);
-        }
-        git
-    };
+    let merge_base = get_git_merge_base(git_dir)?;
 
-    let merge_base = output_result(git().arg("merge-base").arg(&updated_master).arg("HEAD"))?;
-    let files = output_result(git().arg("diff-index").arg("--name-only").arg(merge_base.trim()))?
+    let mut git = Command::new("git");
+    if let Some(git_dir) = git_dir {
+        git.current_dir(git_dir);
+    }
+    let files = output_result(git.args(["diff-index", "--name-only", merge_base.trim()]))?
         .lines()
         .map(|s| s.trim().to_owned())
         .filter(|f| {
diff --git a/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs b/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs
index f9108145cdb..a687c7d29b5 100644
--- a/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs
@@ -1,24 +1,20 @@
 use super::ARITHMETIC_SIDE_EFFECTS;
 use clippy_utils::consts::{constant, constant_simple, Constant};
 use clippy_utils::diagnostics::span_lint;
+use clippy_utils::ty::type_diagnostic_name;
 use clippy_utils::{expr_or_init, is_from_proc_macro, is_lint_allowed, peel_hir_expr_refs, peel_hir_expr_unary};
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::Ty;
 use rustc_session::impl_lint_pass;
 use rustc_span::source_map::{Span, Spanned};
+use rustc_span::symbol::sym;
 use rustc_span::Symbol;
 use {rustc_ast as ast, rustc_hir as hir};
 
-const HARD_CODED_ALLOWED_BINARY: &[[&str; 2]] = &[
-    ["f32", "f32"],
-    ["f64", "f64"],
-    ["std::num::Saturating", "*"],
-    ["std::num::Wrapping", "*"],
-    ["std::string::String", "str"],
-];
+const HARD_CODED_ALLOWED_BINARY: &[[&str; 2]] = &[["f32", "f32"], ["f64", "f64"], ["std::string::String", "str"]];
 const HARD_CODED_ALLOWED_UNARY: &[&str] = &["f32", "f64", "std::num::Saturating", "std::num::Wrapping"];
-const INTEGER_METHODS: &[&str] = &["saturating_div", "wrapping_div", "wrapping_rem", "wrapping_rem_euclid"];
+const INTEGER_METHODS: &[Symbol] = &[sym::saturating_div, sym::wrapping_div, sym::wrapping_rem, sym::wrapping_rem_euclid];
 
 #[derive(Debug)]
 pub struct ArithmeticSideEffects {
@@ -53,7 +49,7 @@ impl ArithmeticSideEffects {
             allowed_unary,
             const_span: None,
             expr_span: None,
-            integer_methods: INTEGER_METHODS.iter().map(|el| Symbol::intern(el)).collect(),
+            integer_methods: INTEGER_METHODS.iter().copied().collect(),
         }
     }
 
@@ -86,6 +82,38 @@ impl ArithmeticSideEffects {
         self.allowed_unary.contains(ty_string_elem)
     }
 
+    /// Verifies built-in types that have specific allowed operations
+    fn has_specific_allowed_type_and_operation(
+        cx: &LateContext<'_>,
+        lhs_ty: Ty<'_>,
+        op: &Spanned<hir::BinOpKind>,
+        rhs_ty: Ty<'_>,
+    ) -> bool {
+        let is_div_or_rem = matches!(op.node, hir::BinOpKind::Div | hir::BinOpKind::Rem);
+        let is_non_zero_u = |symbol: Option<Symbol>| {
+            matches!(
+                symbol,
+                Some(sym::NonZeroU128 | sym::NonZeroU16 | sym::NonZeroU32 | sym::NonZeroU64 | sym::NonZeroU8 | sym::NonZeroUsize)
+            )
+        };
+        let is_sat_or_wrap = |ty: Ty<'_>| {
+            let is_sat = type_diagnostic_name(cx, ty) == Some(sym::Saturating);
+            let is_wrap = type_diagnostic_name(cx, ty) == Some(sym::Wrapping);
+            is_sat || is_wrap
+        };
+
+        // If the RHS is NonZeroU*, then division or module by zero will never occur
+        if is_non_zero_u(type_diagnostic_name(cx, rhs_ty)) && is_div_or_rem {
+            return true;
+        }
+        // `Saturation` and `Wrapping` can overflow if the RHS is zero in a division or module
+        if is_sat_or_wrap(lhs_ty) {
+            return !is_div_or_rem;
+        }
+
+        false
+    }
+
     // For example, 8i32 or &i64::MAX.
     fn is_integral(ty: Ty<'_>) -> bool {
         ty.peel_refs().is_integral()
@@ -147,6 +175,9 @@ impl ArithmeticSideEffects {
         if self.has_allowed_binary(lhs_ty, rhs_ty) {
             return;
         }
+        if Self::has_specific_allowed_type_and_operation(cx, lhs_ty, op, rhs_ty) {
+            return;
+        }
         let has_valid_op = if Self::is_integral(lhs_ty) && Self::is_integral(rhs_ty) {
             if let hir::BinOpKind::Shl | hir::BinOpKind::Shr = op.node {
                 // At least for integers, shifts are already handled by the CTFE
diff --git a/src/tools/clippy/tests/ui/arithmetic_side_effects.rs b/src/tools/clippy/tests/ui/arithmetic_side_effects.rs
index 8485b3eab71..def30f5903d 100644
--- a/src/tools/clippy/tests/ui/arithmetic_side_effects.rs
+++ b/src/tools/clippy/tests/ui/arithmetic_side_effects.rs
@@ -15,7 +15,7 @@
 
 extern crate proc_macro_derive;
 
-use core::num::{Saturating, Wrapping};
+use core::num::{NonZeroUsize, Saturating, Wrapping};
 
 const ONE: i32 = 1;
 const ZERO: i32 = 0;
@@ -493,4 +493,32 @@ pub fn issue_11262() {
     let _ = 2 / zero;
 }
 
+pub fn issue_11392() {
+    fn example_div(unsigned: usize, nonzero_unsigned: NonZeroUsize) -> usize {
+        unsigned / nonzero_unsigned
+    }
+
+    fn example_rem(unsigned: usize, nonzero_unsigned: NonZeroUsize) -> usize {
+        unsigned % nonzero_unsigned
+    }
+
+    let (unsigned, nonzero_unsigned) = (0, NonZeroUsize::new(1).unwrap());
+    example_div(unsigned, nonzero_unsigned);
+    example_rem(unsigned, nonzero_unsigned);
+}
+
+pub fn issue_11393() {
+    fn example_div(x: Wrapping<i32>, maybe_zero: Wrapping<i32>) -> Wrapping<i32> {
+        x / maybe_zero
+    }
+
+    fn example_rem(x: Wrapping<i32>, maybe_zero: Wrapping<i32>) -> Wrapping<i32> {
+        x % maybe_zero
+    }
+
+    let [x, maybe_zero] = [1, 0].map(Wrapping);
+    example_div(x, maybe_zero);
+    example_rem(x, maybe_zero);
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/arithmetic_side_effects.stderr b/src/tools/clippy/tests/ui/arithmetic_side_effects.stderr
index e9a626643ff..7f490748160 100644
--- a/src/tools/clippy/tests/ui/arithmetic_side_effects.stderr
+++ b/src/tools/clippy/tests/ui/arithmetic_side_effects.stderr
@@ -702,5 +702,17 @@ error: arithmetic operation that can potentially result in unexpected side-effec
 LL |     10 / a
    |     ^^^^^^
 
-error: aborting due to 117 previous errors
+error: arithmetic operation that can potentially result in unexpected side-effects
+  --> $DIR/arithmetic_side_effects.rs:512:9
+   |
+LL |         x / maybe_zero
+   |         ^^^^^^^^^^^^^^
+
+error: arithmetic operation that can potentially result in unexpected side-effects
+  --> $DIR/arithmetic_side_effects.rs:516:9
+   |
+LL |         x % maybe_zero
+   |         ^^^^^^^^^^^^^^
+
+error: aborting due to 119 previous errors
 
diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version
index 919bc135fdf..b40e7f83f4f 100644
--- a/src/tools/miri/rust-version
+++ b/src/tools/miri/rust-version
@@ -1 +1 @@
-35e416303e6591a71ef6a91e006c602d2def3968
+a989e25f1b87949a886eab3da10324d14189fe95
diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs
index 03dd9037808..816055cc4fe 100644
--- a/src/tools/miri/src/lib.rs
+++ b/src/tools/miri/src/lib.rs
@@ -8,7 +8,6 @@
 #![feature(yeet_expr)]
 #![feature(nonzero_ops)]
 #![feature(round_ties_even)]
-#![feature(os_str_bytes)]
 #![feature(lint_reasons)]
 #![feature(trait_upcasting)]
 // Configure clippy and other lints
diff --git a/src/tools/miri/src/shims/os_str.rs b/src/tools/miri/src/shims/os_str.rs
index f08f0aad5e7..a94b1ddcd95 100644
--- a/src/tools/miri/src/shims/os_str.rs
+++ b/src/tools/miri/src/shims/os_str.rs
@@ -24,7 +24,7 @@ pub fn bytes_to_os_str<'tcx>(bytes: &[u8]) -> InterpResult<'tcx, &OsStr> {
 }
 #[cfg(not(unix))]
 pub fn bytes_to_os_str<'tcx>(bytes: &[u8]) -> InterpResult<'tcx, &OsStr> {
-    // We cannot use `from_os_str_bytes_unchecked` here since we can't trust `bytes`.
+    // We cannot use `from_encoded_bytes_unchecked` here since we can't trust `bytes`.
     let s = std::str::from_utf8(bytes)
         .map_err(|_| err_unsup_format!("{:?} is not a valid utf-8 string", bytes))?;
     Ok(OsStr::new(s))
@@ -83,7 +83,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         ptr: Pointer<Option<Provenance>>,
         size: u64,
     ) -> InterpResult<'tcx, (bool, u64)> {
-        let bytes = os_str.as_os_str_bytes();
+        let bytes = os_str.as_encoded_bytes();
         self.eval_context_mut().write_c_str(bytes, ptr, size)
     }
 
diff --git a/src/tools/miri/src/shims/unix/fs.rs b/src/tools/miri/src/shims/unix/fs.rs
index beaef22075b..dd2da3d22f2 100644
--- a/src/tools/miri/src/shims/unix/fs.rs
+++ b/src/tools/miri/src/shims/unix/fs.rs
@@ -1344,7 +1344,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
 
                 let mut name = dir_entry.file_name(); // not a Path as there are no separators!
                 name.push("\0"); // Add a NUL terminator
-                let name_bytes = name.as_os_str_bytes();
+                let name_bytes = name.as_encoded_bytes();
                 let name_len = u64::try_from(name_bytes.len()).unwrap();
 
                 let dirent64_layout = this.libc_ty_layout("dirent64");
@@ -1698,7 +1698,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                     Cow::Borrowed(resolved.as_ref()),
                     crate::shims::os_str::PathConversion::HostToTarget,
                 );
-                let mut path_bytes = resolved.as_os_str_bytes();
+                let mut path_bytes = resolved.as_encoded_bytes();
                 let bufsize: usize = bufsize.try_into().unwrap();
                 if path_bytes.len() > bufsize {
                     path_bytes = &path_bytes[..bufsize]
diff --git a/src/tools/miri/tests/utils/fs.rs b/src/tools/miri/tests/utils/fs.rs
index 47904926b48..0242a228068 100644
--- a/src/tools/miri/tests/utils/fs.rs
+++ b/src/tools/miri/tests/utils/fs.rs
@@ -6,7 +6,7 @@ use super::miri_extern;
 pub fn host_to_target_path(path: OsString) -> PathBuf {
     use std::ffi::{CStr, CString};
 
-    // Once into_os_str_bytes is stable we can use it here.
+    // Once into_encoded_bytes is stable we can use it here.
     // (Unstable features would need feature flags in each test...)
     let path = CString::new(path.into_string().unwrap()).unwrap();
     let mut out = Vec::with_capacity(1024);
diff --git a/tests/codegen/lib-optimizations/iter-sum.rs b/tests/codegen/lib-optimizations/iter-sum.rs
new file mode 100644
index 00000000000..ff7ca6ef6c1
--- /dev/null
+++ b/tests/codegen/lib-optimizations/iter-sum.rs
@@ -0,0 +1,15 @@
+// ignore-debug: the debug assertions get in the way
+// compile-flags: -O
+// only-x86_64 (vectorization varies between architectures)
+#![crate_type = "lib"]
+
+
+// Ensure that slice + take + sum gets vectorized.
+// Currently this relies on the slice::Iter::try_fold implementation
+// CHECK-LABEL: @slice_take_sum
+#[no_mangle]
+pub fn slice_take_sum(s: &[u64], l: usize) -> u64 {
+    // CHECK: vector.body:
+    // CHECK: ret
+    s.iter().take(l).sum()
+}
diff --git a/tests/codegen/slice-as_chunks.rs b/tests/codegen/slice-as_chunks.rs
index 48e3f73fc86..efac9f3d68d 100644
--- a/tests/codegen/slice-as_chunks.rs
+++ b/tests/codegen/slice-as_chunks.rs
@@ -22,9 +22,9 @@ pub fn chunks4(x: &[u8]) -> &[[u8; 4]] {
 // CHECK-LABEL: @chunks4_with_remainder
 #[no_mangle]
 pub fn chunks4_with_remainder(x: &[u8]) -> (&[[u8; 4]], &[u8]) {
-    // CHECK: and i64 %x.1, -4
-    // CHECK: and i64 %x.1, 3
-    // CHECK: lshr exact
+    // CHECK-DAG: and i64 %x.1, -4
+    // CHECK-DAG: and i64 %x.1, 3
+    // CHECK-DAG: lshr
     // CHECK-NOT: mul
     // CHECK-NOT: udiv
     // CHECK-NOT: urem
diff --git a/tests/codegen/slice-iter-nonnull.rs b/tests/codegen/slice-iter-nonnull.rs
index f7d164bc856..8749226d401 100644
--- a/tests/codegen/slice-iter-nonnull.rs
+++ b/tests/codegen/slice-iter-nonnull.rs
@@ -100,13 +100,13 @@ pub fn slice_iter_is_empty(it: &std::slice::Iter<'_, u32>) -> bool {
 // CHECK-LABEL: @slice_iter_len
 #[no_mangle]
 pub fn slice_iter_len(it: &std::slice::Iter<'_, u32>) -> usize {
-    // CHECK: %[[START:.+]] = load ptr, ptr %it,
-    // CHECK-SAME: !nonnull
-    // CHECK-SAME: !noundef
     // CHECK: %[[ENDP:.+]] = getelementptr{{.+}}ptr %it,{{.+}} 1
     // CHECK: %[[END:.+]] = load ptr, ptr %[[ENDP]]
     // CHECK-SAME: !nonnull
     // CHECK-SAME: !noundef
+    // CHECK: %[[START:.+]] = load ptr, ptr %it,
+    // CHECK-SAME: !nonnull
+    // CHECK-SAME: !noundef
 
     // CHECK: ptrtoint
     // CHECK: ptrtoint
diff --git a/tests/mir-opt/bool_compare.opt1.InstSimplify.diff b/tests/mir-opt/bool_compare.opt1.InstSimplify.diff
index 8d0011d5067..657c11516a1 100644
--- a/tests/mir-opt/bool_compare.opt1.InstSimplify.diff
+++ b/tests/mir-opt/bool_compare.opt1.InstSimplify.diff
@@ -13,16 +13,17 @@
           _3 = _1;
 -         _2 = Ne(move _3, const true);
 +         _2 = Not(move _3);
-          StorageDead(_3);
           switchInt(move _2) -> [0: bb2, otherwise: bb1];
       }
   
       bb1: {
+          StorageDead(_3);
           _0 = const 0_u32;
           goto -> bb3;
       }
   
       bb2: {
+          StorageDead(_3);
           _0 = const 1_u32;
           goto -> bb3;
       }
diff --git a/tests/mir-opt/bool_compare.opt2.InstSimplify.diff b/tests/mir-opt/bool_compare.opt2.InstSimplify.diff
index 35f1068709b..bc8be62bd49 100644
--- a/tests/mir-opt/bool_compare.opt2.InstSimplify.diff
+++ b/tests/mir-opt/bool_compare.opt2.InstSimplify.diff
@@ -13,16 +13,17 @@
           _3 = _1;
 -         _2 = Ne(const true, move _3);
 +         _2 = Not(move _3);
-          StorageDead(_3);
           switchInt(move _2) -> [0: bb2, otherwise: bb1];
       }
   
       bb1: {
+          StorageDead(_3);
           _0 = const 0_u32;
           goto -> bb3;
       }
   
       bb2: {
+          StorageDead(_3);
           _0 = const 1_u32;
           goto -> bb3;
       }
diff --git a/tests/mir-opt/bool_compare.opt3.InstSimplify.diff b/tests/mir-opt/bool_compare.opt3.InstSimplify.diff
index ab15c30ca11..034d5e44013 100644
--- a/tests/mir-opt/bool_compare.opt3.InstSimplify.diff
+++ b/tests/mir-opt/bool_compare.opt3.InstSimplify.diff
@@ -13,16 +13,17 @@
           _3 = _1;
 -         _2 = Eq(move _3, const false);
 +         _2 = Not(move _3);
-          StorageDead(_3);
           switchInt(move _2) -> [0: bb2, otherwise: bb1];
       }
   
       bb1: {
+          StorageDead(_3);
           _0 = const 0_u32;
           goto -> bb3;
       }
   
       bb2: {
+          StorageDead(_3);
           _0 = const 1_u32;
           goto -> bb3;
       }
diff --git a/tests/mir-opt/bool_compare.opt4.InstSimplify.diff b/tests/mir-opt/bool_compare.opt4.InstSimplify.diff
index 40fd1cfe112..d3096da6c5a 100644
--- a/tests/mir-opt/bool_compare.opt4.InstSimplify.diff
+++ b/tests/mir-opt/bool_compare.opt4.InstSimplify.diff
@@ -13,16 +13,17 @@
           _3 = _1;
 -         _2 = Eq(const false, move _3);
 +         _2 = Not(move _3);
-          StorageDead(_3);
           switchInt(move _2) -> [0: bb2, otherwise: bb1];
       }
   
       bb1: {
+          StorageDead(_3);
           _0 = const 0_u32;
           goto -> bb3;
       }
   
       bb2: {
+          StorageDead(_3);
           _0 = const 1_u32;
           goto -> bb3;
       }
diff --git a/tests/mir-opt/building/logical_or_in_conditional.rs b/tests/mir-opt/building/logical_or_in_conditional.rs
new file mode 100644
index 00000000000..ae159f7e122
--- /dev/null
+++ b/tests/mir-opt/building/logical_or_in_conditional.rs
@@ -0,0 +1,39 @@
+// compile-flags: -Z validate-mir
+#![feature(let_chains)]
+struct Droppy(u8);
+impl Drop for Droppy {
+    fn drop(&mut self) {
+        println!("drop {}", self.0);
+    }
+}
+
+enum E {
+    A(u8),
+    B,
+}
+
+impl E {
+    fn f() -> Self {
+        Self::A(1)
+    }
+}
+
+fn always_true() -> bool {
+    true
+}
+
+// EMIT_MIR logical_or_in_conditional.test_or.built.after.mir
+fn test_or() {
+    if Droppy(0).0 > 0 || Droppy(1).0 > 1 {}
+}
+
+// EMIT_MIR logical_or_in_conditional.test_complex.built.after.mir
+fn test_complex() {
+    if let E::A(_) = E::f() && ((always_true() && Droppy(0).0 > 0) || Droppy(1).0 > 1) {}
+
+    if !always_true() && let E::B = E::f() {}
+}
+
+fn main() {
+    test_or();
+}
diff --git a/tests/mir-opt/building/logical_or_in_conditional.test_complex.built.after.mir b/tests/mir-opt/building/logical_or_in_conditional.test_complex.built.after.mir
new file mode 100644
index 00000000000..096aaec4a38
--- /dev/null
+++ b/tests/mir-opt/building/logical_or_in_conditional.test_complex.built.after.mir
@@ -0,0 +1,186 @@
+// MIR for `test_complex` after built
+
+fn test_complex() -> () {
+    let mut _0: ();
+    let _1: ();
+    let mut _2: E;
+    let mut _3: isize;
+    let mut _4: bool;
+    let mut _5: bool;
+    let mut _6: u8;
+    let mut _7: Droppy;
+    let mut _8: bool;
+    let mut _9: u8;
+    let mut _10: Droppy;
+    let mut _11: bool;
+    let mut _12: E;
+    let mut _13: isize;
+
+    bb0: {
+        StorageLive(_1);
+        StorageLive(_2);
+        _2 = E::f() -> [return: bb1, unwind: bb31];
+    }
+
+    bb1: {
+        FakeRead(ForMatchedPlace(None), _2);
+        _3 = discriminant(_2);
+        switchInt(move _3) -> [0: bb2, otherwise: bb3];
+    }
+
+    bb2: {
+        falseEdge -> [real: bb4, imaginary: bb3];
+    }
+
+    bb3: {
+        goto -> bb19;
+    }
+
+    bb4: {
+        StorageLive(_4);
+        _4 = always_true() -> [return: bb5, unwind: bb31];
+    }
+
+    bb5: {
+        switchInt(move _4) -> [0: bb7, otherwise: bb6];
+    }
+
+    bb6: {
+        StorageLive(_5);
+        StorageLive(_6);
+        StorageLive(_7);
+        _7 = Droppy(const 0_u8);
+        _6 = (_7.0: u8);
+        _5 = Gt(move _6, const 0_u8);
+        switchInt(move _5) -> [0: bb9, otherwise: bb8];
+    }
+
+    bb7: {
+        goto -> bb13;
+    }
+
+    bb8: {
+        drop(_7) -> [return: bb10, unwind: bb31];
+    }
+
+    bb9: {
+        goto -> bb11;
+    }
+
+    bb10: {
+        StorageDead(_7);
+        StorageDead(_6);
+        goto -> bb16;
+    }
+
+    bb11: {
+        drop(_7) -> [return: bb12, unwind: bb31];
+    }
+
+    bb12: {
+        StorageDead(_7);
+        StorageDead(_6);
+        goto -> bb13;
+    }
+
+    bb13: {
+        StorageLive(_8);
+        StorageLive(_9);
+        StorageLive(_10);
+        _10 = Droppy(const 1_u8);
+        _9 = (_10.0: u8);
+        _8 = Gt(move _9, const 1_u8);
+        switchInt(move _8) -> [0: bb15, otherwise: bb14];
+    }
+
+    bb14: {
+        drop(_10) -> [return: bb16, unwind: bb31];
+    }
+
+    bb15: {
+        goto -> bb17;
+    }
+
+    bb16: {
+        StorageDead(_10);
+        StorageDead(_9);
+        _1 = const ();
+        goto -> bb20;
+    }
+
+    bb17: {
+        drop(_10) -> [return: bb18, unwind: bb31];
+    }
+
+    bb18: {
+        StorageDead(_10);
+        StorageDead(_9);
+        goto -> bb19;
+    }
+
+    bb19: {
+        _1 = const ();
+        goto -> bb20;
+    }
+
+    bb20: {
+        StorageDead(_8);
+        StorageDead(_5);
+        StorageDead(_4);
+        StorageDead(_2);
+        StorageDead(_1);
+        StorageLive(_11);
+        _11 = always_true() -> [return: bb21, unwind: bb31];
+    }
+
+    bb21: {
+        switchInt(move _11) -> [0: bb23, otherwise: bb22];
+    }
+
+    bb22: {
+        goto -> bb29;
+    }
+
+    bb23: {
+        goto -> bb24;
+    }
+
+    bb24: {
+        StorageLive(_12);
+        _12 = E::f() -> [return: bb25, unwind: bb31];
+    }
+
+    bb25: {
+        FakeRead(ForMatchedPlace(None), _12);
+        _13 = discriminant(_12);
+        switchInt(move _13) -> [1: bb27, otherwise: bb26];
+    }
+
+    bb26: {
+        goto -> bb29;
+    }
+
+    bb27: {
+        falseEdge -> [real: bb28, imaginary: bb26];
+    }
+
+    bb28: {
+        _0 = const ();
+        goto -> bb30;
+    }
+
+    bb29: {
+        _0 = const ();
+        goto -> bb30;
+    }
+
+    bb30: {
+        StorageDead(_11);
+        StorageDead(_12);
+        return;
+    }
+
+    bb31 (cleanup): {
+        resume;
+    }
+}
diff --git a/tests/mir-opt/building/logical_or_in_conditional.test_or.built.after.mir b/tests/mir-opt/building/logical_or_in_conditional.test_or.built.after.mir
new file mode 100644
index 00000000000..b84c17c2188
--- /dev/null
+++ b/tests/mir-opt/building/logical_or_in_conditional.test_or.built.after.mir
@@ -0,0 +1,87 @@
+// MIR for `test_or` after built
+
+fn test_or() -> () {
+    let mut _0: ();
+    let mut _1: bool;
+    let mut _2: u8;
+    let mut _3: Droppy;
+    let mut _4: bool;
+    let mut _5: u8;
+    let mut _6: Droppy;
+
+    bb0: {
+        StorageLive(_1);
+        StorageLive(_2);
+        StorageLive(_3);
+        _3 = Droppy(const 0_u8);
+        _2 = (_3.0: u8);
+        _1 = Gt(move _2, const 0_u8);
+        switchInt(move _1) -> [0: bb2, otherwise: bb1];
+    }
+
+    bb1: {
+        drop(_3) -> [return: bb3, unwind: bb12];
+    }
+
+    bb2: {
+        goto -> bb4;
+    }
+
+    bb3: {
+        StorageDead(_3);
+        StorageDead(_2);
+        goto -> bb8;
+    }
+
+    bb4: {
+        drop(_3) -> [return: bb5, unwind: bb12];
+    }
+
+    bb5: {
+        StorageDead(_3);
+        StorageDead(_2);
+        StorageLive(_4);
+        StorageLive(_5);
+        StorageLive(_6);
+        _6 = Droppy(const 1_u8);
+        _5 = (_6.0: u8);
+        _4 = Gt(move _5, const 1_u8);
+        switchInt(move _4) -> [0: bb7, otherwise: bb6];
+    }
+
+    bb6: {
+        drop(_6) -> [return: bb8, unwind: bb12];
+    }
+
+    bb7: {
+        goto -> bb9;
+    }
+
+    bb8: {
+        StorageDead(_6);
+        StorageDead(_5);
+        _0 = const ();
+        goto -> bb11;
+    }
+
+    bb9: {
+        drop(_6) -> [return: bb10, unwind: bb12];
+    }
+
+    bb10: {
+        StorageDead(_6);
+        StorageDead(_5);
+        _0 = const ();
+        goto -> bb11;
+    }
+
+    bb11: {
+        StorageDead(_4);
+        StorageDead(_1);
+        return;
+    }
+
+    bb12 (cleanup): {
+        resume;
+    }
+}
diff --git a/tests/mir-opt/const_goto_storage.match_nested_if.ConstGoto.diff b/tests/mir-opt/const_goto_storage.match_nested_if.ConstGoto.diff
index d1dbc7089a1..1768298d521 100644
--- a/tests/mir-opt/const_goto_storage.match_nested_if.ConstGoto.diff
+++ b/tests/mir-opt/const_goto_storage.match_nested_if.ConstGoto.diff
@@ -43,31 +43,33 @@
       }
   
       bb3: {
--         StorageDead(_6);
 -         switchInt(move _5) -> [0: bb5, otherwise: bb4];
 -     }
 - 
 -     bb4: {
+-         StorageDead(_6);
 -         _4 = const true;
 -         goto -> bb6;
 -     }
 - 
 -     bb5: {
+-         StorageDead(_6);
 -         _4 = const false;
 -         goto -> bb6;
 -     }
 - 
 -     bb6: {
--         StorageDead(_5);
 -         switchInt(move _4) -> [0: bb8, otherwise: bb7];
 -     }
 - 
 -     bb7: {
+-         StorageDead(_5);
 -         _3 = const true;
 -         goto -> bb9;
 -     }
 - 
 -     bb8: {
+-         StorageDead(_5);
 -         _3 = const false;
 -         goto -> bb9;
 -     }
diff --git a/tests/mir-opt/dataflow-const-prop/if.main.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/if.main.DataflowConstProp.diff
index 08b599f9f5d..355f28b03db 100644
--- a/tests/mir-opt/dataflow-const-prop/if.main.DataflowConstProp.diff
+++ b/tests/mir-opt/dataflow-const-prop/if.main.DataflowConstProp.diff
@@ -39,19 +39,20 @@
           StorageLive(_4);
 -         _4 = _1;
 -         _3 = Eq(move _4, const 1_i32);
+-         switchInt(move _3) -> [0: bb2, otherwise: bb1];
 +         _4 = const 1_i32;
 +         _3 = const true;
-          StorageDead(_4);
--         switchInt(move _3) -> [0: bb2, otherwise: bb1];
 +         switchInt(const true) -> [0: bb2, otherwise: bb1];
       }
   
       bb1: {
+          StorageDead(_4);
           _2 = const 2_i32;
           goto -> bb3;
       }
   
       bb2: {
+          StorageDead(_4);
           _2 = const 3_i32;
           goto -> bb3;
       }
@@ -70,20 +71,21 @@
           StorageLive(_9);
 -         _9 = _1;
 -         _8 = Eq(move _9, const 1_i32);
+-         switchInt(move _8) -> [0: bb5, otherwise: bb4];
 +         _9 = const 1_i32;
 +         _8 = const true;
-          StorageDead(_9);
--         switchInt(move _8) -> [0: bb5, otherwise: bb4];
 +         switchInt(const true) -> [0: bb5, otherwise: bb4];
       }
   
       bb4: {
+          StorageDead(_9);
 -         _7 = _1;
 +         _7 = const 1_i32;
           goto -> bb6;
       }
   
       bb5: {
+          StorageDead(_9);
           StorageLive(_10);
           _10 = _1;
           _7 = Add(move _10, const 1_i32);
diff --git a/tests/mir-opt/equal_true.opt.InstSimplify.diff b/tests/mir-opt/equal_true.opt.InstSimplify.diff
index 7b38862e4d5..88a51000c93 100644
--- a/tests/mir-opt/equal_true.opt.InstSimplify.diff
+++ b/tests/mir-opt/equal_true.opt.InstSimplify.diff
@@ -13,16 +13,17 @@
           _3 = _1;
 -         _2 = Eq(move _3, const true);
 +         _2 = move _3;
-          StorageDead(_3);
           switchInt(move _2) -> [0: bb2, otherwise: bb1];
       }
   
       bb1: {
+          StorageDead(_3);
           _0 = const 0_i32;
           goto -> bb3;
       }
   
       bb2: {
+          StorageDead(_3);
           _0 = const 1_i32;
           goto -> bb3;
       }
diff --git a/tests/mir-opt/if_condition_int.dont_opt_floats.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.dont_opt_floats.SimplifyComparisonIntegral.diff
index 8483b89f814..15319586062 100644
--- a/tests/mir-opt/if_condition_int.dont_opt_floats.SimplifyComparisonIntegral.diff
+++ b/tests/mir-opt/if_condition_int.dont_opt_floats.SimplifyComparisonIntegral.diff
@@ -12,16 +12,17 @@
           StorageLive(_3);
           _3 = _1;
           _2 = Eq(move _3, const -42f32);
-          StorageDead(_3);
           switchInt(move _2) -> [0: bb2, otherwise: bb1];
       }
   
       bb1: {
+          StorageDead(_3);
           _0 = const 0_i32;
           goto -> bb3;
       }
   
       bb2: {
+          StorageDead(_3);
           _0 = const 1_i32;
           goto -> bb3;
       }
diff --git a/tests/mir-opt/if_condition_int.opt_char.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.opt_char.SimplifyComparisonIntegral.diff
index 837841b009b..fedbd6cdd24 100644
--- a/tests/mir-opt/if_condition_int.opt_char.SimplifyComparisonIntegral.diff
+++ b/tests/mir-opt/if_condition_int.opt_char.SimplifyComparisonIntegral.diff
@@ -12,21 +12,19 @@
           StorageLive(_3);
           _3 = _1;
 -         _2 = Eq(move _3, const 'x');
--         StorageDead(_3);
 -         switchInt(move _2) -> [0: bb2, otherwise: bb1];
 +         nop;
-+         nop;
 +         switchInt(move _3) -> [120: bb1, otherwise: bb2];
       }
   
       bb1: {
-+         StorageDead(_3);
+          StorageDead(_3);
           _0 = const 0_u32;
           goto -> bb3;
       }
   
       bb2: {
-+         StorageDead(_3);
+          StorageDead(_3);
           _0 = const 1_u32;
           goto -> bb3;
       }
diff --git a/tests/mir-opt/if_condition_int.opt_i8.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.opt_i8.SimplifyComparisonIntegral.diff
index 3cbf912996c..9c38d8fe065 100644
--- a/tests/mir-opt/if_condition_int.opt_i8.SimplifyComparisonIntegral.diff
+++ b/tests/mir-opt/if_condition_int.opt_i8.SimplifyComparisonIntegral.diff
@@ -12,21 +12,19 @@
           StorageLive(_3);
           _3 = _1;
 -         _2 = Eq(move _3, const 42_i8);
--         StorageDead(_3);
 -         switchInt(move _2) -> [0: bb2, otherwise: bb1];
 +         nop;
-+         nop;
 +         switchInt(move _3) -> [42: bb1, otherwise: bb2];
       }
   
       bb1: {
-+         StorageDead(_3);
+          StorageDead(_3);
           _0 = const 0_u32;
           goto -> bb3;
       }
   
       bb2: {
-+         StorageDead(_3);
+          StorageDead(_3);
           _0 = const 1_u32;
           goto -> bb3;
       }
diff --git a/tests/mir-opt/if_condition_int.opt_multiple_ifs.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.opt_multiple_ifs.SimplifyComparisonIntegral.diff
index 8d6f3b2249e..8c85ce78565 100644
--- a/tests/mir-opt/if_condition_int.opt_multiple_ifs.SimplifyComparisonIntegral.diff
+++ b/tests/mir-opt/if_condition_int.opt_multiple_ifs.SimplifyComparisonIntegral.diff
@@ -14,40 +14,36 @@
           StorageLive(_3);
           _3 = _1;
 -         _2 = Eq(move _3, const 42_u32);
--         StorageDead(_3);
 -         switchInt(move _2) -> [0: bb2, otherwise: bb1];
 +         nop;
-+         nop;
 +         switchInt(move _3) -> [42: bb1, otherwise: bb2];
       }
   
       bb1: {
-+         StorageDead(_3);
+          StorageDead(_3);
           _0 = const 0_u32;
           goto -> bb6;
       }
   
       bb2: {
-+         StorageDead(_3);
+          StorageDead(_3);
           StorageLive(_4);
           StorageLive(_5);
           _5 = _1;
 -         _4 = Ne(move _5, const 21_u32);
--         StorageDead(_5);
 -         switchInt(move _4) -> [0: bb4, otherwise: bb3];
 +         nop;
-+         nop;
 +         switchInt(move _5) -> [21: bb4, otherwise: bb3];
       }
   
       bb3: {
-+         StorageDead(_5);
+          StorageDead(_5);
           _0 = const 1_u32;
           goto -> bb5;
       }
   
       bb4: {
-+         StorageDead(_5);
+          StorageDead(_5);
           _0 = const 2_u32;
           goto -> bb5;
       }
diff --git a/tests/mir-opt/if_condition_int.opt_negative.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.opt_negative.SimplifyComparisonIntegral.diff
index e2566b13c59..876ed61e9fa 100644
--- a/tests/mir-opt/if_condition_int.opt_negative.SimplifyComparisonIntegral.diff
+++ b/tests/mir-opt/if_condition_int.opt_negative.SimplifyComparisonIntegral.diff
@@ -12,21 +12,19 @@
           StorageLive(_3);
           _3 = _1;
 -         _2 = Eq(move _3, const -42_i32);
--         StorageDead(_3);
 -         switchInt(move _2) -> [0: bb2, otherwise: bb1];
 +         nop;
-+         nop;
 +         switchInt(move _3) -> [4294967254: bb1, otherwise: bb2];
       }
   
       bb1: {
-+         StorageDead(_3);
+          StorageDead(_3);
           _0 = const 0_u32;
           goto -> bb3;
       }
   
       bb2: {
-+         StorageDead(_3);
+          StorageDead(_3);
           _0 = const 1_u32;
           goto -> bb3;
       }
diff --git a/tests/mir-opt/if_condition_int.opt_u32.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.opt_u32.SimplifyComparisonIntegral.diff
index dc8da5b44b2..ed3eb47dd3d 100644
--- a/tests/mir-opt/if_condition_int.opt_u32.SimplifyComparisonIntegral.diff
+++ b/tests/mir-opt/if_condition_int.opt_u32.SimplifyComparisonIntegral.diff
@@ -12,21 +12,19 @@
           StorageLive(_3);
           _3 = _1;
 -         _2 = Eq(move _3, const 42_u32);
--         StorageDead(_3);
 -         switchInt(move _2) -> [0: bb2, otherwise: bb1];
 +         nop;
-+         nop;
 +         switchInt(move _3) -> [42: bb1, otherwise: bb2];
       }
   
       bb1: {
-+         StorageDead(_3);
+          StorageDead(_3);
           _0 = const 0_u32;
           goto -> bb3;
       }
   
       bb2: {
-+         StorageDead(_3);
+          StorageDead(_3);
           _0 = const 1_u32;
           goto -> bb3;
       }
diff --git a/tests/mir-opt/inline/inline_diverging.g.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_diverging.g.Inline.panic-abort.diff
index 9db0d385da7..d675695eb10 100644
--- a/tests/mir-opt/inline/inline_diverging.g.Inline.panic-abort.diff
+++ b/tests/mir-opt/inline/inline_diverging.g.Inline.panic-abort.diff
@@ -18,11 +18,11 @@
           StorageLive(_3);
           _3 = _1;
           _2 = Gt(move _3, const 0_i32);
-          StorageDead(_3);
           switchInt(move _2) -> [0: bb2, otherwise: bb1];
       }
   
       bb1: {
+          StorageDead(_3);
           StorageLive(_4);
           _4 = _1;
           _0 = move _4 as u32 (IntToInt);
@@ -32,6 +32,7 @@
       }
   
       bb2: {
+          StorageDead(_3);
           StorageLive(_6);
 -         _6 = panic() -> unwind unreachable;
 +         StorageLive(_7);
diff --git a/tests/mir-opt/inline/inline_diverging.g.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_diverging.g.Inline.panic-unwind.diff
index 5663b462400..1142616115f 100644
--- a/tests/mir-opt/inline/inline_diverging.g.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/inline_diverging.g.Inline.panic-unwind.diff
@@ -18,11 +18,11 @@
           StorageLive(_3);
           _3 = _1;
           _2 = Gt(move _3, const 0_i32);
-          StorageDead(_3);
           switchInt(move _2) -> [0: bb2, otherwise: bb1];
       }
   
       bb1: {
+          StorageDead(_3);
           StorageLive(_4);
           _4 = _1;
           _0 = move _4 as u32 (IntToInt);
@@ -32,6 +32,7 @@
       }
   
       bb2: {
+          StorageDead(_3);
           StorageLive(_6);
 -         _6 = panic() -> unwind continue;
 +         StorageLive(_7);
diff --git a/tests/mir-opt/issue_99325.main.built.after.mir b/tests/mir-opt/issue_99325.main.built.after.mir
index aef89c7f9f7..f12179a8905 100644
--- a/tests/mir-opt/issue_99325.main.built.after.mir
+++ b/tests/mir-opt/issue_99325.main.built.after.mir
@@ -16,51 +16,49 @@ fn main() -> () {
     let _8: &&[u8];
     let _9: &&[u8; 4];
     let mut _10: bool;
-    let mut _11: bool;
-    let mut _12: &&[u8];
-    let mut _13: &&[u8; 4];
-    let mut _14: !;
-    let _16: !;
-    let mut _17: core::panicking::AssertKind;
-    let mut _18: &&[u8];
-    let _19: &&[u8];
-    let mut _20: &&[u8; 4];
-    let _21: &&[u8; 4];
-    let mut _22: std::option::Option<std::fmt::Arguments<'_>>;
-    let _23: ();
-    let mut _24: (&&[u8], &&[u8; 4]);
-    let mut _25: &&[u8];
-    let _26: &[u8];
-    let mut _27: &&[u8; 4];
-    let _28: &[u8; 4];
-    let _29: &&[u8];
-    let _30: &&[u8; 4];
-    let mut _31: bool;
-    let mut _32: bool;
-    let mut _33: &&[u8];
-    let mut _34: &&[u8; 4];
-    let mut _35: !;
-    let _37: !;
-    let mut _38: core::panicking::AssertKind;
-    let mut _39: &&[u8];
-    let _40: &&[u8];
-    let mut _41: &&[u8; 4];
-    let _42: &&[u8; 4];
-    let mut _43: std::option::Option<std::fmt::Arguments<'_>>;
+    let mut _11: &&[u8];
+    let mut _12: &&[u8; 4];
+    let mut _13: !;
+    let _15: !;
+    let mut _16: core::panicking::AssertKind;
+    let mut _17: &&[u8];
+    let _18: &&[u8];
+    let mut _19: &&[u8; 4];
+    let _20: &&[u8; 4];
+    let mut _21: std::option::Option<std::fmt::Arguments<'_>>;
+    let _22: ();
+    let mut _23: (&&[u8], &&[u8; 4]);
+    let mut _24: &&[u8];
+    let _25: &[u8];
+    let mut _26: &&[u8; 4];
+    let _27: &[u8; 4];
+    let _28: &&[u8];
+    let _29: &&[u8; 4];
+    let mut _30: bool;
+    let mut _31: &&[u8];
+    let mut _32: &&[u8; 4];
+    let mut _33: !;
+    let _35: !;
+    let mut _36: core::panicking::AssertKind;
+    let mut _37: &&[u8];
+    let _38: &&[u8];
+    let mut _39: &&[u8; 4];
+    let _40: &&[u8; 4];
+    let mut _41: std::option::Option<std::fmt::Arguments<'_>>;
     scope 1 {
         debug left_val => _8;
         debug right_val => _9;
-        let _15: core::panicking::AssertKind;
+        let _14: core::panicking::AssertKind;
         scope 2 {
-            debug kind => _15;
+            debug kind => _14;
         }
     }
     scope 3 {
-        debug left_val => _29;
-        debug right_val => _30;
-        let _36: core::panicking::AssertKind;
+        debug left_val => _28;
+        debug right_val => _29;
+        let _34: core::panicking::AssertKind;
         scope 4 {
-            debug kind => _36;
+            debug kind => _34;
         }
     }
 
@@ -69,7 +67,7 @@ fn main() -> () {
         StorageLive(_2);
         StorageLive(_3);
         StorageLive(_4);
-        _4 = function_with_bytes::<&*b"AAAA">() -> [return: bb1, unwind: bb19];
+        _4 = function_with_bytes::<&*b"AAAA">() -> [return: bb1, unwind: bb21];
     }
 
     bb1: {
@@ -90,179 +88,185 @@ fn main() -> () {
         _9 = (_2.1: &&[u8; 4]);
         StorageLive(_10);
         StorageLive(_11);
+        _11 = &(*_8);
         StorageLive(_12);
-        _12 = &(*_8);
-        StorageLive(_13);
-        _13 = &(*_9);
-        _11 = <&[u8] as PartialEq<&[u8; 4]>>::eq(move _12, move _13) -> [return: bb2, unwind: bb19];
+        _12 = &(*_9);
+        _10 = <&[u8] as PartialEq<&[u8; 4]>>::eq(move _11, move _12) -> [return: bb2, unwind: bb21];
     }
 
     bb2: {
-        StorageDead(_13);
-        StorageDead(_12);
-        _10 = Not(move _11);
-        StorageDead(_11);
         switchInt(move _10) -> [0: bb4, otherwise: bb3];
     }
 
     bb3: {
+        StorageDead(_12);
+        StorageDead(_11);
+        goto -> bb8;
+    }
+
+    bb4: {
+        goto -> bb5;
+    }
+
+    bb5: {
+        StorageDead(_12);
+        StorageDead(_11);
+        StorageLive(_14);
+        _14 = core::panicking::AssertKind::Eq;
+        FakeRead(ForLet(None), _14);
         StorageLive(_15);
-        _15 = core::panicking::AssertKind::Eq;
-        FakeRead(ForLet(None), _15);
         StorageLive(_16);
+        _16 = move _14;
         StorageLive(_17);
-        _17 = move _15;
         StorageLive(_18);
+        _18 = &(*_8);
+        _17 = &(*_18);
         StorageLive(_19);
-        _19 = &(*_8);
-        _18 = &(*_19);
         StorageLive(_20);
+        _20 = &(*_9);
+        _19 = &(*_20);
         StorageLive(_21);
-        _21 = &(*_9);
-        _20 = &(*_21);
-        StorageLive(_22);
-        _22 = Option::<Arguments<'_>>::None;
-        _16 = core::panicking::assert_failed::<&[u8], &[u8; 4]>(move _17, move _18, move _20, move _22) -> bb19;
-    }
-
-    bb4: {
-        goto -> bb7;
+        _21 = Option::<Arguments<'_>>::None;
+        _15 = core::panicking::assert_failed::<&[u8], &[u8; 4]>(move _16, move _17, move _19, move _21) -> bb21;
     }
 
-    bb5: {
-        StorageDead(_22);
-        StorageDead(_20);
-        StorageDead(_18);
-        StorageDead(_17);
+    bb6: {
         StorageDead(_21);
         StorageDead(_19);
+        StorageDead(_17);
         StorageDead(_16);
+        StorageDead(_20);
+        StorageDead(_18);
         StorageDead(_15);
+        StorageDead(_14);
         unreachable;
     }
 
-    bb6: {
-        goto -> bb8;
+    bb7: {
+        goto -> bb9;
     }
 
-    bb7: {
+    bb8: {
         _1 = const ();
-        goto -> bb8;
+        goto -> bb9;
     }
 
-    bb8: {
+    bb9: {
         StorageDead(_10);
         StorageDead(_9);
         StorageDead(_8);
-        goto -> bb9;
+        goto -> bb10;
     }
 
-    bb9: {
+    bb10: {
         StorageDead(_7);
         StorageDead(_6);
         StorageDead(_4);
         StorageDead(_2);
         StorageDead(_1);
+        StorageLive(_22);
         StorageLive(_23);
         StorageLive(_24);
         StorageLive(_25);
-        StorageLive(_26);
-        _26 = function_with_bytes::<&*b"AAAA">() -> [return: bb10, unwind: bb19];
+        _25 = function_with_bytes::<&*b"AAAA">() -> [return: bb11, unwind: bb21];
     }
 
-    bb10: {
-        _25 = &_26;
+    bb11: {
+        _24 = &_25;
+        StorageLive(_26);
         StorageLive(_27);
+        _27 = const b"AAAA";
+        _26 = &_27;
+        _23 = (move _24, move _26);
+        StorageDead(_26);
+        StorageDead(_24);
+        FakeRead(ForMatchedPlace(None), _23);
         StorageLive(_28);
-        _28 = const b"AAAA";
-        _27 = &_28;
-        _24 = (move _25, move _27);
-        StorageDead(_27);
-        StorageDead(_25);
-        FakeRead(ForMatchedPlace(None), _24);
+        _28 = (_23.0: &&[u8]);
         StorageLive(_29);
-        _29 = (_24.0: &&[u8]);
+        _29 = (_23.1: &&[u8; 4]);
         StorageLive(_30);
-        _30 = (_24.1: &&[u8; 4]);
         StorageLive(_31);
+        _31 = &(*_28);
         StorageLive(_32);
-        StorageLive(_33);
-        _33 = &(*_29);
-        StorageLive(_34);
-        _34 = &(*_30);
-        _32 = <&[u8] as PartialEq<&[u8; 4]>>::eq(move _33, move _34) -> [return: bb11, unwind: bb19];
+        _32 = &(*_29);
+        _30 = <&[u8] as PartialEq<&[u8; 4]>>::eq(move _31, move _32) -> [return: bb12, unwind: bb21];
     }
 
-    bb11: {
-        StorageDead(_34);
-        StorageDead(_33);
-        _31 = Not(move _32);
+    bb12: {
+        switchInt(move _30) -> [0: bb14, otherwise: bb13];
+    }
+
+    bb13: {
         StorageDead(_32);
-        switchInt(move _31) -> [0: bb13, otherwise: bb12];
+        StorageDead(_31);
+        goto -> bb18;
     }
 
-    bb12: {
+    bb14: {
+        goto -> bb15;
+    }
+
+    bb15: {
+        StorageDead(_32);
+        StorageDead(_31);
+        StorageLive(_34);
+        _34 = core::panicking::AssertKind::Eq;
+        FakeRead(ForLet(None), _34);
+        StorageLive(_35);
         StorageLive(_36);
-        _36 = core::panicking::AssertKind::Eq;
-        FakeRead(ForLet(None), _36);
+        _36 = move _34;
         StorageLive(_37);
         StorageLive(_38);
-        _38 = move _36;
+        _38 = &(*_28);
+        _37 = &(*_38);
         StorageLive(_39);
         StorageLive(_40);
         _40 = &(*_29);
         _39 = &(*_40);
         StorageLive(_41);
-        StorageLive(_42);
-        _42 = &(*_30);
-        _41 = &(*_42);
-        StorageLive(_43);
-        _43 = Option::<Arguments<'_>>::None;
-        _37 = core::panicking::assert_failed::<&[u8], &[u8; 4]>(move _38, move _39, move _41, move _43) -> bb19;
-    }
-
-    bb13: {
-        goto -> bb16;
+        _41 = Option::<Arguments<'_>>::None;
+        _35 = core::panicking::assert_failed::<&[u8], &[u8; 4]>(move _36, move _37, move _39, move _41) -> bb21;
     }
 
-    bb14: {
-        StorageDead(_43);
+    bb16: {
         StorageDead(_41);
         StorageDead(_39);
-        StorageDead(_38);
-        StorageDead(_42);
-        StorageDead(_40);
         StorageDead(_37);
         StorageDead(_36);
+        StorageDead(_40);
+        StorageDead(_38);
+        StorageDead(_35);
+        StorageDead(_34);
         unreachable;
     }
 
-    bb15: {
-        goto -> bb17;
+    bb17: {
+        goto -> bb19;
     }
 
-    bb16: {
-        _23 = const ();
-        goto -> bb17;
+    bb18: {
+        _22 = const ();
+        goto -> bb19;
     }
 
-    bb17: {
-        StorageDead(_31);
+    bb19: {
         StorageDead(_30);
         StorageDead(_29);
-        goto -> bb18;
+        StorageDead(_28);
+        goto -> bb20;
     }
 
-    bb18: {
-        StorageDead(_28);
-        StorageDead(_26);
-        StorageDead(_24);
+    bb20: {
+        StorageDead(_27);
+        StorageDead(_25);
         StorageDead(_23);
+        StorageDead(_22);
         _0 = const ();
         return;
     }
 
-    bb19 (cleanup): {
+    bb21 (cleanup): {
         resume;
     }
 }
diff --git a/tests/mir-opt/lower_array_len.array_bound.NormalizeArrayLen.panic-abort.diff b/tests/mir-opt/lower_array_len.array_bound.NormalizeArrayLen.panic-abort.diff
index 6174d5259d0..5242c5f6afd 100644
--- a/tests/mir-opt/lower_array_len.array_bound.NormalizeArrayLen.panic-abort.diff
+++ b/tests/mir-opt/lower_array_len.array_bound.NormalizeArrayLen.panic-abort.diff
@@ -32,12 +32,12 @@
       bb1: {
           StorageDead(_6);
           _3 = Lt(move _4, move _5);
-          StorageDead(_5);
-          StorageDead(_4);
           switchInt(move _3) -> [0: bb4, otherwise: bb2];
       }
   
       bb2: {
+          StorageDead(_5);
+          StorageDead(_4);
           StorageLive(_8);
           _8 = _1;
           _9 = Len((*_2));
@@ -52,6 +52,8 @@
       }
   
       bb4: {
+          StorageDead(_5);
+          StorageDead(_4);
           _0 = const 42_u8;
           goto -> bb5;
       }
diff --git a/tests/mir-opt/lower_array_len.array_bound.NormalizeArrayLen.panic-unwind.diff b/tests/mir-opt/lower_array_len.array_bound.NormalizeArrayLen.panic-unwind.diff
index 60c0772d8ec..a9e99933b12 100644
--- a/tests/mir-opt/lower_array_len.array_bound.NormalizeArrayLen.panic-unwind.diff
+++ b/tests/mir-opt/lower_array_len.array_bound.NormalizeArrayLen.panic-unwind.diff
@@ -32,12 +32,12 @@
       bb1: {
           StorageDead(_6);
           _3 = Lt(move _4, move _5);
-          StorageDead(_5);
-          StorageDead(_4);
           switchInt(move _3) -> [0: bb4, otherwise: bb2];
       }
   
       bb2: {
+          StorageDead(_5);
+          StorageDead(_4);
           StorageLive(_8);
           _8 = _1;
           _9 = Len((*_2));
@@ -52,6 +52,8 @@
       }
   
       bb4: {
+          StorageDead(_5);
+          StorageDead(_4);
           _0 = const 42_u8;
           goto -> bb5;
       }
diff --git a/tests/mir-opt/lower_array_len.array_bound_mut.NormalizeArrayLen.panic-abort.diff b/tests/mir-opt/lower_array_len.array_bound_mut.NormalizeArrayLen.panic-abort.diff
index e2de1845296..7749ba6beca 100644
--- a/tests/mir-opt/lower_array_len.array_bound_mut.NormalizeArrayLen.panic-abort.diff
+++ b/tests/mir-opt/lower_array_len.array_bound_mut.NormalizeArrayLen.panic-abort.diff
@@ -35,12 +35,12 @@
       bb1: {
           StorageDead(_6);
           _3 = Lt(move _4, move _5);
-          StorageDead(_5);
-          StorageDead(_4);
           switchInt(move _3) -> [0: bb4, otherwise: bb2];
       }
   
       bb2: {
+          StorageDead(_5);
+          StorageDead(_4);
           StorageLive(_8);
           _8 = _1;
           _9 = Len((*_2));
@@ -55,6 +55,8 @@
       }
   
       bb4: {
+          StorageDead(_5);
+          StorageDead(_4);
           StorageLive(_11);
           _11 = const 0_usize;
           _12 = Len((*_2));
diff --git a/tests/mir-opt/lower_array_len.array_bound_mut.NormalizeArrayLen.panic-unwind.diff b/tests/mir-opt/lower_array_len.array_bound_mut.NormalizeArrayLen.panic-unwind.diff
index eb81e0eea2c..fcc2c1653dc 100644
--- a/tests/mir-opt/lower_array_len.array_bound_mut.NormalizeArrayLen.panic-unwind.diff
+++ b/tests/mir-opt/lower_array_len.array_bound_mut.NormalizeArrayLen.panic-unwind.diff
@@ -35,12 +35,12 @@
       bb1: {
           StorageDead(_6);
           _3 = Lt(move _4, move _5);
-          StorageDead(_5);
-          StorageDead(_4);
           switchInt(move _3) -> [0: bb4, otherwise: bb2];
       }
   
       bb2: {
+          StorageDead(_5);
+          StorageDead(_4);
           StorageLive(_8);
           _8 = _1;
           _9 = Len((*_2));
@@ -55,6 +55,8 @@
       }
   
       bb4: {
+          StorageDead(_5);
+          StorageDead(_4);
           StorageLive(_11);
           _11 = const 0_usize;
           _12 = Len((*_2));
diff --git a/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-abort.diff b/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-abort.diff
index 70b33fb703b..7f752ca0f5a 100644
--- a/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-abort.diff
+++ b/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-abort.diff
@@ -28,12 +28,12 @@
       bb1: {
           StorageDead(_6);
           _3 = Lt(move _4, move _5);
-          StorageDead(_5);
-          StorageDead(_4);
           switchInt(move _3) -> [0: bb4, otherwise: bb2];
       }
   
       bb2: {
+          StorageDead(_5);
+          StorageDead(_4);
           StorageLive(_7);
           _7 = _1;
           _8 = Len((*_2));
@@ -48,6 +48,8 @@
       }
   
       bb4: {
+          StorageDead(_5);
+          StorageDead(_4);
           _0 = const 42_u8;
           goto -> bb5;
       }
diff --git a/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-unwind.diff b/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-unwind.diff
index 310b3b26ac5..d73b563a0e5 100644
--- a/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-unwind.diff
+++ b/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-unwind.diff
@@ -28,12 +28,12 @@
       bb1: {
           StorageDead(_6);
           _3 = Lt(move _4, move _5);
-          StorageDead(_5);
-          StorageDead(_4);
           switchInt(move _3) -> [0: bb4, otherwise: bb2];
       }
   
       bb2: {
+          StorageDead(_5);
+          StorageDead(_4);
           StorageLive(_7);
           _7 = _1;
           _8 = Len((*_2));
@@ -48,6 +48,8 @@
       }
   
       bb4: {
+          StorageDead(_5);
+          StorageDead(_4);
           _0 = const 42_u8;
           goto -> bb5;
       }
diff --git a/tests/mir-opt/matches_reduce_branches.match_nested_if.MatchBranchSimplification.diff b/tests/mir-opt/matches_reduce_branches.match_nested_if.MatchBranchSimplification.diff
index b5edbfee0fc..5a71bef9341 100644
--- a/tests/mir-opt/matches_reduce_branches.match_nested_if.MatchBranchSimplification.diff
+++ b/tests/mir-opt/matches_reduce_branches.match_nested_if.MatchBranchSimplification.diff
@@ -40,39 +40,43 @@
 -     }
 - 
 -     bb3: {
+-         switchInt(move _5) -> [0: bb5, otherwise: bb4];
+-     }
+- 
+-     bb4: {
 +         StorageLive(_7);
 +         _7 = move _6;
 +         _5 = Ne(_7, const false);
 +         StorageDead(_7);
++         StorageLive(_8);
++         _8 = move _5;
           StorageDead(_6);
--         switchInt(move _5) -> [0: bb5, otherwise: bb4];
--     }
-- 
--     bb4: {
 -         _4 = const true;
 -         goto -> bb6;
 -     }
 - 
 -     bb5: {
+-         StorageDead(_6);
 -         _4 = const false;
 -         goto -> bb6;
 -     }
 - 
 -     bb6: {
-+         StorageLive(_8);
-+         _8 = move _5;
-+         _4 = Ne(_8, const false);
-+         StorageDead(_8);
-          StorageDead(_5);
 -         switchInt(move _4) -> [0: bb8, otherwise: bb7];
 -     }
 - 
 -     bb7: {
++         _4 = Ne(_8, const false);
++         StorageDead(_8);
++         StorageLive(_9);
++         _9 = move _4;
+          StorageDead(_5);
 -         _3 = const true;
 -         goto -> bb9;
 -     }
 - 
 -     bb8: {
+-         StorageDead(_5);
 -         _3 = const false;
 -         goto -> bb9;
 -     }
@@ -82,8 +86,6 @@
 -     }
 - 
 -     bb10: {
-+         StorageLive(_9);
-+         _9 = move _4;
 +         _3 = Ne(_9, const false);
 +         StorageDead(_9);
 +         StorageLive(_10);
diff --git a/tests/mir-opt/not_equal_false.opt.InstSimplify.diff b/tests/mir-opt/not_equal_false.opt.InstSimplify.diff
index 71353be24a6..1342966aa15 100644
--- a/tests/mir-opt/not_equal_false.opt.InstSimplify.diff
+++ b/tests/mir-opt/not_equal_false.opt.InstSimplify.diff
@@ -13,16 +13,17 @@
           _3 = _1;
 -         _2 = Ne(move _3, const false);
 +         _2 = move _3;
-          StorageDead(_3);
           switchInt(move _2) -> [0: bb2, otherwise: bb1];
       }
   
       bb1: {
+          StorageDead(_3);
           _0 = const 0_u32;
           goto -> bb3;
       }
   
       bb2: {
+          StorageDead(_3);
           _0 = const 1_u32;
           goto -> bb3;
       }
diff --git a/tests/mir-opt/pre-codegen/chained_comparison.naive.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/chained_comparison.naive.PreCodegen.after.mir
index c7fd397fcd4..838e30fa35e 100644
--- a/tests/mir-opt/pre-codegen/chained_comparison.naive.PreCodegen.after.mir
+++ b/tests/mir-opt/pre-codegen/chained_comparison.naive.PreCodegen.after.mir
@@ -7,130 +7,111 @@ fn naive(_1: &Blueprint, _2: &Blueprint) -> bool {
     let mut _3: u32;
     let mut _4: u32;
     let mut _5: bool;
-    let mut _6: bool;
+    let mut _6: u32;
     let mut _7: u32;
-    let mut _8: u32;
-    let mut _9: bool;
-    let mut _10: bool;
-    let mut _11: u32;
+    let mut _8: bool;
+    let mut _9: u32;
+    let mut _10: u32;
+    let mut _11: bool;
     let mut _12: u32;
-    let mut _13: bool;
+    let mut _13: u32;
     let mut _14: bool;
     let mut _15: u32;
     let mut _16: u32;
-    let mut _17: bool;
-    let mut _18: u32;
-    let mut _19: u32;
-    let mut _20: bool;
 
     bb0: {
-        StorageLive(_14);
-        StorageLive(_10);
-        StorageLive(_6);
         StorageLive(_5);
         StorageLive(_3);
         _3 = ((*_1).0: u32);
         StorageLive(_4);
         _4 = ((*_2).0: u32);
         _5 = Eq(move _3, move _4);
-        StorageDead(_4);
-        StorageDead(_3);
         switchInt(move _5) -> [0: bb1, otherwise: bb2];
     }
 
     bb1: {
-        _6 = const false;
-        goto -> bb3;
+        StorageDead(_4);
+        StorageDead(_3);
+        goto -> bb8;
     }
 
     bb2: {
-        StorageLive(_9);
-        StorageLive(_7);
-        _7 = ((*_1).1: u32);
+        StorageDead(_4);
+        StorageDead(_3);
         StorageLive(_8);
-        _8 = ((*_2).1: u32);
-        _9 = Eq(move _7, move _8);
-        StorageDead(_8);
-        StorageDead(_7);
-        _6 = move _9;
-        goto -> bb3;
+        StorageLive(_6);
+        _6 = ((*_1).1: u32);
+        StorageLive(_7);
+        _7 = ((*_2).1: u32);
+        _8 = Eq(move _6, move _7);
+        switchInt(move _8) -> [0: bb3, otherwise: bb4];
     }
 
     bb3: {
-        StorageDead(_9);
-        StorageDead(_5);
-        switchInt(move _6) -> [0: bb4, otherwise: bb5];
+        StorageDead(_7);
+        StorageDead(_6);
+        goto -> bb8;
     }
 
     bb4: {
-        _10 = const false;
-        goto -> bb6;
+        StorageDead(_7);
+        StorageDead(_6);
+        StorageLive(_11);
+        StorageLive(_9);
+        _9 = ((*_1).2: u32);
+        StorageLive(_10);
+        _10 = ((*_2).2: u32);
+        _11 = Eq(move _9, move _10);
+        switchInt(move _11) -> [0: bb5, otherwise: bb6];
     }
 
     bb5: {
-        StorageLive(_13);
-        StorageLive(_11);
-        _11 = ((*_1).2: u32);
-        StorageLive(_12);
-        _12 = ((*_2).2: u32);
-        _13 = Eq(move _11, move _12);
-        StorageDead(_12);
-        StorageDead(_11);
-        _10 = move _13;
-        goto -> bb6;
+        StorageDead(_10);
+        StorageDead(_9);
+        goto -> bb8;
     }
 
     bb6: {
-        StorageDead(_13);
-        StorageDead(_6);
-        switchInt(move _10) -> [0: bb7, otherwise: bb8];
+        StorageDead(_10);
+        StorageDead(_9);
+        StorageLive(_14);
+        StorageLive(_12);
+        _12 = ((*_1).3: u32);
+        StorageLive(_13);
+        _13 = ((*_2).3: u32);
+        _14 = Eq(move _12, move _13);
+        switchInt(move _14) -> [0: bb7, otherwise: bb9];
     }
 
     bb7: {
-        _14 = const false;
-        goto -> bb9;
+        StorageDead(_13);
+        StorageDead(_12);
+        goto -> bb8;
     }
 
     bb8: {
-        StorageLive(_17);
+        _0 = const false;
+        goto -> bb10;
+    }
+
+    bb9: {
+        StorageDead(_13);
+        StorageDead(_12);
         StorageLive(_15);
-        _15 = ((*_1).3: u32);
+        _15 = ((*_1).4: u32);
         StorageLive(_16);
-        _16 = ((*_2).3: u32);
-        _17 = Eq(move _15, move _16);
+        _16 = ((*_2).4: u32);
+        _0 = Eq(move _15, move _16);
         StorageDead(_16);
         StorageDead(_15);
-        _14 = move _17;
-        goto -> bb9;
-    }
-
-    bb9: {
-        StorageDead(_17);
-        StorageDead(_10);
-        switchInt(move _14) -> [0: bb10, otherwise: bb11];
+        goto -> bb10;
     }
 
     bb10: {
-        _0 = const false;
-        goto -> bb12;
-    }
-
-    bb11: {
-        StorageLive(_20);
-        StorageLive(_18);
-        _18 = ((*_1).4: u32);
-        StorageLive(_19);
-        _19 = ((*_2).4: u32);
-        _20 = Eq(move _18, move _19);
-        StorageDead(_19);
-        StorageDead(_18);
-        _0 = move _20;
-        goto -> bb12;
-    }
-
-    bb12: {
-        StorageDead(_20);
         StorageDead(_14);
+        StorageDead(_11);
+        StorageDead(_8);
+        StorageDead(_5);
         return;
     }
 }
diff --git a/tests/mir-opt/pre-codegen/chained_comparison.returning.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/chained_comparison.returning.PreCodegen.after.mir
index 1e619bc9704..8452fa12f31 100644
--- a/tests/mir-opt/pre-codegen/chained_comparison.returning.PreCodegen.after.mir
+++ b/tests/mir-opt/pre-codegen/chained_comparison.returning.PreCodegen.after.mir
@@ -27,12 +27,12 @@ fn returning(_1: &Blueprint, _2: &Blueprint) -> bool {
         StorageLive(_4);
         _4 = ((*_2).0: u32);
         _5 = Ne(move _3, move _4);
-        StorageDead(_4);
-        StorageDead(_3);
         switchInt(move _5) -> [0: bb1, otherwise: bb10];
     }
 
     bb1: {
+        StorageDead(_4);
+        StorageDead(_3);
         StorageDead(_5);
         StorageLive(_8);
         StorageLive(_6);
@@ -40,12 +40,12 @@ fn returning(_1: &Blueprint, _2: &Blueprint) -> bool {
         StorageLive(_7);
         _7 = ((*_2).1: u32);
         _8 = Ne(move _6, move _7);
-        StorageDead(_7);
-        StorageDead(_6);
         switchInt(move _8) -> [0: bb2, otherwise: bb9];
     }
 
     bb2: {
+        StorageDead(_7);
+        StorageDead(_6);
         StorageDead(_8);
         StorageLive(_11);
         StorageLive(_9);
@@ -53,12 +53,12 @@ fn returning(_1: &Blueprint, _2: &Blueprint) -> bool {
         StorageLive(_10);
         _10 = ((*_2).2: u32);
         _11 = Ne(move _9, move _10);
-        StorageDead(_10);
-        StorageDead(_9);
         switchInt(move _11) -> [0: bb3, otherwise: bb8];
     }
 
     bb3: {
+        StorageDead(_10);
+        StorageDead(_9);
         StorageDead(_11);
         StorageLive(_14);
         StorageLive(_12);
@@ -66,12 +66,12 @@ fn returning(_1: &Blueprint, _2: &Blueprint) -> bool {
         StorageLive(_13);
         _13 = ((*_2).3: u32);
         _14 = Ne(move _12, move _13);
-        StorageDead(_13);
-        StorageDead(_12);
         switchInt(move _14) -> [0: bb4, otherwise: bb7];
     }
 
     bb4: {
+        StorageDead(_13);
+        StorageDead(_12);
         StorageDead(_14);
         StorageLive(_17);
         StorageLive(_15);
@@ -79,42 +79,52 @@ fn returning(_1: &Blueprint, _2: &Blueprint) -> bool {
         StorageLive(_16);
         _16 = ((*_2).4: u32);
         _17 = Ne(move _15, move _16);
-        StorageDead(_16);
-        StorageDead(_15);
         switchInt(move _17) -> [0: bb5, otherwise: bb6];
     }
 
     bb5: {
+        StorageDead(_16);
+        StorageDead(_15);
         StorageDead(_17);
         _0 = const true;
         goto -> bb11;
     }
 
     bb6: {
+        StorageDead(_16);
+        StorageDead(_15);
         _0 = const false;
         StorageDead(_17);
         goto -> bb11;
     }
 
     bb7: {
+        StorageDead(_13);
+        StorageDead(_12);
         _0 = const false;
         StorageDead(_14);
         goto -> bb11;
     }
 
     bb8: {
+        StorageDead(_10);
+        StorageDead(_9);
         _0 = const false;
         StorageDead(_11);
         goto -> bb11;
     }
 
     bb9: {
+        StorageDead(_7);
+        StorageDead(_6);
         _0 = const false;
         StorageDead(_8);
         goto -> bb11;
     }
 
     bb10: {
+        StorageDead(_4);
+        StorageDead(_3);
         _0 = const false;
         StorageDead(_5);
         goto -> bb11;
diff --git a/tests/mir-opt/pre-codegen/checked_ops.step_forward.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/checked_ops.step_forward.PreCodegen.after.mir
index b2ea96f033e..75f81c5aaca 100644
--- a/tests/mir-opt/pre-codegen/checked_ops.step_forward.PreCodegen.after.mir
+++ b/tests/mir-opt/pre-codegen/checked_ops.step_forward.PreCodegen.after.mir
@@ -40,16 +40,22 @@ fn step_forward(_1: u32, _2: usize) -> u32 {
         _5 = Eq(_4, const 1_isize);
         _6 = Not(move _5);
         StorageDead(_5);
-        StorageDead(_3);
-        StorageDead(_8);
-        switchInt(move _6) -> [0: bb3, otherwise: bb2];
+        switchInt(move _6) -> [0: bb2, otherwise: bb3];
     }
 
     bb2: {
-        assert(!const true, "attempt to compute `{} + {}`, which would overflow", const _, const 1_u32) -> [success: bb3, unwind continue];
+        StorageDead(_3);
+        StorageDead(_8);
+        goto -> bb4;
     }
 
     bb3: {
+        StorageDead(_3);
+        StorageDead(_8);
+        assert(!const true, "attempt to compute `{} + {}`, which would overflow", const _, const 1_u32) -> [success: bb4, unwind continue];
+    }
+
+    bb4: {
         StorageDead(_6);
         StorageLive(_7);
         _7 = _2 as u32 (IntToInt);
diff --git a/tests/mir-opt/pre-codegen/loops.int_range.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/loops.int_range.PreCodegen.after.mir
index 2e51faeba5a..0d79f2de10d 100644
--- a/tests/mir-opt/pre-codegen/loops.int_range.PreCodegen.after.mir
+++ b/tests/mir-opt/pre-codegen/loops.int_range.PreCodegen.after.mir
@@ -63,17 +63,19 @@ fn int_range(_1: usize, _2: usize) -> () {
         _7 = Lt(move _5, move _6);
         StorageDead(_6);
         StorageDead(_5);
-        StorageDead(_16);
-        StorageDead(_15);
         switchInt(move _7) -> [0: bb2, otherwise: bb3];
     }
 
     bb2: {
+        StorageDead(_16);
+        StorageDead(_15);
         _8 = Option::<usize>::None;
         goto -> bb5;
     }
 
     bb3: {
+        StorageDead(_16);
+        StorageDead(_15);
         _9 = (_4.0: usize);
         StorageLive(_10);
         _10 = <usize as Step>::forward_unchecked(_9, const 1_usize) -> [return: bb4, unwind continue];
diff --git a/tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.mir
index 26919dd98dd..630babaa821 100644
--- a/tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.mir
+++ b/tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.mir
@@ -10,23 +10,53 @@ fn mem_replace(_1: &mut u32, _2: u32) -> u32 {
         scope 2 {
             scope 3 {
                 debug result => _0;
-                scope 6 (inlined std::ptr::write::<u32>) {
+                scope 16 (inlined std::ptr::write::<u32>) {
                     debug dst => _1;
                     debug src => _2;
-                    scope 7 {
+                    scope 17 {
                     }
                 }
             }
             scope 4 (inlined std::ptr::read::<u32>) {
                 debug src => _1;
                 scope 5 {
+                    scope 6 (inlined std::ptr::read::runtime::<u32>) {
+                        debug src => _1;
+                        scope 7 (inlined intrinsics::is_aligned_and_not_null::<u32>) {
+                            debug ptr => _1;
+                            scope 8 (inlined ptr::const_ptr::<impl *const u32>::is_null) {
+                                debug self => _1;
+                                let mut _3: *const u8;
+                                scope 9 {
+                                    scope 10 (inlined ptr::const_ptr::<impl *const T>::is_null::runtime_impl) {
+                                        debug ptr => _3;
+                                        scope 11 (inlined ptr::const_ptr::<impl *const u8>::addr) {
+                                            debug self => _3;
+                                            scope 12 {
+                                                scope 13 (inlined ptr::const_ptr::<impl *const u8>::cast::<()>) {
+                                                    debug self => _3;
+                                                }
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                            scope 14 (inlined ptr::const_ptr::<impl *const u32>::is_aligned) {
+                                debug self => _1;
+                                scope 15 (inlined align_of::<u32>) {
+                                }
+                            }
+                        }
+                    }
                 }
             }
         }
     }
 
     bb0: {
+        StorageLive(_3);
         _0 = (*_1);
+        StorageDead(_3);
         (*_1) = _2;
         return;
     }
diff --git a/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-abort.mir
index d76b46bdd94..9664ccfb094 100644
--- a/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-abort.mir
@@ -66,17 +66,19 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () {
         _8 = Lt(move _6, move _7);
         StorageDead(_7);
         StorageDead(_6);
-        StorageDead(_19);
-        StorageDead(_18);
         switchInt(move _8) -> [0: bb2, otherwise: bb3];
     }
 
     bb2: {
+        StorageDead(_19);
+        StorageDead(_18);
         _9 = Option::<u32>::None;
         goto -> bb5;
     }
 
     bb3: {
+        StorageDead(_19);
+        StorageDead(_18);
         _10 = (_5.0: u32);
         StorageLive(_11);
         _11 = <u32 as Step>::forward_unchecked(_10, const 1_usize) -> [return: bb4, unwind unreachable];
diff --git a/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-unwind.mir
index 35f7356d47a..dc8b46b6c08 100644
--- a/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-unwind.mir
@@ -66,17 +66,19 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () {
         _8 = Lt(move _6, move _7);
         StorageDead(_7);
         StorageDead(_6);
-        StorageDead(_19);
-        StorageDead(_18);
         switchInt(move _8) -> [0: bb2, otherwise: bb3];
     }
 
     bb2: {
+        StorageDead(_19);
+        StorageDead(_18);
         _9 = Option::<u32>::None;
         goto -> bb5;
     }
 
     bb3: {
+        StorageDead(_19);
+        StorageDead(_18);
         _10 = (_5.0: u32);
         StorageLive(_11);
         _11 = <u32 as Step>::forward_unchecked(_10, const 1_usize) -> [return: bb4, unwind: bb11];
diff --git a/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-abort.mir
index 7360aa3e698..fff713b5a79 100644
--- a/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-abort.mir
@@ -38,17 +38,19 @@ fn range_iter_next(_1: &mut std::ops::Range<u32>) -> Option<u32> {
         _4 = Lt(move _2, move _3);
         StorageDead(_3);
         StorageDead(_2);
-        StorageDead(_8);
-        StorageDead(_7);
         switchInt(move _4) -> [0: bb1, otherwise: bb2];
     }
 
     bb1: {
+        StorageDead(_8);
+        StorageDead(_7);
         _0 = Option::<u32>::None;
         goto -> bb4;
     }
 
     bb2: {
+        StorageDead(_8);
+        StorageDead(_7);
         _5 = ((*_1).0: u32);
         StorageLive(_6);
         _6 = <u32 as Step>::forward_unchecked(_5, const 1_usize) -> [return: bb3, unwind unreachable];
diff --git a/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-unwind.mir
index 61957082d8b..cc12c0122b7 100644
--- a/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-unwind.mir
@@ -38,17 +38,19 @@ fn range_iter_next(_1: &mut std::ops::Range<u32>) -> Option<u32> {
         _4 = Lt(move _2, move _3);
         StorageDead(_3);
         StorageDead(_2);
-        StorageDead(_8);
-        StorageDead(_7);
         switchInt(move _4) -> [0: bb1, otherwise: bb2];
     }
 
     bb1: {
+        StorageDead(_8);
+        StorageDead(_7);
         _0 = Option::<u32>::None;
         goto -> bb4;
     }
 
     bb2: {
+        StorageDead(_8);
+        StorageDead(_7);
         _5 = ((*_1).0: u32);
         StorageLive(_6);
         _6 = <u32 as Step>::forward_unchecked(_5, const 1_usize) -> [return: bb3, unwind continue];
diff --git a/tests/mir-opt/pre-codegen/slice_filter.variant_a-{closure#0}.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/slice_filter.variant_a-{closure#0}.PreCodegen.after.mir
index 1488779f93b..ddfd5b0fefc 100644
--- a/tests/mir-opt/pre-codegen/slice_filter.variant_a-{closure#0}.PreCodegen.after.mir
+++ b/tests/mir-opt/pre-codegen/slice_filter.variant_a-{closure#0}.PreCodegen.after.mir
@@ -12,30 +12,27 @@ fn variant_a::{closure#0}(_1: &mut [closure@$DIR/slice_filter.rs:7:25: 7:39], _2
     let _10: &usize;
     let _11: &usize;
     let mut _16: bool;
-    let mut _17: bool;
-    let _18: &usize;
-    let mut _23: bool;
-    let _24: &usize;
-    let mut _29: bool;
-    let mut _30: bool;
-    let _31: &usize;
-    let mut _36: bool;
+    let _17: &usize;
+    let mut _22: bool;
+    let _23: &usize;
+    let mut _28: bool;
+    let _29: &usize;
+    let mut _34: &&usize;
+    let mut _35: &&usize;
+    let mut _36: &&usize;
     let mut _37: &&usize;
     let mut _38: &&usize;
     let mut _39: &&usize;
     let mut _40: &&usize;
     let mut _41: &&usize;
-    let mut _42: &&usize;
-    let mut _43: &&usize;
-    let mut _44: &&usize;
     scope 1 {
         debug a => _4;
         debug b => _6;
         debug c => _8;
         debug d => _10;
         scope 2 (inlined cmp::impls::<impl PartialOrd for &usize>::le) {
-            debug self => _37;
-            debug other => _38;
+            debug self => _34;
+            debug other => _35;
             let mut _12: &usize;
             let mut _13: &usize;
             scope 3 (inlined cmp::impls::<impl PartialOrd for usize>::le) {
@@ -46,39 +43,39 @@ fn variant_a::{closure#0}(_1: &mut [closure@$DIR/slice_filter.rs:7:25: 7:39], _2
             }
         }
         scope 4 (inlined cmp::impls::<impl PartialOrd for &usize>::le) {
-            debug self => _41;
-            debug other => _42;
-            let mut _25: &usize;
-            let mut _26: &usize;
+            debug self => _36;
+            debug other => _37;
+            let mut _18: &usize;
+            let mut _19: &usize;
             scope 5 (inlined cmp::impls::<impl PartialOrd for usize>::le) {
-                debug self => _25;
-                debug other => _26;
-                let mut _27: usize;
-                let mut _28: usize;
+                debug self => _18;
+                debug other => _19;
+                let mut _20: usize;
+                let mut _21: usize;
             }
         }
         scope 6 (inlined cmp::impls::<impl PartialOrd for &usize>::le) {
-            debug self => _39;
-            debug other => _40;
-            let mut _19: &usize;
-            let mut _20: &usize;
+            debug self => _38;
+            debug other => _39;
+            let mut _24: &usize;
+            let mut _25: &usize;
             scope 7 (inlined cmp::impls::<impl PartialOrd for usize>::le) {
-                debug self => _19;
-                debug other => _20;
-                let mut _21: usize;
-                let mut _22: usize;
+                debug self => _24;
+                debug other => _25;
+                let mut _26: usize;
+                let mut _27: usize;
             }
         }
         scope 8 (inlined cmp::impls::<impl PartialOrd for &usize>::le) {
-            debug self => _43;
-            debug other => _44;
-            let mut _32: &usize;
-            let mut _33: &usize;
+            debug self => _40;
+            debug other => _41;
+            let mut _30: &usize;
+            let mut _31: &usize;
             scope 9 (inlined cmp::impls::<impl PartialOrd for usize>::le) {
-                debug self => _32;
-                debug other => _33;
-                let mut _34: usize;
-                let mut _35: usize;
+                debug self => _30;
+                debug other => _31;
+                let mut _32: usize;
+                let mut _33: usize;
             }
         }
     }
@@ -96,10 +93,9 @@ fn variant_a::{closure#0}(_1: &mut [closure@$DIR/slice_filter.rs:7:25: 7:39], _2
         StorageLive(_10);
         _9 = deref_copy (*_2);
         _10 = &((*_9).3: usize);
-        StorageLive(_17);
         StorageLive(_16);
-        StorageLive(_37);
-        StorageLive(_38);
+        StorageLive(_34);
+        StorageLive(_35);
         StorageLive(_11);
         _11 = _8;
         _12 = deref_copy _4;
@@ -111,109 +107,109 @@ fn variant_a::{closure#0}(_1: &mut [closure@$DIR/slice_filter.rs:7:25: 7:39], _2
         _16 = Le(move _14, move _15);
         StorageDead(_15);
         StorageDead(_14);
-        StorageDead(_11);
-        StorageDead(_38);
-        StorageDead(_37);
         switchInt(move _16) -> [0: bb1, otherwise: bb2];
     }
 
     bb1: {
-        _17 = const false;
-        goto -> bb3;
+        StorageDead(_11);
+        StorageDead(_35);
+        StorageDead(_34);
+        goto -> bb4;
     }
 
     bb2: {
-        StorageLive(_23);
-        StorageLive(_39);
-        StorageLive(_40);
-        StorageLive(_18);
-        _18 = _6;
-        _19 = deref_copy _10;
-        _20 = deref_copy _18;
+        StorageDead(_11);
+        StorageDead(_35);
+        StorageDead(_34);
+        StorageLive(_22);
+        StorageLive(_36);
+        StorageLive(_37);
+        StorageLive(_17);
+        _17 = _6;
+        _18 = deref_copy _10;
+        _19 = deref_copy _17;
+        StorageLive(_20);
+        _20 = (*_18);
         StorageLive(_21);
         _21 = (*_19);
-        StorageLive(_22);
-        _22 = (*_20);
-        _23 = Le(move _21, move _22);
-        StorageDead(_22);
+        _22 = Le(move _20, move _21);
         StorageDead(_21);
-        StorageDead(_18);
-        StorageDead(_40);
-        StorageDead(_39);
-        _17 = move _23;
-        goto -> bb3;
+        StorageDead(_20);
+        switchInt(move _22) -> [0: bb3, otherwise: bb8];
     }
 
     bb3: {
-        StorageDead(_23);
-        StorageDead(_16);
-        switchInt(move _17) -> [0: bb4, otherwise: bb8];
+        StorageDead(_17);
+        StorageDead(_37);
+        StorageDead(_36);
+        goto -> bb4;
     }
 
     bb4: {
-        StorageLive(_30);
-        StorageLive(_29);
-        StorageLive(_41);
-        StorageLive(_42);
-        StorageLive(_24);
-        _24 = _4;
-        _25 = deref_copy _8;
-        _26 = deref_copy _24;
+        StorageLive(_28);
+        StorageLive(_38);
+        StorageLive(_39);
+        StorageLive(_23);
+        _23 = _4;
+        _24 = deref_copy _8;
+        _25 = deref_copy _23;
+        StorageLive(_26);
+        _26 = (*_24);
         StorageLive(_27);
         _27 = (*_25);
-        StorageLive(_28);
-        _28 = (*_26);
-        _29 = Le(move _27, move _28);
-        StorageDead(_28);
+        _28 = Le(move _26, move _27);
         StorageDead(_27);
-        StorageDead(_24);
-        StorageDead(_42);
-        StorageDead(_41);
-        switchInt(move _29) -> [0: bb5, otherwise: bb6];
+        StorageDead(_26);
+        switchInt(move _28) -> [0: bb5, otherwise: bb6];
     }
 
     bb5: {
-        _30 = const false;
+        StorageDead(_23);
+        StorageDead(_39);
+        StorageDead(_38);
+        _0 = const false;
         goto -> bb7;
     }
 
     bb6: {
-        StorageLive(_36);
-        StorageLive(_43);
-        StorageLive(_44);
-        StorageLive(_31);
-        _31 = _10;
-        _32 = deref_copy _6;
-        _33 = deref_copy _31;
-        StorageLive(_34);
-        _34 = (*_32);
-        StorageLive(_35);
-        _35 = (*_33);
-        _36 = Le(move _34, move _35);
-        StorageDead(_35);
-        StorageDead(_34);
-        StorageDead(_31);
-        StorageDead(_44);
-        StorageDead(_43);
-        _30 = move _36;
+        StorageDead(_23);
+        StorageDead(_39);
+        StorageDead(_38);
+        StorageLive(_40);
+        StorageLive(_41);
+        StorageLive(_29);
+        _29 = _10;
+        _30 = deref_copy _6;
+        _31 = deref_copy _29;
+        StorageLive(_32);
+        _32 = (*_30);
+        StorageLive(_33);
+        _33 = (*_31);
+        _0 = Le(move _32, move _33);
+        StorageDead(_33);
+        StorageDead(_32);
+        StorageDead(_29);
+        StorageDead(_41);
+        StorageDead(_40);
         goto -> bb7;
     }
 
     bb7: {
-        StorageDead(_36);
-        StorageDead(_29);
-        _0 = move _30;
+        StorageDead(_28);
         goto -> bb9;
     }
 
     bb8: {
+        StorageDead(_17);
+        StorageDead(_37);
+        StorageDead(_36);
         _0 = const true;
         goto -> bb9;
     }
 
     bb9: {
-        StorageDead(_30);
-        StorageDead(_17);
+        StorageDead(_22);
+        StorageDead(_16);
         StorageDead(_10);
         StorageDead(_8);
         StorageDead(_6);
diff --git a/tests/mir-opt/pre-codegen/slice_filter.variant_b-{closure#0}.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/slice_filter.variant_b-{closure#0}.PreCodegen.after.mir
index bab9f0b58aa..7e70c6290a8 100644
--- a/tests/mir-opt/pre-codegen/slice_filter.variant_b-{closure#0}.PreCodegen.after.mir
+++ b/tests/mir-opt/pre-codegen/slice_filter.variant_b-{closure#0}.PreCodegen.after.mir
@@ -13,9 +13,6 @@ fn variant_b::{closure#0}(_1: &mut [closure@$DIR/slice_filter.rs:11:25: 11:41],
     let mut _11: bool;
     let mut _12: bool;
     let mut _13: bool;
-    let mut _14: bool;
-    let mut _15: bool;
-    let mut _16: bool;
     scope 1 {
         debug a => _4;
         debug b => _6;
@@ -32,64 +29,46 @@ fn variant_b::{closure#0}(_1: &mut [closure@$DIR/slice_filter.rs:11:25: 11:41],
         _8 = ((*_7).2: usize);
         _9 = deref_copy (*_2);
         _10 = ((*_9).3: usize);
-        StorageLive(_12);
         StorageLive(_11);
         _11 = Le(_4, _8);
-        switchInt(move _11) -> [0: bb1, otherwise: bb2];
+        switchInt(move _11) -> [0: bb2, otherwise: bb1];
     }
 
     bb1: {
-        _12 = const false;
-        goto -> bb3;
+        StorageLive(_12);
+        _12 = Le(_10, _6);
+        switchInt(move _12) -> [0: bb2, otherwise: bb6];
     }
 
     bb2: {
         StorageLive(_13);
-        _13 = Le(_10, _6);
-        _12 = move _13;
-        goto -> bb3;
+        _13 = Le(_8, _4);
+        switchInt(move _13) -> [0: bb3, otherwise: bb4];
     }
 
     bb3: {
-        StorageDead(_13);
-        StorageDead(_11);
-        switchInt(move _12) -> [0: bb4, otherwise: bb8];
+        _0 = const false;
+        goto -> bb5;
     }
 
     bb4: {
-        StorageLive(_15);
-        StorageLive(_14);
-        _14 = Le(_8, _4);
-        switchInt(move _14) -> [0: bb5, otherwise: bb6];
+        _0 = Le(_6, _10);
+        goto -> bb5;
     }
 
     bb5: {
-        _15 = const false;
+        StorageDead(_13);
         goto -> bb7;
     }
 
     bb6: {
-        StorageLive(_16);
-        _16 = Le(_6, _10);
-        _15 = move _16;
+        _0 = const true;
         goto -> bb7;
     }
 
     bb7: {
-        StorageDead(_16);
-        StorageDead(_14);
-        _0 = move _15;
-        goto -> bb9;
-    }
-
-    bb8: {
-        _0 = const true;
-        goto -> bb9;
-    }
-
-    bb9: {
-        StorageDead(_15);
         StorageDead(_12);
+        StorageDead(_11);
         return;
     }
 }
diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_get_mut_usize.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_index.slice_get_mut_usize.PreCodegen.after.panic-abort.mir
index 07a58309ee4..8590c9d3b83 100644
--- a/tests/mir-opt/pre-codegen/slice_index.slice_get_mut_usize.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/slice_index.slice_get_mut_usize.PreCodegen.after.panic-abort.mir
@@ -58,16 +58,17 @@ fn slice_get_mut_usize(_1: &mut [u32], _2: usize) -> Option<&mut u32> {
         StorageLive(_3);
         _3 = Len((*_1));
         _4 = Lt(_2, move _3);
-        StorageDead(_3);
         switchInt(move _4) -> [0: bb1, otherwise: bb2];
     }
 
     bb1: {
+        StorageDead(_3);
         _0 = const Option::<&mut u32>::None;
         goto -> bb3;
     }
 
     bb2: {
+        StorageDead(_3);
         StorageLive(_8);
         StorageLive(_5);
         _5 = &raw mut (*_1);
diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_get_mut_usize.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_index.slice_get_mut_usize.PreCodegen.after.panic-unwind.mir
index 07a58309ee4..8590c9d3b83 100644
--- a/tests/mir-opt/pre-codegen/slice_index.slice_get_mut_usize.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/slice_index.slice_get_mut_usize.PreCodegen.after.panic-unwind.mir
@@ -58,16 +58,17 @@ fn slice_get_mut_usize(_1: &mut [u32], _2: usize) -> Option<&mut u32> {
         StorageLive(_3);
         _3 = Len((*_1));
         _4 = Lt(_2, move _3);
-        StorageDead(_3);
         switchInt(move _4) -> [0: bb1, otherwise: bb2];
     }
 
     bb1: {
+        StorageDead(_3);
         _0 = const Option::<&mut u32>::None;
         goto -> bb3;
     }
 
     bb2: {
+        StorageDead(_3);
         StorageLive(_8);
         StorageLive(_5);
         _5 = &raw mut (*_1);
diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-abort.mir
index 2f5d356a26d..8dd2cd7900f 100644
--- a/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-abort.mir
@@ -17,37 +17,50 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range<usize>) ->
                 debug slice => _5;
                 let mut _7: *mut u32;
                 let mut _8: *mut u32;
-                let _14: usize;
                 let _15: usize;
+                let _16: usize;
                 scope 4 {
-                    debug this => std::ops::Range<usize>{ .0 => _14, .1 => _15, };
+                    debug this => std::ops::Range<usize>{ .0 => _15, .1 => _16, };
                     scope 5 {
                         let _6: usize;
                         scope 6 {
                             debug new_len => _6;
-                            scope 7 (inlined ptr::mut_ptr::<impl *mut [u32]>::as_mut_ptr) {
+                            scope 11 (inlined ptr::mut_ptr::<impl *mut [u32]>::as_mut_ptr) {
                                 debug self => _5;
                             }
-                            scope 8 (inlined ptr::mut_ptr::<impl *mut u32>::add) {
+                            scope 12 (inlined ptr::mut_ptr::<impl *mut u32>::add) {
                                 debug self => _7;
                                 debug count => _3;
-                                scope 9 {
+                                scope 13 {
                                 }
                             }
-                            scope 10 (inlined slice_from_raw_parts_mut::<u32>) {
+                            scope 14 (inlined slice_from_raw_parts_mut::<u32>) {
                                 debug data => _8;
                                 debug len => _6;
                                 let mut _9: *mut ();
-                                scope 11 (inlined ptr::mut_ptr::<impl *mut u32>::cast::<()>) {
+                                scope 15 (inlined ptr::mut_ptr::<impl *mut u32>::cast::<()>) {
                                     debug self => _8;
                                 }
-                                scope 12 (inlined std::ptr::from_raw_parts_mut::<[u32]>) {
+                                scope 16 (inlined std::ptr::from_raw_parts_mut::<[u32]>) {
                                     debug data_address => _9;
                                     debug metadata => _6;
                                     let mut _10: *const ();
                                     let mut _11: std::ptr::metadata::PtrComponents<[u32]>;
                                     let mut _12: std::ptr::metadata::PtrRepr<[u32]>;
-                                    scope 13 {
+                                    scope 17 {
+                                    }
+                                }
+                            }
+                        }
+                        scope 7 (inlined <std::ops::Range<usize> as SliceIndex<[T]>>::get_unchecked_mut::runtime::<u32>) {
+                            debug this => std::ops::Range<usize>{ .0 => _15, .1 => _16, };
+                            debug slice => _5;
+                            scope 8 (inlined ptr::mut_ptr::<impl *mut [u32]>::len) {
+                                debug self => _5;
+                                let mut _14: *const [u32];
+                                scope 9 (inlined std::ptr::metadata::<[u32]>) {
+                                    debug ptr => _14;
+                                    scope 10 {
                                     }
                                 }
                             }
@@ -63,9 +76,10 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range<usize>) ->
         _4 = move (_2.1: usize);
         StorageLive(_5);
         _5 = &raw mut (*_1);
+        StorageLive(_6);
         StorageLive(_14);
         StorageLive(_15);
-        StorageLive(_6);
+        StorageLive(_16);
         _6 = SubUnchecked(_4, _3);
         StorageLive(_8);
         StorageLive(_7);
@@ -86,9 +100,10 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range<usize>) ->
         StorageDead(_12);
         StorageDead(_9);
         StorageDead(_8);
-        StorageDead(_6);
-        StorageDead(_14);
+        StorageDead(_16);
         StorageDead(_15);
+        StorageDead(_14);
+        StorageDead(_6);
         StorageDead(_5);
         _0 = &mut (*_13);
         return;
diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-unwind.mir
index 2f5d356a26d..8dd2cd7900f 100644
--- a/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-unwind.mir
@@ -17,37 +17,50 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range<usize>) ->
                 debug slice => _5;
                 let mut _7: *mut u32;
                 let mut _8: *mut u32;
-                let _14: usize;
                 let _15: usize;
+                let _16: usize;
                 scope 4 {
-                    debug this => std::ops::Range<usize>{ .0 => _14, .1 => _15, };
+                    debug this => std::ops::Range<usize>{ .0 => _15, .1 => _16, };
                     scope 5 {
                         let _6: usize;
                         scope 6 {
                             debug new_len => _6;
-                            scope 7 (inlined ptr::mut_ptr::<impl *mut [u32]>::as_mut_ptr) {
+                            scope 11 (inlined ptr::mut_ptr::<impl *mut [u32]>::as_mut_ptr) {
                                 debug self => _5;
                             }
-                            scope 8 (inlined ptr::mut_ptr::<impl *mut u32>::add) {
+                            scope 12 (inlined ptr::mut_ptr::<impl *mut u32>::add) {
                                 debug self => _7;
                                 debug count => _3;
-                                scope 9 {
+                                scope 13 {
                                 }
                             }
-                            scope 10 (inlined slice_from_raw_parts_mut::<u32>) {
+                            scope 14 (inlined slice_from_raw_parts_mut::<u32>) {
                                 debug data => _8;
                                 debug len => _6;
                                 let mut _9: *mut ();
-                                scope 11 (inlined ptr::mut_ptr::<impl *mut u32>::cast::<()>) {
+                                scope 15 (inlined ptr::mut_ptr::<impl *mut u32>::cast::<()>) {
                                     debug self => _8;
                                 }
-                                scope 12 (inlined std::ptr::from_raw_parts_mut::<[u32]>) {
+                                scope 16 (inlined std::ptr::from_raw_parts_mut::<[u32]>) {
                                     debug data_address => _9;
                                     debug metadata => _6;
                                     let mut _10: *const ();
                                     let mut _11: std::ptr::metadata::PtrComponents<[u32]>;
                                     let mut _12: std::ptr::metadata::PtrRepr<[u32]>;
-                                    scope 13 {
+                                    scope 17 {
+                                    }
+                                }
+                            }
+                        }
+                        scope 7 (inlined <std::ops::Range<usize> as SliceIndex<[T]>>::get_unchecked_mut::runtime::<u32>) {
+                            debug this => std::ops::Range<usize>{ .0 => _15, .1 => _16, };
+                            debug slice => _5;
+                            scope 8 (inlined ptr::mut_ptr::<impl *mut [u32]>::len) {
+                                debug self => _5;
+                                let mut _14: *const [u32];
+                                scope 9 (inlined std::ptr::metadata::<[u32]>) {
+                                    debug ptr => _14;
+                                    scope 10 {
                                     }
                                 }
                             }
@@ -63,9 +76,10 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range<usize>) ->
         _4 = move (_2.1: usize);
         StorageLive(_5);
         _5 = &raw mut (*_1);
+        StorageLive(_6);
         StorageLive(_14);
         StorageLive(_15);
-        StorageLive(_6);
+        StorageLive(_16);
         _6 = SubUnchecked(_4, _3);
         StorageLive(_8);
         StorageLive(_7);
@@ -86,9 +100,10 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range<usize>) ->
         StorageDead(_12);
         StorageDead(_9);
         StorageDead(_8);
-        StorageDead(_6);
-        StorageDead(_14);
+        StorageDead(_16);
         StorageDead(_15);
+        StorageDead(_14);
+        StorageDead(_6);
         StorageDead(_5);
         _0 = &mut (*_13);
         return;
diff --git a/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-abort.mir
index 4edf4b4fb44..4afe2eda188 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-abort.mir
@@ -75,17 +75,19 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
         _8 = Lt(move _6, move _7);
         StorageDead(_7);
         StorageDead(_6);
-        StorageDead(_22);
-        StorageDead(_21);
         switchInt(move _8) -> [0: bb2, otherwise: bb3];
     }
 
     bb2: {
+        StorageDead(_22);
+        StorageDead(_21);
         _9 = Option::<usize>::None;
         goto -> bb5;
     }
 
     bb3: {
+        StorageDead(_22);
+        StorageDead(_21);
         _10 = (_5.0: usize);
         StorageLive(_11);
         _11 = <usize as Step>::forward_unchecked(_10, const 1_usize) -> [return: bb4, unwind unreachable];
diff --git a/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir
index 8bd072fd625..48092608d9c 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir
@@ -75,17 +75,19 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
         _8 = Lt(move _6, move _7);
         StorageDead(_7);
         StorageDead(_6);
-        StorageDead(_22);
-        StorageDead(_21);
         switchInt(move _8) -> [0: bb2, otherwise: bb3];
     }
 
     bb2: {
+        StorageDead(_22);
+        StorageDead(_21);
         _9 = Option::<usize>::None;
         goto -> bb5;
     }
 
     bb3: {
+        StorageDead(_22);
+        StorageDead(_21);
         _10 = (_5.0: usize);
         StorageLive(_11);
         _11 = <usize as Step>::forward_unchecked(_10, const 1_usize) -> [return: bb4, unwind: bb12];
diff --git a/tests/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.panic-abort.mir b/tests/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.panic-abort.mir
index 70efdbf4b34..566b6af95ba 100644
--- a/tests/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.panic-abort.mir
+++ b/tests/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.panic-abort.mir
@@ -19,17 +19,16 @@ fn array_casts() -> () {
     let mut _18: &usize;
     let _19: usize;
     let mut _22: bool;
-    let mut _23: bool;
+    let mut _23: usize;
     let mut _24: usize;
-    let mut _25: usize;
-    let mut _26: !;
-    let _28: !;
-    let mut _29: core::panicking::AssertKind;
-    let mut _30: &usize;
-    let _31: &usize;
-    let mut _32: &usize;
-    let _33: &usize;
-    let mut _34: std::option::Option<std::fmt::Arguments<'_>>;
+    let mut _25: !;
+    let _27: !;
+    let mut _28: core::panicking::AssertKind;
+    let mut _29: &usize;
+    let _30: &usize;
+    let mut _31: &usize;
+    let _32: &usize;
+    let mut _33: std::option::Option<std::fmt::Arguments<'_>>;
     scope 1 {
         debug x => _1;
         let _2: *mut usize;
@@ -45,15 +44,15 @@ fn array_casts() -> () {
                     debug p => _9;
                     let _20: &usize;
                     let _21: &usize;
-                    let mut _35: &usize;
+                    let mut _34: &usize;
                     scope 6 {
                     }
                     scope 7 {
                         debug left_val => _20;
                         debug right_val => _21;
-                        let _27: core::panicking::AssertKind;
+                        let _26: core::panicking::AssertKind;
                         scope 8 {
-                            debug kind => _27;
+                            debug kind => _26;
                         }
                     }
                 }
@@ -110,9 +109,9 @@ fn array_casts() -> () {
         _15 = (*_16);
         _14 = &_15;
         StorageLive(_18);
-        _35 = const _;
-        Retag(_35);
-        _18 = &(*_35);
+        _34 = const _;
+        Retag(_34);
+        _18 = &(*_34);
         _13 = (move _14, move _18);
         Retag(_13);
         StorageDead(_18);
@@ -125,39 +124,16 @@ fn array_casts() -> () {
         Retag(_21);
         StorageLive(_22);
         StorageLive(_23);
+        _23 = (*_20);
         StorageLive(_24);
-        _24 = (*_20);
-        StorageLive(_25);
-        _25 = (*_21);
-        _23 = Eq(move _24, move _25);
-        StorageDead(_25);
-        StorageDead(_24);
-        _22 = Not(move _23);
-        StorageDead(_23);
+        _24 = (*_21);
+        _22 = Eq(move _23, move _24);
         switchInt(move _22) -> [0: bb4, otherwise: bb3];
     }
 
     bb3: {
-        StorageLive(_27);
-        _27 = core::panicking::AssertKind::Eq;
-        StorageLive(_28);
-        StorageLive(_29);
-        _29 = move _27;
-        StorageLive(_30);
-        StorageLive(_31);
-        _31 = &(*_20);
-        _30 = &(*_31);
-        StorageLive(_32);
-        StorageLive(_33);
-        _33 = &(*_21);
-        _32 = &(*_33);
-        StorageLive(_34);
-        _34 = Option::<Arguments<'_>>::None;
-        Retag(_34);
-        _28 = core::panicking::assert_failed::<usize, usize>(move _29, move _30, move _32, move _34) -> unwind unreachable;
-    }
-
-    bb4: {
+        StorageDead(_24);
+        StorageDead(_23);
         _12 = const ();
         StorageDead(_22);
         StorageDead(_21);
@@ -173,4 +149,26 @@ fn array_casts() -> () {
         StorageDead(_1);
         return;
     }
+
+    bb4: {
+        StorageDead(_24);
+        StorageDead(_23);
+        StorageLive(_26);
+        _26 = core::panicking::AssertKind::Eq;
+        StorageLive(_27);
+        StorageLive(_28);
+        _28 = move _26;
+        StorageLive(_29);
+        StorageLive(_30);
+        _30 = &(*_20);
+        _29 = &(*_30);
+        StorageLive(_31);
+        StorageLive(_32);
+        _32 = &(*_21);
+        _31 = &(*_32);
+        StorageLive(_33);
+        _33 = Option::<Arguments<'_>>::None;
+        Retag(_33);
+        _27 = core::panicking::assert_failed::<usize, usize>(move _28, move _29, move _31, move _33) -> unwind unreachable;
+    }
 }
diff --git a/tests/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.panic-unwind.mir b/tests/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.panic-unwind.mir
index cfa9628d498..d0d3176320b 100644
--- a/tests/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.panic-unwind.mir
+++ b/tests/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.panic-unwind.mir
@@ -19,17 +19,16 @@ fn array_casts() -> () {
     let mut _18: &usize;
     let _19: usize;
     let mut _22: bool;
-    let mut _23: bool;
+    let mut _23: usize;
     let mut _24: usize;
-    let mut _25: usize;
-    let mut _26: !;
-    let _28: !;
-    let mut _29: core::panicking::AssertKind;
-    let mut _30: &usize;
-    let _31: &usize;
-    let mut _32: &usize;
-    let _33: &usize;
-    let mut _34: std::option::Option<std::fmt::Arguments<'_>>;
+    let mut _25: !;
+    let _27: !;
+    let mut _28: core::panicking::AssertKind;
+    let mut _29: &usize;
+    let _30: &usize;
+    let mut _31: &usize;
+    let _32: &usize;
+    let mut _33: std::option::Option<std::fmt::Arguments<'_>>;
     scope 1 {
         debug x => _1;
         let _2: *mut usize;
@@ -45,15 +44,15 @@ fn array_casts() -> () {
                     debug p => _9;
                     let _20: &usize;
                     let _21: &usize;
-                    let mut _35: &usize;
+                    let mut _34: &usize;
                     scope 6 {
                     }
                     scope 7 {
                         debug left_val => _20;
                         debug right_val => _21;
-                        let _27: core::panicking::AssertKind;
+                        let _26: core::panicking::AssertKind;
                         scope 8 {
-                            debug kind => _27;
+                            debug kind => _26;
                         }
                     }
                 }
@@ -110,9 +109,9 @@ fn array_casts() -> () {
         _15 = (*_16);
         _14 = &_15;
         StorageLive(_18);
-        _35 = const _;
-        Retag(_35);
-        _18 = &(*_35);
+        _34 = const _;
+        Retag(_34);
+        _18 = &(*_34);
         _13 = (move _14, move _18);
         Retag(_13);
         StorageDead(_18);
@@ -125,39 +124,16 @@ fn array_casts() -> () {
         Retag(_21);
         StorageLive(_22);
         StorageLive(_23);
+        _23 = (*_20);
         StorageLive(_24);
-        _24 = (*_20);
-        StorageLive(_25);
-        _25 = (*_21);
-        _23 = Eq(move _24, move _25);
-        StorageDead(_25);
-        StorageDead(_24);
-        _22 = Not(move _23);
-        StorageDead(_23);
+        _24 = (*_21);
+        _22 = Eq(move _23, move _24);
         switchInt(move _22) -> [0: bb4, otherwise: bb3];
     }
 
     bb3: {
-        StorageLive(_27);
-        _27 = core::panicking::AssertKind::Eq;
-        StorageLive(_28);
-        StorageLive(_29);
-        _29 = move _27;
-        StorageLive(_30);
-        StorageLive(_31);
-        _31 = &(*_20);
-        _30 = &(*_31);
-        StorageLive(_32);
-        StorageLive(_33);
-        _33 = &(*_21);
-        _32 = &(*_33);
-        StorageLive(_34);
-        _34 = Option::<Arguments<'_>>::None;
-        Retag(_34);
-        _28 = core::panicking::assert_failed::<usize, usize>(move _29, move _30, move _32, move _34) -> unwind continue;
-    }
-
-    bb4: {
+        StorageDead(_24);
+        StorageDead(_23);
         _12 = const ();
         StorageDead(_22);
         StorageDead(_21);
@@ -173,4 +149,26 @@ fn array_casts() -> () {
         StorageDead(_1);
         return;
     }
+
+    bb4: {
+        StorageDead(_24);
+        StorageDead(_23);
+        StorageLive(_26);
+        _26 = core::panicking::AssertKind::Eq;
+        StorageLive(_27);
+        StorageLive(_28);
+        _28 = move _26;
+        StorageLive(_29);
+        StorageLive(_30);
+        _30 = &(*_20);
+        _29 = &(*_30);
+        StorageLive(_31);
+        StorageLive(_32);
+        _32 = &(*_21);
+        _31 = &(*_32);
+        StorageLive(_33);
+        _33 = Option::<Arguments<'_>>::None;
+        Retag(_33);
+        _27 = core::panicking::assert_failed::<usize, usize>(move _28, move _29, move _31, move _33) -> unwind continue;
+    }
 }
diff --git a/tests/run-coverage/lazy_boolean.coverage b/tests/run-coverage/lazy_boolean.coverage
index 2d927a08356..8f14082ef68 100644
--- a/tests/run-coverage/lazy_boolean.coverage
+++ b/tests/run-coverage/lazy_boolean.coverage
@@ -32,7 +32,7 @@
                                           ^0
    LL|       |
    LL|       |    if
-   LL|      1|        !
+   LL|       |        !
    LL|      1|        is_true
    LL|      0|    {
    LL|      0|        a = 2
diff --git a/tests/rustdoc-gui/sidebar.goml b/tests/rustdoc-gui/sidebar.goml
index 913d72932b9..520481d3bba 100644
--- a/tests/rustdoc-gui/sidebar.goml
+++ b/tests/rustdoc-gui/sidebar.goml
@@ -25,24 +25,24 @@ call-function: (
     "check-colors",
     {
         "theme": "ayu",
-        "color": "rgb(197, 197, 197)",
-        "background_color": "rgb(20, 25, 31)",
+        "color": "#c5c5c5",
+        "background_color": "#14191f",
     }
 )
 call-function: (
     "check-colors",
     {
         "theme": "dark",
-        "color": "rgb(221, 221, 221)",
-        "background_color": "rgb(80, 80, 80)",
+        "color": "#ddd",
+        "background_color": "#505050",
     }
 )
 call-function: (
     "check-colors",
     {
         "theme": "light",
-        "color": "rgb(0, 0, 0)",
-        "background_color": "rgb(245, 245, 245)",
+        "color": "black",
+        "background_color": "#f5f5f5",
     }
 )
 
@@ -55,7 +55,7 @@ assert-text: (".sidebar > .location", "Crate test_docs")
 assert-count: (".sidebar .location", 1)
 assert-count: (".sidebar h2", 1)
 assert-text: ("#all-types", "All Items")
-assert-css: ("#all-types", {"color": "rgb(53, 109, 164)"})
+assert-css: ("#all-types", {"color": "#356da4"})
 // We check that we have the crates list and that the "current" on is "test_docs".
 assert-text: (".sidebar-elems ul.crate > li > a.current", "test_docs")
 // And we're also supposed to have the list of items in the current module.
@@ -88,7 +88,7 @@ assert-property: ("html", {"scrollTop": "0"})
 // We now go back to the crate page to click on the "lib2" crate link.
 go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
 assert-property: (".sidebar", {"clientWidth": "200"})
-assert-css: (".sidebar-elems ul.crate > li:first-child > a", {"color": "rgb(53, 109, 164)"})
+assert-css: (".sidebar-elems ul.crate > li:first-child > a", {"color": "#356da4"})
 click: ".sidebar-elems ul.crate > li:first-child > a"
 
 // PAGE: lib2/index.html
@@ -140,7 +140,7 @@ go-to: "file://" + |DOC_PATH| + "/test_docs/struct.Foo.html"
 assert-property: (".sidebar", {"clientWidth": "200"})
 click: "//ul[@class='block mod']/preceding-sibling::h3/a"
 // PAGE: index.html
-assert-css: ("#modules", {"background-color": "rgb(253, 255, 211)"})
+assert-css: ("#modules", {"background-color": "#fdffd3"})
 
 // Finally, assert that the `[+]/[−]` toggle doesn't affect sidebar width.
 click: "#toggle-all-docs"
diff --git a/tests/rustdoc-js-std/full-path-function.js b/tests/rustdoc-js-std/full-path-function.js
new file mode 100644
index 00000000000..ac157b3aadf
--- /dev/null
+++ b/tests/rustdoc-js-std/full-path-function.js
@@ -0,0 +1,7 @@
+const EXPECTED = {
+    'query': 'vec::vec -> usize',
+    'others': [
+        { 'path': 'std::vec::Vec', 'name': 'len' },
+        { 'path': 'std::vec::Vec', 'name': 'capacity' },
+    ],
+};
diff --git a/tests/rustdoc-js/full-path-function.js b/tests/rustdoc-js/full-path-function.js
new file mode 100644
index 00000000000..48be51b156f
--- /dev/null
+++ b/tests/rustdoc-js/full-path-function.js
@@ -0,0 +1,43 @@
+// exact-check
+
+const EXPECTED = [
+    {
+        'query': 'sac -> usize',
+        'others': [
+            { 'path': 'full_path_function::b::Sac', 'name': 'bar' },
+            { 'path': 'full_path_function::b::Sac', 'name': 'len' },
+            { 'path': 'full_path_function::sac::Sac', 'name': 'len' },
+        ],
+    },
+    {
+        'query': 'b::sac -> usize',
+        'others': [
+            { 'path': 'full_path_function::b::Sac', 'name': 'bar' },
+            { 'path': 'full_path_function::b::Sac', 'name': 'len' },
+        ],
+    },
+    {
+        'query': 'b::sac -> u32',
+        'others': [
+            { 'path': 'full_path_function::b::Sac', 'name': 'bar2' },
+        ],
+    },
+    {
+        'query': 'string::string -> u32',
+        'others': [
+            { 'path': 'full_path_function::b::Sac', 'name': 'string' },
+        ],
+    },
+    {
+        'query': 'alloc::string::string -> u32',
+        'others': [
+            { 'path': 'full_path_function::b::Sac', 'name': 'string' },
+        ],
+    },
+    {
+        'query': 'alloc::string -> u32',
+        'others': [
+            { 'path': 'full_path_function::b::Sac', 'name': 'string' },
+        ],
+    },
+];
diff --git a/tests/rustdoc-js/full-path-function.rs b/tests/rustdoc-js/full-path-function.rs
new file mode 100644
index 00000000000..8dcc3f2b69d
--- /dev/null
+++ b/tests/rustdoc-js/full-path-function.rs
@@ -0,0 +1,17 @@
+pub mod sac {
+    pub struct Sac;
+
+    impl Sac {
+        pub fn len(&self) -> usize { 0 }
+    }
+}
+
+pub mod b {
+    pub struct Sac;
+    impl Sac {
+        pub fn len(&self) -> usize { 0 }
+        pub fn bar(&self, w: u32) -> usize { 0 }
+        pub fn bar2(&self, w: u32) -> u32 { 0 }
+        pub fn string(w: String) -> u32 { 0 }
+    }
+}
diff --git a/tests/rustdoc/inline_cross/auxiliary/dyn_trait.rs b/tests/rustdoc/inline_cross/auxiliary/dyn_trait.rs
index 644d0699e9d..df88530071b 100644
--- a/tests/rustdoc/inline_cross/auxiliary/dyn_trait.rs
+++ b/tests/rustdoc/inline_cross/auxiliary/dyn_trait.rs
@@ -65,3 +65,22 @@ pub trait HigherRankedBoundTrait1<'e> where for<'l> Self: 'e + 'l {}
 pub trait AmbiguousBoundTrait<'a, 'b>: 'a + 'b {}
 
 pub struct AmbiguousBoundWrapper<'a, 'b, T: ?Sized + 'a + 'b>(&'a T, &'b T);
+
+// Trait objects inside of another trait object, a trait bound or an associated type.
+
+pub trait Inner {}
+pub trait Outer<T: ?Sized> {}
+pub trait Base {
+    type Type<T: ?Sized>;
+}
+impl Base for () {
+    type Type<T: ?Sized> = ();
+}
+
+pub type NestedTraitObjects = dyn Outer<dyn Inner>;
+
+pub fn apit_rpit(o: impl Outer<dyn Inner>) -> impl Outer<dyn Inner> {
+    o
+}
+
+pub type AssocTy = <() as Base>::Type<dyn Inner>;
diff --git a/tests/rustdoc/inline_cross/dyn_trait.rs b/tests/rustdoc/inline_cross/dyn_trait.rs
index 1de01af83d1..679972f035a 100644
--- a/tests/rustdoc/inline_cross/dyn_trait.rs
+++ b/tests/rustdoc/inline_cross/dyn_trait.rs
@@ -128,3 +128,18 @@ pub use dyn_trait::BareAmbiguousBoundEarly1;
 // @has user/type.BareAmbiguousBoundStatic.html
 // @has - '//*[@class="rust item-decl"]//code' "dyn AmbiguousBoundTrait<'o, 'o> + 'static;"
 pub use dyn_trait::BareAmbiguousBoundStatic;
+
+// Regression test for issue #115179:
+
+// @has user/type.NestedTraitObjects.html
+// @has - '//*[@class="rust item-decl"]//code' "dyn Outer<dyn Inner>;"
+pub use dyn_trait::NestedTraitObjects;
+
+// @has user/fn.apit_rpit.html
+// @has - '//pre[@class="rust item-decl"]' \
+//     "apit_rpit(o: impl Outer<dyn Inner>) -> impl Outer<dyn Inner>"
+pub use dyn_trait::apit_rpit;
+
+// @has user/type.AssocTy.html
+// @has - '//*[@class="rust item-decl"]//code' "<() as Base>::Type<dyn Inner>"
+pub use dyn_trait::AssocTy;
diff --git a/tests/rustdoc/show-const-contents.rs b/tests/rustdoc/show-const-contents.rs
index 69e742ee747..91df03adbbc 100644
--- a/tests/rustdoc/show-const-contents.rs
+++ b/tests/rustdoc/show-const-contents.rs
@@ -47,7 +47,7 @@ pub struct MyTypeWithStr(&'static str);
 // @!hasraw show_const_contents/constant.MY_TYPE_WITH_STR.html '; //'
 pub const MY_TYPE_WITH_STR: MyTypeWithStr = MyTypeWithStr("show this");
 
-// @hasraw show_const_contents/constant.PI.html '= 3.14159265358979323846264338327950288f32;'
+// @hasraw show_const_contents/constant.PI.html '= 3.14159265358979323846264338327950288_f32;'
 // @hasraw show_const_contents/constant.PI.html '; // 3.14159274f32'
 pub use std::f32::consts::PI;
 
diff --git a/tests/ui/argument-suggestions/two-mismatch-notes.stderr b/tests/ui/argument-suggestions/two-mismatch-notes.stderr
index 38cf23ddc38..70cc60255c7 100644
--- a/tests/ui/argument-suggestions/two-mismatch-notes.stderr
+++ b/tests/ui/argument-suggestions/two-mismatch-notes.stderr
@@ -11,7 +11,6 @@ LL |     foo(f, w);
    |         ^
    = note: expected fn pointer `fn(i32)`
                  found fn item `fn(u32) {f}`
-   = note: when the arguments and return types match, functions can be coerced to function pointers
 note: expected `Wrapper<i32>`, found `Wrapper<isize>`
   --> $DIR/two-mismatch-notes.rs:10:12
    |
diff --git a/tests/ui/associated-consts/double-elided.rs b/tests/ui/associated-consts/double-elided.rs
new file mode 100644
index 00000000000..fd0317781bb
--- /dev/null
+++ b/tests/ui/associated-consts/double-elided.rs
@@ -0,0 +1,12 @@
+struct S;
+
+impl S {
+    const C: &&str = &"";
+    //~^ WARN `&` without an explicit lifetime name cannot be used here
+    //~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+    //~| WARN `&` without an explicit lifetime name cannot be used here
+    //~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+    //~| ERROR in type `&&str`, reference has a longer lifetime than the data it references
+}
+
+fn main() {}
diff --git a/tests/ui/associated-consts/double-elided.stderr b/tests/ui/associated-consts/double-elided.stderr
new file mode 100644
index 00000000000..ba4e6a23e27
--- /dev/null
+++ b/tests/ui/associated-consts/double-elided.stderr
@@ -0,0 +1,47 @@
+warning: `&` without an explicit lifetime name cannot be used here
+  --> $DIR/double-elided.rs:4:14
+   |
+LL |     const C: &&str = &"";
+   |              ^
+   |
+   = 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 #115010 <https://github.com/rust-lang/rust/issues/115010>
+   = note: `#[warn(elided_lifetimes_in_associated_constant)]` on by default
+help: use the `'static` lifetime
+   |
+LL |     const C: &'static &str = &"";
+   |               +++++++
+
+warning: `&` without an explicit lifetime name cannot be used here
+  --> $DIR/double-elided.rs:4:15
+   |
+LL |     const C: &&str = &"";
+   |               ^
+   |
+   = 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 #115010 <https://github.com/rust-lang/rust/issues/115010>
+help: use the `'static` lifetime
+   |
+LL |     const C: &&'static str = &"";
+   |                +++++++
+
+error[E0491]: in type `&&str`, reference has a longer lifetime than the data it references
+  --> $DIR/double-elided.rs:4:5
+   |
+LL |     const C: &&str = &"";
+   |     ^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the pointer is valid for the anonymous lifetime as defined here
+  --> $DIR/double-elided.rs:4:14
+   |
+LL |     const C: &&str = &"";
+   |              ^
+note: but the referenced data is only valid for the anonymous lifetime as defined here
+  --> $DIR/double-elided.rs:4:14
+   |
+LL |     const C: &&str = &"";
+   |              ^
+
+error: aborting due to previous error; 2 warnings emitted
+
+For more information about this error, try `rustc --explain E0491`.
diff --git a/tests/ui/associated-inherent-types/private-in-public.rs b/tests/ui/associated-inherent-types/private-in-public.rs
index e9e189f95c9..7797a2a16a5 100644
--- a/tests/ui/associated-inherent-types/private-in-public.rs
+++ b/tests/ui/associated-inherent-types/private-in-public.rs
@@ -1,26 +1,15 @@
+// check-pass
+
 #![feature(inherent_associated_types)]
-#![feature(type_privacy_lints)]
 #![allow(incomplete_features)]
 #![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)
-//~| WARNING this was previously accepted
-//~| WARNING associated type `PubTy::PrivAssocTy` is more private than the item `PubAlias0`
+//~^ WARNING associated type `PubTy::PrivAssocTy` is more private than the item `PubAlias0`
 pub type PubAlias1 = PrivTy::PubAssocTy;
-//~^ ERROR private type `PrivTy` in public interface (error E0446)
-//~| WARNING this was previously accepted
-//~| WARNING type `PrivTy` is more private than the item `PubAlias1`
+//~^ WARNING type `PrivTy` is more private than the item `PubAlias1`
 pub type PubAlias2 = PubTy::PubAssocTy<PrivTy>;
-//~^ ERROR private type `PrivTy` in public interface (error E0446)
-//~| WARNING this was previously accepted
-//~| WARNING type `PrivTy` is more private than the item `PubAlias2`
+//~^ WARNING type `PrivTy` is more private than the item `PubAlias2`
 
 pub struct PubTy;
 impl PubTy {
diff --git a/tests/ui/associated-inherent-types/private-in-public.stderr b/tests/ui/associated-inherent-types/private-in-public.stderr
index 65d187c1bcd..076bbd78ae9 100644
--- a/tests/ui/associated-inherent-types/private-in-public.stderr
+++ b/tests/ui/associated-inherent-types/private-in-public.stderr
@@ -1,75 +1,39 @@
-error: private associated type `PubTy::PrivAssocTy` in public interface (error E0446)
-  --> $DIR/private-in-public.rs:12:1
-   |
-LL | pub type PubAlias0 = PubTy::PrivAssocTy;
-   | ^^^^^^^^^^^^^^^^^^
-   |
-   = 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>
-note: the lint level is defined here
-  --> $DIR/private-in-public.rs:5:9
-   |
-LL | #![deny(private_in_public)]
-   |         ^^^^^^^^^^^^^^^^^
-
 warning: associated type `PubTy::PrivAssocTy` is more private than the item `PubAlias0`
-  --> $DIR/private-in-public.rs:12:1
+  --> $DIR/private-in-public.rs:7:1
    |
 LL | pub type PubAlias0 = PubTy::PrivAssocTy;
    | ^^^^^^^^^^^^^^^^^^ type alias `PubAlias0` is reachable at visibility `pub`
    |
 note: but associated type `PubTy::PrivAssocTy` is only usable at visibility `pub(crate)`
-  --> $DIR/private-in-public.rs:27:5
+  --> $DIR/private-in-public.rs:16: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:16:1
-   |
-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>
+   = note: `#[warn(private_interfaces)]` on by default
 
 warning: type `PrivTy` is more private than the item `PubAlias1`
-  --> $DIR/private-in-public.rs:16:1
+  --> $DIR/private-in-public.rs:9:1
    |
 LL | pub type PubAlias1 = PrivTy::PubAssocTy;
    | ^^^^^^^^^^^^^^^^^^ type alias `PubAlias1` is reachable at visibility `pub`
    |
 note: but type `PrivTy` is only usable at visibility `pub(crate)`
-  --> $DIR/private-in-public.rs:31:1
+  --> $DIR/private-in-public.rs:20:1
    |
 LL | struct PrivTy;
    | ^^^^^^^^^^^^^
 
-error: private type `PrivTy` in public interface (error E0446)
-  --> $DIR/private-in-public.rs:20:1
-   |
-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>
-
 warning: type `PrivTy` is more private than the item `PubAlias2`
-  --> $DIR/private-in-public.rs:20:1
+  --> $DIR/private-in-public.rs:11:1
    |
 LL | pub type PubAlias2 = PubTy::PubAssocTy<PrivTy>;
    | ^^^^^^^^^^^^^^^^^^ type alias `PubAlias2` is reachable at visibility `pub`
    |
 note: but type `PrivTy` is only usable at visibility `pub(crate)`
-  --> $DIR/private-in-public.rs:31:1
+  --> $DIR/private-in-public.rs:20:1
    |
 LL | struct PrivTy;
    | ^^^^^^^^^^^^^
 
-error: aborting due to 3 previous errors; 3 warnings emitted
+warning: 3 warnings emitted
 
diff --git a/tests/ui/attributes/issue-115264-expr-field.rs b/tests/ui/attributes/issue-115264-expr-field.rs
new file mode 100644
index 00000000000..f53ac4aee66
--- /dev/null
+++ b/tests/ui/attributes/issue-115264-expr-field.rs
@@ -0,0 +1,17 @@
+// Regression test for issue 115264
+// Tests that retrieving the ident of the X::foo field
+// in main() does not cause an ICE
+
+// check-pass
+
+#[allow(dead_code)]
+struct X {
+    foo: i32,
+}
+
+fn main() {
+    let _ = X {
+        #[doc(alias = "StructItem")]
+        foo: 123,
+    };
+}
diff --git a/tests/ui/attributes/issue-115264-pat-field.rs b/tests/ui/attributes/issue-115264-pat-field.rs
new file mode 100644
index 00000000000..8c6bbe16726
--- /dev/null
+++ b/tests/ui/attributes/issue-115264-pat-field.rs
@@ -0,0 +1,19 @@
+// Regression test for issue 115264
+// Tests that retrieving the ident of 'foo' variable in
+// the pattern inside main() does not cause an ICE
+
+// check-pass
+
+struct X {
+    foo: i32,
+}
+
+#[allow(unused_variables)]
+fn main() {
+    let X {
+        #[doc(alias = "StructItem")]
+        foo
+    } = X {
+        foo: 123
+    };
+}
diff --git a/tests/ui/c-variadic/variadic-ffi-1.stderr b/tests/ui/c-variadic/variadic-ffi-1.stderr
index c7899338197..4beea83d8a5 100644
--- a/tests/ui/c-variadic/variadic-ffi-1.stderr
+++ b/tests/ui/c-variadic/variadic-ffi-1.stderr
@@ -46,7 +46,6 @@ LL |         let x: unsafe extern "C" fn(f: isize, x: u8) = foo;
    |
    = note: expected fn pointer `unsafe extern "C" fn(_, _)`
                  found fn item `unsafe extern "C" fn(_, _, ...) {foo}`
-   = note: when the arguments and return types match, functions can be coerced to function pointers
 
 error[E0308]: mismatched types
   --> $DIR/variadic-ffi-1.rs:26:54
@@ -58,7 +57,6 @@ LL |         let y: extern "C" fn(f: isize, x: u8, ...) = bar;
    |
    = note: expected fn pointer `extern "C" fn(_, _, ...)`
                  found fn item `extern "C" fn(_, _) {bar}`
-   = note: when the arguments and return types match, functions can be coerced to function pointers
 
 error[E0617]: can't pass `f32` to variadic function
   --> $DIR/variadic-ffi-1.rs:28:19
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 e5464a4253f..8023b998a40 100644
--- a/tests/ui/const-generics/generic_const_exprs/eval-privacy.rs
+++ b/tests/ui/const-generics/generic_const_exprs/eval-privacy.rs
@@ -1,12 +1,6 @@
 #![crate_type = "lib"]
 #![feature(generic_const_exprs)]
-#![feature(type_privacy_lints)]
 #![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>;
 
@@ -21,7 +15,6 @@ where
 {
     type AssocTy = Const<{ my_const_fn(U) }>;
     //~^ ERROR private type
-    //~| WARNING type `fn(u8) -> u8 {my_const_fn}` is more private than the item `<Const<U> as Trait>::AssocTy`
     fn assoc_fn() -> Self::AssocTy {
         Const
     }
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 16fae6b5c63..2d9de8805bb 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:22:5
+  --> $DIR/eval-privacy.rs:16:5
    |
 LL |     type AssocTy = Const<{ my_const_fn(U) }>;
    |     ^^^^^^^^^^^^ can't leak private type
@@ -7,23 +7,6 @@ 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
 
-warning: type `fn(u8) -> u8 {my_const_fn}` is more private than the item `<Const<U> as Trait>::AssocTy`
-  --> $DIR/eval-privacy.rs:22:5
-   |
-LL |     type AssocTy = Const<{ my_const_fn(U) }>;
-   |     ^^^^^^^^^^^^ associated type `<Const<U> as Trait>::AssocTy` is reachable at visibility `pub`
-   |
-note: but type `fn(u8) -> u8 {my_const_fn}` is only usable at visibility `pub(crate)`
-  --> $DIR/eval-privacy.rs:30: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
+error: aborting due to previous error
 
 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
deleted file mode 100644
index 9f29c81673e..00000000000
--- a/tests/ui/error-codes/E0445.rs
+++ /dev/null
@@ -1,23 +0,0 @@
-#![feature(type_privacy_lints)]
-#[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) { }
-}
-
-pub trait Bar : Foo {}
-//~^ ERROR private trait `Foo` in public interface [E0445]
-//~| WARNING trait `Foo` is more private than the item `Bar`
-pub struct Bar2<T: Foo>(pub T);
-//~^ ERROR private trait `Foo` in public interface [E0445]
-//~| WARNING trait `Foo` is more private than the item `Bar2`
-pub fn foo<T: Foo> (t: T) {}
-//~^ ERROR private trait `Foo` in public interface [E0445]
-//~| WARNING trait `Foo` is more private than the item `foo`
-
-fn main() {}
diff --git a/tests/ui/error-codes/E0445.stderr b/tests/ui/error-codes/E0445.stderr
deleted file mode 100644
index 4f940868ff9..00000000000
--- a/tests/ui/error-codes/E0445.stderr
+++ /dev/null
@@ -1,71 +0,0 @@
-error[E0445]: private trait `Foo` in public interface
-  --> $DIR/E0445.rs:13:1
-   |
-LL | trait Foo {
-   | --------- `Foo` declared as private
-...
-LL | pub trait Bar : Foo {}
-   | ^^^^^^^^^^^^^^^^^^^ can't leak private trait
-
-warning: trait `Foo` is more private than the item `Bar`
-  --> $DIR/E0445.rs:13:1
-   |
-LL | pub trait Bar : Foo {}
-   | ^^^^^^^^^^^^^^^^^^^ trait `Bar` is reachable at visibility `pub`
-   |
-note: but trait `Foo` is only usable at visibility `pub(crate)`
-  --> $DIR/E0445.rs:9:1
-   |
-LL | trait Foo {
-   | ^^^^^^^^^
-note: the lint level is defined here
-  --> $DIR/E0445.rs:2:8
-   |
-LL | #[warn(private_bounds)]
-   |        ^^^^^^^^^^^^^^
-
-error[E0445]: private trait `Foo` in public interface
-  --> $DIR/E0445.rs:16:1
-   |
-LL | trait Foo {
-   | --------- `Foo` declared as private
-...
-LL | pub struct Bar2<T: Foo>(pub T);
-   | ^^^^^^^^^^^^^^^^^^^^^^^ can't leak private trait
-
-warning: trait `Foo` is more private than the item `Bar2`
-  --> $DIR/E0445.rs:16:1
-   |
-LL | pub struct Bar2<T: Foo>(pub T);
-   | ^^^^^^^^^^^^^^^^^^^^^^^ struct `Bar2` is reachable at visibility `pub`
-   |
-note: but trait `Foo` is only usable at visibility `pub(crate)`
-  --> $DIR/E0445.rs:9:1
-   |
-LL | trait Foo {
-   | ^^^^^^^^^
-
-error[E0445]: private trait `Foo` in public interface
-  --> $DIR/E0445.rs:19:1
-   |
-LL | trait Foo {
-   | --------- `Foo` declared as private
-...
-LL | pub fn foo<T: Foo> (t: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private trait
-
-warning: trait `Foo` is more private than the item `foo`
-  --> $DIR/E0445.rs:19:1
-   |
-LL | pub fn foo<T: Foo> (t: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^ function `foo` is reachable at visibility `pub`
-   |
-note: but trait `Foo` is only usable at visibility `pub(crate)`
-  --> $DIR/E0445.rs:9: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/error-codes/E0446.rs b/tests/ui/error-codes/E0446.rs
index f61c7e54616..6d6c4f97c06 100644
--- a/tests/ui/error-codes/E0446.rs
+++ b/tests/ui/error-codes/E0446.rs
@@ -1,9 +1,14 @@
-mod foo {
-    struct Bar(u32);
+struct Bar;
+trait PrivTr {}
 
-    pub fn bar() -> Bar { //~ ERROR E0446
-        Bar(0)
-    }
+pub trait PubTr {
+    type Alias1;
+    type Alias2;
+}
+
+impl PubTr for u8 {
+    type Alias1 = Bar; //~ ERROR E0446
+    type Alias2 = Box<dyn PrivTr>; //~ ERROR E0446
 }
 
 fn main() {}
diff --git a/tests/ui/error-codes/E0446.stderr b/tests/ui/error-codes/E0446.stderr
index b6a195c40a9..2951e69d1c2 100644
--- a/tests/ui/error-codes/E0446.stderr
+++ b/tests/ui/error-codes/E0446.stderr
@@ -1,12 +1,21 @@
 error[E0446]: private type `Bar` in public interface
-  --> $DIR/E0446.rs:4:5
+  --> $DIR/E0446.rs:10:5
    |
-LL |     struct Bar(u32);
-   |     ---------- `Bar` declared as private
-LL |
-LL |     pub fn bar() -> Bar {
-   |     ^^^^^^^^^^^^^^^^^^^ can't leak private type
+LL | struct Bar;
+   | ---------- `Bar` declared as private
+...
+LL |     type Alias1 = Bar;
+   |     ^^^^^^^^^^^ can't leak private type
 
-error: aborting due to previous error
+error[E0446]: private trait `PrivTr` in public interface
+  --> $DIR/E0446.rs:11:5
+   |
+LL | trait PrivTr {}
+   | ------------ `PrivTr` declared as private
+...
+LL |     type Alias2 = Box<dyn PrivTr>;
+   |     ^^^^^^^^^^^ can't leak private trait
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0446`.
diff --git a/tests/ui/feature-gates/feature-gate-type_privacy_lints.rs b/tests/ui/feature-gates/feature-gate-type_privacy_lints.rs
index aad64c9d073..8bb9736f1b4 100644
--- a/tests/ui/feature-gates/feature-gate-type_privacy_lints.rs
+++ b/tests/ui/feature-gates/feature-gate-type_privacy_lints.rs
@@ -1,11 +1,5 @@
 // check-pass
 
-#![warn(private_interfaces)] //~ WARN unknown lint
-                             //~| WARN unknown lint
-                             //~| WARN unknown lint
-#![warn(private_bounds)] //~ WARN unknown lint
-                         //~| WARN unknown lint
-                         //~| WARN unknown lint
 #![warn(unnameable_types)] //~ WARN unknown lint
                            //~| WARN unknown lint
                            //~| WARN unknown lint
diff --git a/tests/ui/feature-gates/feature-gate-type_privacy_lints.stderr b/tests/ui/feature-gates/feature-gate-type_privacy_lints.stderr
index 79cc974cca1..4349fea6f89 100644
--- a/tests/ui/feature-gates/feature-gate-type_privacy_lints.stderr
+++ b/tests/ui/feature-gates/feature-gate-type_privacy_lints.stderr
@@ -1,26 +1,5 @@
-warning: unknown lint: `private_interfaces`
-  --> $DIR/feature-gate-type_privacy_lints.rs:3:1
-   |
-LL | #![warn(private_interfaces)]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: the `private_interfaces` lint is unstable
-   = note: see issue #48054 <https://github.com/rust-lang/rust/issues/48054> for more information
-   = help: add `#![feature(type_privacy_lints)]` to the crate attributes to enable
-   = note: `#[warn(unknown_lints)]` on by default
-
-warning: unknown lint: `private_bounds`
-  --> $DIR/feature-gate-type_privacy_lints.rs:6:1
-   |
-LL | #![warn(private_bounds)]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: the `private_bounds` lint is unstable
-   = note: see issue #48054 <https://github.com/rust-lang/rust/issues/48054> for more information
-   = help: add `#![feature(type_privacy_lints)]` to the crate attributes to enable
-
 warning: unknown lint: `unnameable_types`
-  --> $DIR/feature-gate-type_privacy_lints.rs:9:1
+  --> $DIR/feature-gate-type_privacy_lints.rs:3:1
    |
 LL | #![warn(unnameable_types)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -28,29 +7,10 @@ LL | #![warn(unnameable_types)]
    = note: the `unnameable_types` lint is unstable
    = note: see issue #48054 <https://github.com/rust-lang/rust/issues/48054> for more information
    = help: add `#![feature(type_privacy_lints)]` to the crate attributes to enable
-
-warning: unknown lint: `private_interfaces`
-  --> $DIR/feature-gate-type_privacy_lints.rs:3:1
-   |
-LL | #![warn(private_interfaces)]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: the `private_interfaces` lint is unstable
-   = note: see issue #48054 <https://github.com/rust-lang/rust/issues/48054> for more information
-   = help: add `#![feature(type_privacy_lints)]` to the crate attributes to enable
-
-warning: unknown lint: `private_bounds`
-  --> $DIR/feature-gate-type_privacy_lints.rs:6:1
-   |
-LL | #![warn(private_bounds)]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: the `private_bounds` lint is unstable
-   = note: see issue #48054 <https://github.com/rust-lang/rust/issues/48054> for more information
-   = help: add `#![feature(type_privacy_lints)]` to the crate attributes to enable
+   = note: `#[warn(unknown_lints)]` on by default
 
 warning: unknown lint: `unnameable_types`
-  --> $DIR/feature-gate-type_privacy_lints.rs:9:1
+  --> $DIR/feature-gate-type_privacy_lints.rs:3:1
    |
 LL | #![warn(unnameable_types)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -59,28 +19,8 @@ LL | #![warn(unnameable_types)]
    = note: see issue #48054 <https://github.com/rust-lang/rust/issues/48054> for more information
    = help: add `#![feature(type_privacy_lints)]` to the crate attributes to enable
 
-warning: unknown lint: `private_interfaces`
-  --> $DIR/feature-gate-type_privacy_lints.rs:3:1
-   |
-LL | #![warn(private_interfaces)]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: the `private_interfaces` lint is unstable
-   = note: see issue #48054 <https://github.com/rust-lang/rust/issues/48054> for more information
-   = help: add `#![feature(type_privacy_lints)]` to the crate attributes to enable
-
-warning: unknown lint: `private_bounds`
-  --> $DIR/feature-gate-type_privacy_lints.rs:6:1
-   |
-LL | #![warn(private_bounds)]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: the `private_bounds` lint is unstable
-   = note: see issue #48054 <https://github.com/rust-lang/rust/issues/48054> for more information
-   = help: add `#![feature(type_privacy_lints)]` to the crate attributes to enable
-
 warning: unknown lint: `unnameable_types`
-  --> $DIR/feature-gate-type_privacy_lints.rs:9:1
+  --> $DIR/feature-gate-type_privacy_lints.rs:3:1
    |
 LL | #![warn(unnameable_types)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -89,5 +29,5 @@ LL | #![warn(unnameable_types)]
    = note: see issue #48054 <https://github.com/rust-lang/rust/issues/48054> for more information
    = help: add `#![feature(type_privacy_lints)]` to the crate attributes to enable
 
-warning: 9 warnings emitted
+warning: 3 warnings emitted
 
diff --git a/tests/ui/fn/fn-pointer-mismatch.stderr b/tests/ui/fn/fn-pointer-mismatch.stderr
index a674babcb32..87ece845b83 100644
--- a/tests/ui/fn/fn-pointer-mismatch.stderr
+++ b/tests/ui/fn/fn-pointer-mismatch.stderr
@@ -80,7 +80,6 @@ LL |     let e: &fn(u32) -> u32 = &foo;
    = note: expected reference `&fn(u32) -> u32`
               found reference `&fn(u32) -> u32 {foo}`
    = note: fn items are distinct from fn pointers
-   = note: when the arguments and return types match, functions can be coerced to function pointers
 help: consider casting to a fn pointer
    |
 LL |     let e: &fn(u32) -> u32 = &(foo as fn(u32) -> u32);
diff --git a/tests/ui/fn/signature-error-reporting-under-verbose.rs b/tests/ui/fn/signature-error-reporting-under-verbose.rs
index 12ff113c913..d00cbd8a0f2 100644
--- a/tests/ui/fn/signature-error-reporting-under-verbose.rs
+++ b/tests/ui/fn/signature-error-reporting-under-verbose.rs
@@ -12,5 +12,4 @@ fn main() {
     //~| NOTE expected fn pointer, found fn item
     //~| NOTE expected fn pointer `fn(i32, u32)`
     //~| NOTE arguments to this function are incorrect
-    //~| NOTE when the arguments and return types match, functions can be coerced to function pointers
 }
diff --git a/tests/ui/fn/signature-error-reporting-under-verbose.stderr b/tests/ui/fn/signature-error-reporting-under-verbose.stderr
index f4498db7259..067ee824d5d 100644
--- a/tests/ui/fn/signature-error-reporting-under-verbose.stderr
+++ b/tests/ui/fn/signature-error-reporting-under-verbose.stderr
@@ -8,7 +8,6 @@ LL |     needs_ptr(foo);
    |
    = note: expected fn pointer `fn(i32, u32)`
                  found fn item `fn(i32, i32) {foo}`
-   = note: when the arguments and return types match, functions can be coerced to function pointers
 note: function defined here
   --> $DIR/signature-error-reporting-under-verbose.rs:5:4
    |
diff --git a/tests/ui/impl-trait/in-trait/lifetime-in-associated-trait-bound.rs b/tests/ui/impl-trait/in-trait/lifetime-in-associated-trait-bound.rs
new file mode 100644
index 00000000000..49d36d6c99c
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/lifetime-in-associated-trait-bound.rs
@@ -0,0 +1,19 @@
+// check-pass
+
+#![feature(associated_type_bounds, return_position_impl_trait_in_trait)]
+
+trait Trait {
+    type Type;
+
+    fn method(&self) -> impl Trait<Type: '_>;
+}
+
+impl Trait for () {
+    type Type = ();
+
+    fn method(&self) -> impl Trait<Type: '_> {
+        ()
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/imports/ambiguous-4.rs b/tests/ui/imports/ambiguous-4.rs
index 10f883339c3..24ae33784c5 100644
--- a/tests/ui/imports/ambiguous-4.rs
+++ b/tests/ui/imports/ambiguous-4.rs
@@ -1,4 +1,4 @@
-// check-pass
+// build-pass
 // aux-build: ../ambiguous-4-extern.rs
 
 extern crate ambiguous_4_extern;
diff --git a/tests/ui/infinite/infinite-type-alias-mutual-recursion.feature.stderr b/tests/ui/infinite/infinite-type-alias-mutual-recursion.feature.stderr
new file mode 100644
index 00000000000..8b8fc46dfc5
--- /dev/null
+++ b/tests/ui/infinite/infinite-type-alias-mutual-recursion.feature.stderr
@@ -0,0 +1,27 @@
+error[E0275]: overflow evaluating the requirement `X2`
+  --> $DIR/infinite-type-alias-mutual-recursion.rs:6:11
+   |
+LL | type X1 = X2;
+   |           ^^
+   |
+   = note: in case this is a recursive type alias, consider using a struct, enum, or union instead
+
+error[E0275]: overflow evaluating the requirement `X3`
+  --> $DIR/infinite-type-alias-mutual-recursion.rs:9:11
+   |
+LL | type X2 = X3;
+   |           ^^
+   |
+   = note: in case this is a recursive type alias, consider using a struct, enum, or union instead
+
+error[E0275]: overflow evaluating the requirement `X1`
+  --> $DIR/infinite-type-alias-mutual-recursion.rs:11:11
+   |
+LL | type X3 = X1;
+   |           ^^
+   |
+   = note: in case this is a recursive type alias, consider using a struct, enum, or union instead
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0275`.
diff --git a/tests/ui/infinite/infinite-type-alias-mutual-recursion.stderr b/tests/ui/infinite/infinite-type-alias-mutual-recursion.gated.stderr
index bbdb1f70b80..ec63688fa8b 100644
--- a/tests/ui/infinite/infinite-type-alias-mutual-recursion.stderr
+++ b/tests/ui/infinite/infinite-type-alias-mutual-recursion.gated.stderr
@@ -1,16 +1,16 @@
 error[E0391]: cycle detected when expanding type alias `X1`
-  --> $DIR/infinite-type-alias-mutual-recursion.rs:1:11
+  --> $DIR/infinite-type-alias-mutual-recursion.rs:6:11
    |
 LL | type X1 = X2;
    |           ^^
    |
 note: ...which requires expanding type alias `X2`...
-  --> $DIR/infinite-type-alias-mutual-recursion.rs:3:11
+  --> $DIR/infinite-type-alias-mutual-recursion.rs:9:11
    |
 LL | type X2 = X3;
    |           ^^
 note: ...which requires expanding type alias `X3`...
-  --> $DIR/infinite-type-alias-mutual-recursion.rs:4:11
+  --> $DIR/infinite-type-alias-mutual-recursion.rs:11:11
    |
 LL | type X3 = X1;
    |           ^^
@@ -19,12 +19,13 @@ LL | type X3 = X1;
    = help: consider using a struct, enum, or union instead to break the cycle
    = help: see <https://doc.rust-lang.org/reference/types.html#recursive-types> for more information
 note: cycle used when collecting item types in top-level module
-  --> $DIR/infinite-type-alias-mutual-recursion.rs:1:1
+  --> $DIR/infinite-type-alias-mutual-recursion.rs:3:1
    |
-LL | / type X1 = X2;
+LL | / #![cfg_attr(feature, feature(lazy_type_alias))]
+LL | | #![allow(incomplete_features)]
 LL | |
-LL | | type X2 = X3;
-LL | | type X3 = X1;
+LL | | type X1 = X2;
+...  |
 LL | |
 LL | | fn main() {}
    | |____________^
diff --git a/tests/ui/infinite/infinite-type-alias-mutual-recursion.rs b/tests/ui/infinite/infinite-type-alias-mutual-recursion.rs
index 5381eedcfac..90c941c634e 100644
--- a/tests/ui/infinite/infinite-type-alias-mutual-recursion.rs
+++ b/tests/ui/infinite/infinite-type-alias-mutual-recursion.rs
@@ -1,6 +1,14 @@
+// revisions: feature gated
+
+#![cfg_attr(feature, feature(lazy_type_alias))]
+#![allow(incomplete_features)]
+
 type X1 = X2;
-//~^ ERROR cycle detected when expanding type alias `X1`
+//[gated]~^ ERROR cycle detected when expanding type alias `X1`
+//[feature]~^^ ERROR: overflow evaluating the requirement `X2`
 type X2 = X3;
+//[feature]~^ ERROR: overflow evaluating the requirement `X3`
 type X3 = X1;
+//[feature]~^ ERROR: overflow evaluating the requirement `X1`
 
 fn main() {}
diff --git a/tests/ui/infinite/infinite-vec-type-recursion.feature.stderr b/tests/ui/infinite/infinite-vec-type-recursion.feature.stderr
new file mode 100644
index 00000000000..3a146215905
--- /dev/null
+++ b/tests/ui/infinite/infinite-vec-type-recursion.feature.stderr
@@ -0,0 +1,11 @@
+error[E0275]: overflow evaluating the requirement `X`
+  --> $DIR/infinite-vec-type-recursion.rs:6:10
+   |
+LL | type X = Vec<X>;
+   |          ^^^^^^
+   |
+   = note: in case this is a recursive type alias, consider using a struct, enum, or union instead
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0275`.
diff --git a/tests/ui/infinite/infinite-vec-type-recursion.stderr b/tests/ui/infinite/infinite-vec-type-recursion.gated.stderr
index a21b033a9a9..e47d9b652fb 100644
--- a/tests/ui/infinite/infinite-vec-type-recursion.stderr
+++ b/tests/ui/infinite/infinite-vec-type-recursion.gated.stderr
@@ -1,5 +1,5 @@
 error[E0391]: cycle detected when expanding type alias `X`
-  --> $DIR/infinite-vec-type-recursion.rs:1:14
+  --> $DIR/infinite-vec-type-recursion.rs:6:14
    |
 LL | type X = Vec<X>;
    |              ^
@@ -9,11 +9,14 @@ LL | type X = Vec<X>;
    = help: consider using a struct, enum, or union instead to break the cycle
    = help: see <https://doc.rust-lang.org/reference/types.html#recursive-types> for more information
 note: cycle used when collecting item types in top-level module
-  --> $DIR/infinite-vec-type-recursion.rs:1:1
+  --> $DIR/infinite-vec-type-recursion.rs:3:1
    |
-LL | / type X = Vec<X>;
-LL | |
+LL | / #![cfg_attr(feature, feature(lazy_type_alias))]
+LL | | #![allow(incomplete_features)]
 LL | |
+LL | | type X = Vec<X>;
+...  |
+LL | | #[rustfmt::skip]
 LL | | fn main() { let b: X = Vec::new(); }
    | |____________________________________^
    = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
diff --git a/tests/ui/infinite/infinite-vec-type-recursion.rs b/tests/ui/infinite/infinite-vec-type-recursion.rs
index 35681822598..71ab4a33013 100644
--- a/tests/ui/infinite/infinite-vec-type-recursion.rs
+++ b/tests/ui/infinite/infinite-vec-type-recursion.rs
@@ -1,4 +1,11 @@
+// revisions: feature gated
+
+#![cfg_attr(feature, feature(lazy_type_alias))]
+#![allow(incomplete_features)]
+
 type X = Vec<X>;
-//~^ ERROR cycle detected
+//[gated]~^ ERROR cycle detected
+//[feature]~^^ ERROR: overflow evaluating the requirement `X`
 
+#[rustfmt::skip]
 fn main() { let b: X = Vec::new(); }
diff --git a/tests/ui/issues/issue-10764.stderr b/tests/ui/issues/issue-10764.stderr
index fcb45affe2c..4d8a85a1397 100644
--- a/tests/ui/issues/issue-10764.stderr
+++ b/tests/ui/issues/issue-10764.stderr
@@ -8,7 +8,6 @@ LL | fn main() { f(bar) }
    |
    = note: expected fn pointer `fn()`
                  found fn item `extern "C" fn() {bar}`
-   = note: when the arguments and return types match, functions can be coerced to function pointers
 note: function defined here
   --> $DIR/issue-10764.rs:1:4
    |
diff --git a/tests/ui/issues/issue-18389.rs b/tests/ui/issues/issue-18389.rs
index 05a5decf462..26b607f4081 100644
--- a/tests/ui/issues/issue-18389.rs
+++ b/tests/ui/issues/issue-18389.rs
@@ -1,9 +1,4 @@
-#![feature(type_privacy_lints)]
-#![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.
+// check-pass
 
 use std::any::Any;
 use std::any::TypeId;
@@ -12,8 +7,7 @@ trait Private<P, R> {
     fn call(&self, p: P, r: R);
 }
 pub trait Public: Private<
-//~^ ERROR private trait `Private<<Self as Public>::P, <Self as Public>::R>` in public interface
-//~| WARNING trait `Private<<Self as Public>::P, <Self as Public>::R>` is more private than the item `Public`
+//~^ WARNING trait `Private<<Self as Public>::P, <Self as Public>::R>` is more private than the item `Public`
     <Self as Public>::P,
     <Self as Public>::R
 > {
diff --git a/tests/ui/issues/issue-18389.stderr b/tests/ui/issues/issue-18389.stderr
index 18ffc4177d7..4706d1ba177 100644
--- a/tests/ui/issues/issue-18389.stderr
+++ b/tests/ui/issues/issue-18389.stderr
@@ -1,39 +1,19 @@
-error[E0445]: private trait `Private<<Self as Public>::P, <Self as Public>::R>` in public interface
-  --> $DIR/issue-18389.rs:14:1
-   |
-LL |   trait Private<P, R> {
-   |   ------------------- `Private<<Self as Public>::P, <Self as Public>::R>` declared as private
-...
-LL | / pub trait Public: Private<
-LL | |
-LL | |
-LL | |     <Self as Public>::P,
-LL | |     <Self as Public>::R
-LL | | > {
-   | |_^ can't leak private trait
-
 warning: trait `Private<<Self as Public>::P, <Self as Public>::R>` is more private than the item `Public`
-  --> $DIR/issue-18389.rs:14:1
+  --> $DIR/issue-18389.rs:9:1
    |
 LL | / pub trait Public: Private<
 LL | |
-LL | |
 LL | |     <Self as Public>::P,
 LL | |     <Self as Public>::R
 LL | | > {
    | |_^ trait `Public` is reachable at visibility `pub`
    |
 note: but trait `Private<<Self as Public>::P, <Self as Public>::R>` is only usable at visibility `pub(crate)`
-  --> $DIR/issue-18389.rs:11:1
+  --> $DIR/issue-18389.rs:6:1
    |
 LL | trait Private<P, R> {
    | ^^^^^^^^^^^^^^^^^^^
-note: the lint level is defined here
-  --> $DIR/issue-18389.rs:2:9
-   |
-LL | #![warn(private_bounds)]
-   |         ^^^^^^^^^^^^^^
+   = note: `#[warn(private_bounds)]` on by default
 
-error: aborting due to previous error; 1 warning emitted
+warning: 1 warning emitted
 
-For more information about this error, try `rustc --explain E0445`.
diff --git a/tests/ui/lint/issue-99387.rs b/tests/ui/lint/issue-99387.rs
index ba5031167e3..571d4194fe7 100644
--- a/tests/ui/lint/issue-99387.rs
+++ b/tests/ui/lint/issue-99387.rs
@@ -2,7 +2,7 @@
 //! opaque types.
 
 #![feature(type_alias_impl_trait)]
-#![allow(private_in_public)]
+#![allow(private_interfaces)]
 
 pub type Successors<'a> = impl Iterator<Item = &'a ()>;
 
diff --git a/tests/ui/lint/lint-ctypes-fn.rs b/tests/ui/lint/lint-ctypes-fn.rs
index d3b36a9d59c..14831e24718 100644
--- a/tests/ui/lint/lint-ctypes-fn.rs
+++ b/tests/ui/lint/lint-ctypes-fn.rs
@@ -1,6 +1,6 @@
 #![feature(rustc_private)]
 
-#![allow(private_in_public)]
+#![allow(private_interfaces)]
 #![deny(improper_ctypes_definitions)]
 
 extern crate libc;
diff --git a/tests/ui/lint/lint-ctypes.rs b/tests/ui/lint/lint-ctypes.rs
index 9165e14b7ff..3dd731625f4 100644
--- a/tests/ui/lint/lint-ctypes.rs
+++ b/tests/ui/lint/lint-ctypes.rs
@@ -1,6 +1,6 @@
 #![feature(rustc_private)]
 
-#![allow(private_in_public)]
+#![allow(private_interfaces)]
 #![deny(improper_ctypes)]
 
 extern crate libc;
diff --git a/tests/ui/lint/unused/unused-parens-issue-106413.rs b/tests/ui/lint/unused/unused-parens-issue-106413.rs
new file mode 100644
index 00000000000..7e76ab073b4
--- /dev/null
+++ b/tests/ui/lint/unused/unused-parens-issue-106413.rs
@@ -0,0 +1,32 @@
+// check-pass
+#![warn(unused_parens)]
+
+fn id<T>(t: T) -> T { t }
+
+fn main() {
+    // This should not warn
+    let _ = 1 as (i32) < 2;
+    let _ = id(1 as (i32) < 2);
+    let _ = id(1 as i32)
+        as (i32) < 2;
+    // These should warn
+    let _ = 1 as ((i32)) < 2; //~WARN unnecessary parentheses
+    let _ = 1 as (i32); //~WARN unnecessary parentheses
+    let _ = 1 as (i32) > 2; //~WARN unnecessary parentheses
+    let _ = id(1 as (i32)) //~WARN unnecessary parentheses
+        as (i32) < 2;
+    let _ = id(1 as (i32)) < 2; //~WARN unnecessary parentheses
+
+    // This should not warn
+    let _ = 1 as (i32) << 2;
+    let _ = id(1 as (i32) << 2);
+    let _ = id(1 as i32)
+        as (i32) << 2;
+    // These should warn
+    let _ = 1 as ((i32)) << 2; //~WARN unnecessary parentheses
+    let _ = 1 as (i32); //~WARN unnecessary parentheses
+    let _ = 1 as (i32) >> 2; //~WARN unnecessary parentheses
+    let _ = id(1 as (i32)) //~WARN unnecessary parentheses
+        as (i32) << 2;
+    let _ = id(1 as (i32)) << 2; //~WARN unnecessary parentheses
+}
diff --git a/tests/ui/lint/unused/unused-parens-issue-106413.stderr b/tests/ui/lint/unused/unused-parens-issue-106413.stderr
new file mode 100644
index 00000000000..d2d8f76d967
--- /dev/null
+++ b/tests/ui/lint/unused/unused-parens-issue-106413.stderr
@@ -0,0 +1,127 @@
+warning: unnecessary parentheses around type
+  --> $DIR/unused-parens-issue-106413.rs:13:19
+   |
+LL |     let _ = 1 as ((i32)) < 2;
+   |                   ^   ^
+   |
+note: the lint level is defined here
+  --> $DIR/unused-parens-issue-106413.rs:2:9
+   |
+LL | #![warn(unused_parens)]
+   |         ^^^^^^^^^^^^^
+help: remove these parentheses
+   |
+LL -     let _ = 1 as ((i32)) < 2;
+LL +     let _ = 1 as (i32) < 2;
+   |
+
+warning: unnecessary parentheses around type
+  --> $DIR/unused-parens-issue-106413.rs:14:18
+   |
+LL |     let _ = 1 as (i32);
+   |                  ^   ^
+   |
+help: remove these parentheses
+   |
+LL -     let _ = 1 as (i32);
+LL +     let _ = 1 as i32;
+   |
+
+warning: unnecessary parentheses around type
+  --> $DIR/unused-parens-issue-106413.rs:15:18
+   |
+LL |     let _ = 1 as (i32) > 2;
+   |                  ^   ^
+   |
+help: remove these parentheses
+   |
+LL -     let _ = 1 as (i32) > 2;
+LL +     let _ = 1 as i32 > 2;
+   |
+
+warning: unnecessary parentheses around type
+  --> $DIR/unused-parens-issue-106413.rs:16:21
+   |
+LL |     let _ = id(1 as (i32))
+   |                     ^   ^
+   |
+help: remove these parentheses
+   |
+LL -     let _ = id(1 as (i32))
+LL +     let _ = id(1 as i32)
+   |
+
+warning: unnecessary parentheses around type
+  --> $DIR/unused-parens-issue-106413.rs:18:21
+   |
+LL |     let _ = id(1 as (i32)) < 2;
+   |                     ^   ^
+   |
+help: remove these parentheses
+   |
+LL -     let _ = id(1 as (i32)) < 2;
+LL +     let _ = id(1 as i32) < 2;
+   |
+
+warning: unnecessary parentheses around type
+  --> $DIR/unused-parens-issue-106413.rs:26:19
+   |
+LL |     let _ = 1 as ((i32)) << 2;
+   |                   ^   ^
+   |
+help: remove these parentheses
+   |
+LL -     let _ = 1 as ((i32)) << 2;
+LL +     let _ = 1 as (i32) << 2;
+   |
+
+warning: unnecessary parentheses around type
+  --> $DIR/unused-parens-issue-106413.rs:27:18
+   |
+LL |     let _ = 1 as (i32);
+   |                  ^   ^
+   |
+help: remove these parentheses
+   |
+LL -     let _ = 1 as (i32);
+LL +     let _ = 1 as i32;
+   |
+
+warning: unnecessary parentheses around type
+  --> $DIR/unused-parens-issue-106413.rs:28:18
+   |
+LL |     let _ = 1 as (i32) >> 2;
+   |                  ^   ^
+   |
+help: remove these parentheses
+   |
+LL -     let _ = 1 as (i32) >> 2;
+LL +     let _ = 1 as i32 >> 2;
+   |
+
+warning: unnecessary parentheses around type
+  --> $DIR/unused-parens-issue-106413.rs:29:21
+   |
+LL |     let _ = id(1 as (i32))
+   |                     ^   ^
+   |
+help: remove these parentheses
+   |
+LL -     let _ = id(1 as (i32))
+LL +     let _ = id(1 as i32)
+   |
+
+warning: unnecessary parentheses around type
+  --> $DIR/unused-parens-issue-106413.rs:31:21
+   |
+LL |     let _ = id(1 as (i32)) << 2;
+   |                     ^   ^
+   |
+help: remove these parentheses
+   |
+LL -     let _ = id(1 as (i32)) << 2;
+LL +     let _ = id(1 as i32) << 2;
+   |
+
+warning: 10 warnings emitted
+
diff --git a/tests/ui/mismatched_types/normalize-fn-sig.stderr b/tests/ui/mismatched_types/normalize-fn-sig.stderr
index e3a0646550c..252e56387ba 100644
--- a/tests/ui/mismatched_types/normalize-fn-sig.stderr
+++ b/tests/ui/mismatched_types/normalize-fn-sig.stderr
@@ -8,7 +8,6 @@ LL |     needs_i32_ref_fn(foo::<()>);
    |
    = note: expected fn pointer `fn(&'static i32, i32)`
                  found fn item `fn(i32, &'static i32) {foo::<()>}`
-   = note: when the arguments and return types match, functions can be coerced to function pointers
 note: function defined here
   --> $DIR/normalize-fn-sig.rs:11:4
    |
diff --git a/tests/ui/nll/missing-universe-cause-issue-114907.rs b/tests/ui/nll/missing-universe-cause-issue-114907.rs
new file mode 100644
index 00000000000..94acdccfcf2
--- /dev/null
+++ b/tests/ui/nll/missing-universe-cause-issue-114907.rs
@@ -0,0 +1,40 @@
+// This is a non-regression test for issue #114907 where an ICE happened because of missing
+// `UniverseInfo`s accessed during diagnostics.
+//
+// A couple notes:
+// - the `FnOnce` bounds need an arg that is a reference
+// - a custom `Drop` is needed somewhere in the type that `accept` returns, to create universes
+//   during liveness and dropck outlives computation
+
+// check-fail
+
+trait Role {
+    type Inner;
+}
+
+struct HandshakeCallback<C>(C);
+impl<C: FnOnce(&())> Role for HandshakeCallback<C> {
+    type Inner = ();
+}
+
+struct Handshake<R: Role> {
+    _inner: Option<R::Inner>,
+}
+impl<R: Role> Drop for Handshake<R> {
+    fn drop(&mut self) {}
+}
+
+fn accept<C: FnOnce(&())>(_: C) -> Handshake<HandshakeCallback<C>> {
+    todo!()
+}
+
+fn main() {
+    let callback = |_| {};
+    accept(callback);
+    //~^ ERROR mismatched types
+    //~| ERROR mismatched types
+    //~| ERROR implementation of `FnOnce` is not general enough
+    //~| ERROR implementation of `FnOnce` is not general enough
+    //~| ERROR higher-ranked subtype error
+    //~| ERROR higher-ranked subtype error
+}
diff --git a/tests/ui/nll/missing-universe-cause-issue-114907.stderr b/tests/ui/nll/missing-universe-cause-issue-114907.stderr
new file mode 100644
index 00000000000..c3dd4257a73
--- /dev/null
+++ b/tests/ui/nll/missing-universe-cause-issue-114907.stderr
@@ -0,0 +1,79 @@
+error[E0308]: mismatched types
+  --> $DIR/missing-universe-cause-issue-114907.rs:33:5
+   |
+LL |     accept(callback);
+   |     ^^^^^^^^^^^^^^^^ one type is more general than the other
+   |
+   = note: expected trait `for<'a> FnOnce<(&'a (),)>`
+              found trait `FnOnce<(&(),)>`
+note: this closure does not fulfill the lifetime requirements
+  --> $DIR/missing-universe-cause-issue-114907.rs:32:20
+   |
+LL |     let callback = |_| {};
+   |                    ^^^
+note: the lifetime requirement is introduced here
+  --> $DIR/missing-universe-cause-issue-114907.rs:27:14
+   |
+LL | fn accept<C: FnOnce(&())>(_: C) -> Handshake<HandshakeCallback<C>> {
+   |              ^^^^^^^^^^^
+help: consider specifying the type of the closure parameters
+   |
+LL |     let callback = |_: &_| {};
+   |                    ~~~~~~~
+
+error: implementation of `FnOnce` is not general enough
+  --> $DIR/missing-universe-cause-issue-114907.rs:33:5
+   |
+LL |     accept(callback);
+   |     ^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
+   |
+   = note: closure with signature `fn(&'2 ())` must implement `FnOnce<(&'1 (),)>`, for any lifetime `'1`...
+   = note: ...but it actually implements `FnOnce<(&'2 (),)>`, for some specific lifetime `'2`
+
+error: implementation of `FnOnce` is not general enough
+  --> $DIR/missing-universe-cause-issue-114907.rs:33:5
+   |
+LL |     accept(callback);
+   |     ^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
+   |
+   = note: closure with signature `fn(&'2 ())` must implement `FnOnce<(&'1 (),)>`, for any lifetime `'1`...
+   = note: ...but it actually implements `FnOnce<(&'2 (),)>`, for some specific lifetime `'2`
+
+error[E0308]: mismatched types
+  --> $DIR/missing-universe-cause-issue-114907.rs:33:5
+   |
+LL |     accept(callback);
+   |     ^^^^^^^^^^^^^^^^ one type is more general than the other
+   |
+   = note: expected trait `for<'a> FnOnce<(&'a (),)>`
+              found trait `FnOnce<(&(),)>`
+note: this closure does not fulfill the lifetime requirements
+  --> $DIR/missing-universe-cause-issue-114907.rs:32:20
+   |
+LL |     let callback = |_| {};
+   |                    ^^^
+note: the lifetime requirement is introduced here
+  --> $DIR/missing-universe-cause-issue-114907.rs:20:21
+   |
+LL | struct Handshake<R: Role> {
+   |                     ^^^^
+help: consider specifying the type of the closure parameters
+   |
+LL |     let callback = |_: &_| {};
+   |                    ~~~~~~~
+
+error: higher-ranked subtype error
+  --> $DIR/missing-universe-cause-issue-114907.rs:33:21
+   |
+LL |     accept(callback);
+   |                     ^
+
+error: higher-ranked subtype error
+  --> $DIR/missing-universe-cause-issue-114907.rs:33:21
+   |
+LL |     accept(callback);
+   |                     ^
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/privacy/associated-item-privacy-inherent.rs b/tests/ui/privacy/associated-item-privacy-inherent.rs
index 7b7c734a99a..81703ae1067 100644
--- a/tests/ui/privacy/associated-item-privacy-inherent.rs
+++ b/tests/ui/privacy/associated-item-privacy-inherent.rs
@@ -1,5 +1,5 @@
 #![feature(decl_macro, associated_type_defaults)]
-#![allow(unused, private_in_public)]
+#![allow(private_interfaces)]
 
 mod priv_nominal {
     pub struct Pub;
diff --git a/tests/ui/privacy/associated-item-privacy-trait.rs b/tests/ui/privacy/associated-item-privacy-trait.rs
index c686a21772e..db77a6a7258 100644
--- a/tests/ui/privacy/associated-item-privacy-trait.rs
+++ b/tests/ui/privacy/associated-item-privacy-trait.rs
@@ -1,5 +1,5 @@
 #![feature(decl_macro, associated_type_defaults)]
-#![allow(unused, private_in_public)]
+#![allow(private_interfaces, private_bounds)]
 
 mod priv_trait {
     trait PrivTr {
diff --git a/tests/ui/privacy/associated-item-privacy-type-binding.rs b/tests/ui/privacy/associated-item-privacy-type-binding.rs
index 9826b83a35d..95a4fbf639c 100644
--- a/tests/ui/privacy/associated-item-privacy-type-binding.rs
+++ b/tests/ui/privacy/associated-item-privacy-type-binding.rs
@@ -1,5 +1,5 @@
 #![feature(decl_macro, associated_type_defaults)]
-#![allow(unused, private_in_public)]
+#![allow(private_interfaces, private_bounds)]
 
 mod priv_trait {
     trait PrivTr {
diff --git a/tests/ui/privacy/effective_visibilities_full_priv.rs b/tests/ui/privacy/effective_visibilities_full_priv.rs
index a26ae3bd122..b96eddcab67 100644
--- a/tests/ui/privacy/effective_visibilities_full_priv.rs
+++ b/tests/ui/privacy/effective_visibilities_full_priv.rs
@@ -1,5 +1,5 @@
 #![feature(rustc_attrs)]
-#![allow(private_in_public)]
+#![allow(private_interfaces)]
 
 struct SemiPriv;
 
diff --git a/tests/ui/privacy/issue-30079.rs b/tests/ui/privacy/issue-30079.rs
index a02a932d057..ddba629f528 100644
--- a/tests/ui/privacy/issue-30079.rs
+++ b/tests/ui/privacy/issue-30079.rs
@@ -3,8 +3,7 @@ struct SemiPriv;
 mod m1 {
     struct Priv;
     impl ::SemiPriv {
-        pub fn f(_: Priv) {} //~ WARN private type `m1::Priv` in public interface
-        //~^ WARNING hard error
+        pub fn f(_: Priv) {} //~ WARN type `m1::Priv` is more private than the item `m1::<impl SemiPriv>::f`
     }
 
     impl Priv {
diff --git a/tests/ui/privacy/issue-30079.stderr b/tests/ui/privacy/issue-30079.stderr
index 9179ff339bf..f1facba7cd2 100644
--- a/tests/ui/privacy/issue-30079.stderr
+++ b/tests/ui/privacy/issue-30079.stderr
@@ -1,15 +1,18 @@
-warning: private type `m1::Priv` in public interface (error E0446)
+warning: type `m1::Priv` is more private than the item `m1::<impl SemiPriv>::f`
   --> $DIR/issue-30079.rs:6:9
    |
 LL |         pub fn f(_: Priv) {}
-   |         ^^^^^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^^^^ associated function `m1::<impl SemiPriv>::f` is reachable at visibility `pub(crate)`
    |
-   = 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>
-   = note: `#[warn(private_in_public)]` on by default
+note: but type `m1::Priv` is only usable at visibility `pub(self)`
+  --> $DIR/issue-30079.rs:4:5
+   |
+LL |     struct Priv;
+   |     ^^^^^^^^^^^
+   = note: `#[warn(private_interfaces)]` on by default
 
 error[E0446]: private type `m2::Priv` in public interface
-  --> $DIR/issue-30079.rs:18:9
+  --> $DIR/issue-30079.rs:17:9
    |
 LL |     struct Priv;
    |     ----------- `m2::Priv` declared as private
@@ -18,7 +21,7 @@ LL |         type Target = Priv;
    |         ^^^^^^^^^^^ can't leak private type
 
 error[E0446]: private type `m3::Priv` in public interface
-  --> $DIR/issue-30079.rs:35:9
+  --> $DIR/issue-30079.rs:34:9
    |
 LL |     struct Priv;
    |     ----------- `m3::Priv` declared as private
diff --git a/tests/ui/privacy/private-in-public-assoc-ty.rs b/tests/ui/privacy/private-in-public-assoc-ty.rs
index d4d379bdb73..5f7c4bcf265 100644
--- a/tests/ui/privacy/private-in-public-assoc-ty.rs
+++ b/tests/ui/privacy/private-in-public-assoc-ty.rs
@@ -22,14 +22,11 @@ mod m {
     // applies only to the aliased types, not bounds.
     pub trait PubTr {
         type Alias1: PrivTr;
-        //~^ WARN private trait `PrivTr` in public interface
-        //~| WARN this was previously accepted
+        //~^ WARN trait `PrivTr` is more private than the item `PubTr::Alias1`
         type Alias2: PubTrAux1<Priv> = u8;
-        //~^ WARN private type `Priv` in public interface
-        //~| WARN this was previously accepted
+        //~^ WARN type `Priv` is more private than the item `PubTr::Alias2`
         type Alias3: PubTrAux2<A = Priv> = u8;
-        //~^ WARN private type `Priv` in public interface
-        //~| WARN this was previously accepted
+        //~^ WARN type `Priv` is more private than the item `PubTr::Alias3`
 
         type Alias4 = Priv;
         //~^ ERROR private type `Priv` in public interface
diff --git a/tests/ui/privacy/private-in-public-assoc-ty.stderr b/tests/ui/privacy/private-in-public-assoc-ty.stderr
index a59027d81d2..0931e6d9971 100644
--- a/tests/ui/privacy/private-in-public-assoc-ty.stderr
+++ b/tests/ui/privacy/private-in-public-assoc-ty.stderr
@@ -7,36 +7,45 @@ LL |     struct Priv;
 LL |         type A = Priv;
    |         ^^^^^^ can't leak private type
 
-warning: private trait `PrivTr` in public interface (error E0445)
+warning: trait `PrivTr` is more private than the item `PubTr::Alias1`
   --> $DIR/private-in-public-assoc-ty.rs:24:9
    |
 LL |         type Alias1: PrivTr;
-   |         ^^^^^^^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^^^^^^ associated type `PubTr::Alias1` is reachable at visibility `pub(crate)`
    |
-   = 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>
-   = note: `#[warn(private_in_public)]` on by default
+note: but trait `PrivTr` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public-assoc-ty.rs:9:5
+   |
+LL |     trait PrivTr {}
+   |     ^^^^^^^^^^^^
+   = note: `#[warn(private_bounds)]` on by default
 
-warning: private type `Priv` in public interface (error E0446)
-  --> $DIR/private-in-public-assoc-ty.rs:27:9
+warning: type `Priv` is more private than the item `PubTr::Alias2`
+  --> $DIR/private-in-public-assoc-ty.rs:26:9
    |
 LL |         type Alias2: PubTrAux1<Priv> = u8;
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ associated type `PubTr::Alias2` is reachable at visibility `pub(crate)`
    |
-   = 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>
+note: but type `Priv` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public-assoc-ty.rs:8:5
+   |
+LL |     struct Priv;
+   |     ^^^^^^^^^^^
 
-warning: private type `Priv` in public interface (error E0446)
-  --> $DIR/private-in-public-assoc-ty.rs:30:9
+warning: type `Priv` is more private than the item `PubTr::Alias3`
+  --> $DIR/private-in-public-assoc-ty.rs:28:9
    |
 LL |         type Alias3: PubTrAux2<A = Priv> = u8;
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ associated type `PubTr::Alias3` is reachable at visibility `pub(crate)`
    |
-   = 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>
+note: but type `Priv` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public-assoc-ty.rs:8:5
+   |
+LL |     struct Priv;
+   |     ^^^^^^^^^^^
 
 error[E0446]: private type `Priv` in public interface
-  --> $DIR/private-in-public-assoc-ty.rs:34:9
+  --> $DIR/private-in-public-assoc-ty.rs:31:9
    |
 LL |     struct Priv;
    |     ----------- `Priv` declared as private
@@ -45,7 +54,7 @@ LL |         type Alias4 = Priv;
    |         ^^^^^^^^^^^ can't leak private type
 
 error[E0446]: private type `Priv` in public interface
-  --> $DIR/private-in-public-assoc-ty.rs:41:9
+  --> $DIR/private-in-public-assoc-ty.rs:38:9
    |
 LL |     struct Priv;
    |     ----------- `Priv` declared as private
@@ -53,8 +62,8 @@ LL |     struct Priv;
 LL |         type Alias1 = Priv;
    |         ^^^^^^^^^^^ can't leak private type
 
-error[E0445]: private trait `PrivTr` in public interface
-  --> $DIR/private-in-public-assoc-ty.rs:44:9
+error[E0446]: private trait `PrivTr` in public interface
+  --> $DIR/private-in-public-assoc-ty.rs:41:9
    |
 LL |     trait PrivTr {}
    |     ------------ `PrivTr` declared as private
@@ -64,5 +73,4 @@ LL |         type Exist = impl PrivTr;
 
 error: aborting due to 4 previous errors; 3 warnings emitted
 
-Some errors have detailed explanations: E0445, E0446.
-For more information about an error, try `rustc --explain E0445`.
+For more information about this error, try `rustc --explain E0446`.
diff --git a/tests/ui/privacy/private-in-public-lint.rs b/tests/ui/privacy/private-in-public-lint.rs
deleted file mode 100644
index 8b6e4360160..00000000000
--- a/tests/ui/privacy/private-in-public-lint.rs
+++ /dev/null
@@ -1,19 +0,0 @@
-mod m1 {
-    pub struct Pub;
-    struct Priv;
-
-    impl Pub {
-        pub fn f() -> Priv {Priv} //~ ERROR private type `m1::Priv` in public interface
-    }
-}
-
-mod m2 {
-    pub struct Pub;
-    struct Priv;
-
-    impl Pub {
-        pub fn f() -> Priv {Priv} //~ ERROR private type `m2::Priv` in public interface
-    }
-}
-
-fn main() {}
diff --git a/tests/ui/privacy/private-in-public-lint.stderr b/tests/ui/privacy/private-in-public-lint.stderr
deleted file mode 100644
index 1e98e3bed14..00000000000
--- a/tests/ui/privacy/private-in-public-lint.stderr
+++ /dev/null
@@ -1,21 +0,0 @@
-error[E0446]: private type `m1::Priv` in public interface
-  --> $DIR/private-in-public-lint.rs:6:9
-   |
-LL |     struct Priv;
-   |     ----------- `m1::Priv` declared as private
-...
-LL |         pub fn f() -> Priv {Priv}
-   |         ^^^^^^^^^^^^^^^^^^ can't leak private type
-
-error[E0446]: private type `m2::Priv` in public interface
-  --> $DIR/private-in-public-lint.rs:15:9
-   |
-LL |     struct Priv;
-   |     ----------- `m2::Priv` declared as private
-...
-LL |         pub fn f() -> Priv {Priv}
-   |         ^^^^^^^^^^^^^^^^^^ can't leak private type
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0446`.
diff --git a/tests/ui/privacy/private-in-public-non-principal-2.rs b/tests/ui/privacy/private-in-public-non-principal-2.rs
index db451d33429..d7223c647c0 100644
--- a/tests/ui/privacy/private-in-public-non-principal-2.rs
+++ b/tests/ui/privacy/private-in-public-non-principal-2.rs
@@ -1,7 +1,7 @@
 #![feature(auto_traits)]
 #![feature(negative_impls)]
 
-#[allow(private_in_public)]
+#[allow(private_interfaces)]
 mod m {
     pub trait PubPrincipal {}
     auto trait PrivNonPrincipal {}
diff --git a/tests/ui/privacy/private-in-public-non-principal.rs b/tests/ui/privacy/private-in-public-non-principal.rs
index a2284c93027..e348a181651 100644
--- a/tests/ui/privacy/private-in-public-non-principal.rs
+++ b/tests/ui/privacy/private-in-public-non-principal.rs
@@ -1,19 +1,11 @@
 #![feature(auto_traits)]
 #![feature(negative_impls)]
-#![feature(type_privacy_lints)]
-#![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 {}
 
 pub fn leak_dyn_nonprincipal() -> Box<dyn PubPrincipal + PrivNonPrincipal> { loop {} }
-//~^ WARN private trait `PrivNonPrincipal` in public interface
-//~| WARN this was previously accepted
-//~| ERROR trait `PrivNonPrincipal` is more private than the item `leak_dyn_nonprincipal`
+//~^ WARN trait `PrivNonPrincipal` is more private than the item `leak_dyn_nonprincipal`
 
 #[deny(missing_docs)]
 fn container() {
diff --git a/tests/ui/privacy/private-in-public-non-principal.stderr b/tests/ui/privacy/private-in-public-non-principal.stderr
index 1387f59cbde..63512f462f5 100644
--- a/tests/ui/privacy/private-in-public-non-principal.stderr
+++ b/tests/ui/privacy/private-in-public-non-principal.stderr
@@ -1,41 +1,27 @@
-warning: private trait `PrivNonPrincipal` in public interface (error E0445)
-  --> $DIR/private-in-public-non-principal.rs:13:1
-   |
-LL | pub fn leak_dyn_nonprincipal() -> Box<dyn PubPrincipal + PrivNonPrincipal> { loop {} }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = 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>
-   = note: `#[warn(private_in_public)]` on by default
-
-error: trait `PrivNonPrincipal` is more private than the item `leak_dyn_nonprincipal`
-  --> $DIR/private-in-public-non-principal.rs:13:1
+warning: trait `PrivNonPrincipal` is more private than the item `leak_dyn_nonprincipal`
+  --> $DIR/private-in-public-non-principal.rs:7:1
    |
 LL | pub fn leak_dyn_nonprincipal() -> Box<dyn PubPrincipal + PrivNonPrincipal> { loop {} }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function `leak_dyn_nonprincipal` is reachable at visibility `pub`
    |
 note: but trait `PrivNonPrincipal` is only usable at visibility `pub(crate)`
-  --> $DIR/private-in-public-non-principal.rs:11:1
+  --> $DIR/private-in-public-non-principal.rs:5: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)]
-   |         ^^^^^^^^^^^^^^^^^^
+   = note: `#[warn(private_interfaces)]` on by default
 
 error: missing documentation for an associated function
-  --> $DIR/private-in-public-non-principal.rs:21:9
+  --> $DIR/private-in-public-non-principal.rs:13:9
    |
 LL |         pub fn check_doc_lint() {}
    |         ^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: the lint level is defined here
-  --> $DIR/private-in-public-non-principal.rs:18:8
+  --> $DIR/private-in-public-non-principal.rs:10:8
    |
 LL | #[deny(missing_docs)]
    |        ^^^^^^^^^^^^
 
-error: aborting due to 2 previous errors; 1 warning emitted
+error: aborting due to previous error; 1 warning emitted
 
diff --git a/tests/ui/privacy/private-in-public-type-alias-impl-trait.rs b/tests/ui/privacy/private-in-public-type-alias-impl-trait.rs
index fe6ed46734c..3fb543e9624 100644
--- a/tests/ui/privacy/private-in-public-type-alias-impl-trait.rs
+++ b/tests/ui/privacy/private-in-public-type-alias-impl-trait.rs
@@ -1,7 +1,7 @@
 // build-pass (FIXME(62277): could be check-pass?)
 #![feature(impl_trait_in_assoc_type)]
 #![feature(type_alias_impl_trait)]
-#![deny(private_in_public)]
+#![deny(private_interfaces, private_bounds)]
 
 pub type Pub = impl Default;
 
diff --git a/tests/ui/privacy/private-in-public-warn.rs b/tests/ui/privacy/private-in-public-warn.rs
index 0fa1de975b0..99d318e36be 100644
--- a/tests/ui/privacy/private-in-public-warn.rs
+++ b/tests/ui/privacy/private-in-public-warn.rs
@@ -2,7 +2,7 @@
 // This test also ensures that the checks are performed even inside private modules.
 
 #![feature(associated_type_defaults)]
-#![deny(private_in_public)]
+#![deny(private_interfaces, private_bounds)]
 #![allow(improper_ctypes)]
 
 mod types {
@@ -12,30 +12,21 @@ mod types {
         type Alias;
     }
 
-    pub type Alias = Priv; //~ ERROR private type `types::Priv` in public interface
-    //~^ WARNING hard error
+    pub type Alias = Priv; //~ ERROR type `types::Priv` is more private than the item `types::Alias`
     pub enum E {
-        V1(Priv), //~ ERROR private type `types::Priv` in public interface
-        //~^ WARNING hard error
-        V2 { field: Priv }, //~ ERROR private type `types::Priv` in public interface
-        //~^ WARNING hard error
+        V1(Priv), //~ ERROR type `types::Priv` is more private than the item `E::V1::0`
+        V2 { field: Priv }, //~ ERROR type `types::Priv` is more private than the item `E::V2::field`
     }
     pub trait Tr {
-        const C: Priv = Priv; //~ ERROR private type `types::Priv` in public interface
-        //~^ WARNING hard error
+        const C: Priv = Priv; //~ ERROR type `types::Priv` is more private than the item `Tr::C`
         type Alias = Priv; //~ ERROR private type `types::Priv` in public interface
-        fn f1(arg: Priv) {} //~ ERROR private type `types::Priv` in public interface
-        //~^ WARNING hard error
-        fn f2() -> Priv { panic!() } //~ ERROR private type `types::Priv` in public interface
-        //~^ WARNING hard error
+        fn f1(arg: Priv) {} //~ ERROR type `types::Priv` is more private than the item `Tr::f1`
+        fn f2() -> Priv { panic!() } //~ ERROR type `types::Priv` is more private than the item `Tr::f2`
     }
     extern "C" {
-        pub static ES: Priv; //~ ERROR private type `types::Priv` in public interface
-        //~^ WARNING hard error
-        pub fn ef1(arg: Priv); //~ ERROR private type `types::Priv` in public interface
-        //~^ WARNING hard error
-        pub fn ef2() -> Priv; //~ ERROR private type `types::Priv` in public interface
-        //~^ WARNING hard error
+        pub static ES: Priv; //~ ERROR type `types::Priv` is more private than the item `types::ES`
+        pub fn ef1(arg: Priv); //~ ERROR type `types::Priv` is more private than the item `types::ef1`
+        pub fn ef2() -> Priv; //~ ERROR type `types::Priv` is more private than the item `types::ef2`
     }
     impl PubTr for Pub {
         type Alias = Priv; //~ ERROR private type `types::Priv` in public interface
@@ -47,22 +38,16 @@ mod traits {
     pub struct Pub<T>(T);
     pub trait PubTr {}
 
-    pub type Alias<T: PrivTr> = T; //~ ERROR private trait `traits::PrivTr` in public interface
-    //~| WARNING hard error
-    //~| WARNING bounds on generic parameters are not enforced in type aliases
-    pub trait Tr1: PrivTr {} //~ ERROR private trait `traits::PrivTr` in public interface
-    //~^ WARNING hard error
-    pub trait Tr2<T: PrivTr> {} //~ ERROR private trait `traits::PrivTr` in public interface
-        //~^ WARNING hard error
+    pub type Alias<T: PrivTr> = T; //~ ERROR trait `traits::PrivTr` is more private than the item `traits::Alias`
+    //~^ WARNING bounds on generic parameters are not enforced in type aliases
+    pub trait Tr1: PrivTr {} //~ ERROR trait `traits::PrivTr` is more private than the item `traits::Tr1`
+    pub trait Tr2<T: PrivTr> {} //~ ERROR trait `traits::PrivTr` is more private than the item `traits::Tr2`
     pub trait Tr3 {
         type Alias: PrivTr;
-        //~^ ERROR private trait `traits::PrivTr` in public interface
-        //~| WARNING hard error
-        fn f<T: PrivTr>(arg: T) {} //~ ERROR private trait `traits::PrivTr` in public interface
-        //~^ WARNING hard error
+        //~^ ERROR trait `traits::PrivTr` is more private than the item `traits::Tr3::Alias`
+        fn f<T: PrivTr>(arg: T) {} //~ ERROR trait `traits::PrivTr` is more private than the item `traits::Tr3::f`
     }
-    impl<T: PrivTr> Pub<T> {} //~ ERROR private trait `traits::PrivTr` in public interface
-        //~^ WARNING hard error
+    impl<T: PrivTr> Pub<T> {} //~ ERROR trait `traits::PrivTr` is more private than the item `traits::Pub<T>`
     impl<T: PrivTr> PubTr for Pub<T> {} // OK, trait impl predicates
 }
 
@@ -72,20 +57,16 @@ mod traits_where {
     pub trait PubTr {}
 
     pub type Alias<T> where T: PrivTr = T;
-        //~^ ERROR private trait `traits_where::PrivTr` in public interface
-        //~| WARNING hard error
+        //~^ ERROR trait `traits_where::PrivTr` is more private than the item `traits_where::Alias`
         //~| WARNING where clauses are not enforced in type aliases
     pub trait Tr2<T> where T: PrivTr {}
-        //~^ ERROR private trait `traits_where::PrivTr` in public interface
-        //~| WARNING hard error
+        //~^ ERROR trait `traits_where::PrivTr` is more private than the item `traits_where::Tr2`
     pub trait Tr3 {
         fn f<T>(arg: T) where T: PrivTr {}
-        //~^ ERROR private trait `traits_where::PrivTr` in public interface
-        //~| WARNING hard error
+        //~^ ERROR trait `traits_where::PrivTr` is more private than the item `traits_where::Tr3::f`
     }
     impl<T> Pub<T> where T: PrivTr {}
-        //~^ ERROR private trait `traits_where::PrivTr` in public interface
-        //~| WARNING hard error
+        //~^ ERROR trait `traits_where::PrivTr` is more private than the item `traits_where::Pub<T>`
     impl<T> PubTr for Pub<T> where T: PrivTr {} // OK, trait impl predicates
 }
 
@@ -96,14 +77,10 @@ mod generics {
     pub trait PubTr<T> {}
 
     pub trait Tr1: PrivTr<Pub> {}
-        //~^ ERROR private trait `generics::PrivTr<generics::Pub>` in public interface
-        //~| WARNING hard error
-    pub trait Tr2: PubTr<Priv> {} //~ ERROR private type `generics::Priv` in public interface
-        //~^ WARNING hard error
-    pub trait Tr3: PubTr<[Priv; 1]> {} //~ ERROR private type `generics::Priv` in public interface
-        //~^ WARNING hard error
-    pub trait Tr4: PubTr<Pub<Priv>> {} //~ ERROR private type `generics::Priv` in public interface
-        //~^ WARNING hard error
+        //~^ ERROR trait `generics::PrivTr<generics::Pub>` is more private than the item `generics::Tr1`
+    pub trait Tr2: PubTr<Priv> {} //~ ERROR type `generics::Priv` is more private than the item `generics::Tr2`
+    pub trait Tr3: PubTr<[Priv; 1]> {} //~ ERROR type `generics::Priv` is more private than the item `generics::Tr3`
+    pub trait Tr4: PubTr<Pub<Priv>> {} //~ ERROR type `generics::Priv` is more private than the item `Tr4`
 }
 
 mod impls {
@@ -200,8 +177,7 @@ mod aliases_pub {
     pub trait Tr2: PrivUseAliasTr<PrivAlias> {} // OK
 
     impl PrivAlias {
-        pub fn f(arg: Priv) {} //~ ERROR private type `aliases_pub::Priv` in public interface
-        //~^ WARNING hard error
+        pub fn f(arg: Priv) {} //~ ERROR type `aliases_pub::Priv` is more private than the item `aliases_pub::<impl Pub2>::f`
     }
     impl PrivUseAliasTr for PrivUseAlias {
         type Check = Priv; //~ ERROR private type `aliases_pub::Priv` in public interface
@@ -244,13 +220,10 @@ mod aliases_priv {
     }
 
     pub trait Tr1: PrivUseAliasTr {}
-        //~^ ERROR private trait `PrivTr1` in public interface
-        //~| WARNING hard error
+        //~^ ERROR trait `PrivTr1` is more private than the item `aliases_priv::Tr1`
     pub trait Tr2: PrivUseAliasTr<PrivAlias> {}
-        //~^ ERROR private trait `PrivTr1<Priv2>` in public interface
-        //~| WARNING hard error
-        //~| ERROR private type `Priv2` in public interface
-        //~| WARNING hard error
+        //~^ ERROR trait `PrivTr1<Priv2>` is more private than the item `aliases_priv::Tr2`
+        //~| ERROR type `Priv2` is more private than the item `aliases_priv::Tr2`
 
     impl PrivUseAlias {
         pub fn f(arg: Priv) {} // OK
diff --git a/tests/ui/privacy/private-in-public-warn.stderr b/tests/ui/privacy/private-in-public-warn.stderr
index 66f91ce6fd6..6497b7ff535 100644
--- a/tests/ui/privacy/private-in-public-warn.stderr
+++ b/tests/ui/privacy/private-in-public-warn.stderr
@@ -1,46 +1,58 @@
-error: private type `types::Priv` in public interface (error E0446)
+error: type `types::Priv` is more private than the item `types::Alias`
   --> $DIR/private-in-public-warn.rs:15:5
    |
 LL |     pub type Alias = Priv;
-   |     ^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^ type alias `types::Alias` is reachable at visibility `pub(crate)`
    |
-   = 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>
+note: but type `types::Priv` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public-warn.rs:9:5
+   |
+LL |     struct Priv;
+   |     ^^^^^^^^^^^
 note: the lint level is defined here
   --> $DIR/private-in-public-warn.rs:5:9
    |
-LL | #![deny(private_in_public)]
-   |         ^^^^^^^^^^^^^^^^^
+LL | #![deny(private_interfaces, private_bounds)]
+   |         ^^^^^^^^^^^^^^^^^^
 
-error: private type `types::Priv` in public interface (error E0446)
-  --> $DIR/private-in-public-warn.rs:18:12
+error: type `types::Priv` is more private than the item `E::V1::0`
+  --> $DIR/private-in-public-warn.rs:17:12
    |
 LL |         V1(Priv),
-   |            ^^^^
+   |            ^^^^ field `E::V1::0` is reachable at visibility `pub(crate)`
+   |
+note: but type `types::Priv` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public-warn.rs:9:5
    |
-   = 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>
+LL |     struct Priv;
+   |     ^^^^^^^^^^^
 
-error: private type `types::Priv` in public interface (error E0446)
-  --> $DIR/private-in-public-warn.rs:20:14
+error: type `types::Priv` is more private than the item `E::V2::field`
+  --> $DIR/private-in-public-warn.rs:18:14
    |
 LL |         V2 { field: Priv },
-   |              ^^^^^^^^^^^
+   |              ^^^^^^^^^^^ field `E::V2::field` is reachable at visibility `pub(crate)`
+   |
+note: but type `types::Priv` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public-warn.rs:9:5
    |
-   = 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>
+LL |     struct Priv;
+   |     ^^^^^^^^^^^
 
-error: private type `types::Priv` in public interface (error E0446)
-  --> $DIR/private-in-public-warn.rs:24:9
+error: type `types::Priv` is more private than the item `Tr::C`
+  --> $DIR/private-in-public-warn.rs:21:9
    |
 LL |         const C: Priv = Priv;
-   |         ^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^ associated constant `Tr::C` is reachable at visibility `pub(crate)`
    |
-   = 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>
+note: but type `types::Priv` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public-warn.rs:9:5
+   |
+LL |     struct Priv;
+   |     ^^^^^^^^^^^
 
 error[E0446]: private type `types::Priv` in public interface
-  --> $DIR/private-in-public-warn.rs:26:9
+  --> $DIR/private-in-public-warn.rs:22:9
    |
 LL |     struct Priv;
    |     ----------- `types::Priv` declared as private
@@ -48,53 +60,68 @@ LL |     struct Priv;
 LL |         type Alias = Priv;
    |         ^^^^^^^^^^ can't leak private type
 
-error: private type `types::Priv` in public interface (error E0446)
-  --> $DIR/private-in-public-warn.rs:27:9
+error: type `types::Priv` is more private than the item `Tr::f1`
+  --> $DIR/private-in-public-warn.rs:23:9
    |
 LL |         fn f1(arg: Priv) {}
-   |         ^^^^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^^^ associated function `Tr::f1` is reachable at visibility `pub(crate)`
+   |
+note: but type `types::Priv` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public-warn.rs:9:5
    |
-   = 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>
+LL |     struct Priv;
+   |     ^^^^^^^^^^^
 
-error: private type `types::Priv` in public interface (error E0446)
-  --> $DIR/private-in-public-warn.rs:29:9
+error: type `types::Priv` is more private than the item `Tr::f2`
+  --> $DIR/private-in-public-warn.rs:24:9
    |
 LL |         fn f2() -> Priv { panic!() }
-   |         ^^^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^^ associated function `Tr::f2` is reachable at visibility `pub(crate)`
+   |
+note: but type `types::Priv` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public-warn.rs:9:5
    |
-   = 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>
+LL |     struct Priv;
+   |     ^^^^^^^^^^^
 
-error: private type `types::Priv` in public interface (error E0446)
-  --> $DIR/private-in-public-warn.rs:33:9
+error: type `types::Priv` is more private than the item `types::ES`
+  --> $DIR/private-in-public-warn.rs:27:9
    |
 LL |         pub static ES: Priv;
-   |         ^^^^^^^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^^^^^^ static `types::ES` is reachable at visibility `pub(crate)`
    |
-   = 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>
+note: but type `types::Priv` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public-warn.rs:9:5
+   |
+LL |     struct Priv;
+   |     ^^^^^^^^^^^
 
-error: private type `types::Priv` in public interface (error E0446)
-  --> $DIR/private-in-public-warn.rs:35:9
+error: type `types::Priv` is more private than the item `types::ef1`
+  --> $DIR/private-in-public-warn.rs:28:9
    |
 LL |         pub fn ef1(arg: Priv);
-   |         ^^^^^^^^^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^^^^^^^^ function `types::ef1` is reachable at visibility `pub(crate)`
    |
-   = 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>
+note: but type `types::Priv` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public-warn.rs:9:5
+   |
+LL |     struct Priv;
+   |     ^^^^^^^^^^^
 
-error: private type `types::Priv` in public interface (error E0446)
-  --> $DIR/private-in-public-warn.rs:37:9
+error: type `types::Priv` is more private than the item `types::ef2`
+  --> $DIR/private-in-public-warn.rs:29:9
    |
 LL |         pub fn ef2() -> Priv;
-   |         ^^^^^^^^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^^^^^^^ function `types::ef2` is reachable at visibility `pub(crate)`
+   |
+note: but type `types::Priv` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public-warn.rs:9:5
    |
-   = 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>
+LL |     struct Priv;
+   |     ^^^^^^^^^^^
 
 error[E0446]: private type `types::Priv` in public interface
-  --> $DIR/private-in-public-warn.rs:41:9
+  --> $DIR/private-in-public-warn.rs:32:9
    |
 LL |     struct Priv;
    |     ----------- `types::Priv` declared as private
@@ -102,134 +129,181 @@ LL |     struct Priv;
 LL |         type Alias = Priv;
    |         ^^^^^^^^^^ can't leak private type
 
-error: private trait `traits::PrivTr` in public interface (error E0445)
-  --> $DIR/private-in-public-warn.rs:50:5
+error: trait `traits::PrivTr` is more private than the item `traits::Alias`
+  --> $DIR/private-in-public-warn.rs:41:5
    |
 LL |     pub type Alias<T: PrivTr> = T;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ type alias `traits::Alias` is reachable at visibility `pub(crate)`
    |
-   = 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>
+note: but trait `traits::PrivTr` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public-warn.rs:37:5
+   |
+LL |     trait PrivTr {}
+   |     ^^^^^^^^^^^^
+note: the lint level is defined here
+  --> $DIR/private-in-public-warn.rs:5:29
+   |
+LL | #![deny(private_interfaces, private_bounds)]
+   |                             ^^^^^^^^^^^^^^
 
-error: private trait `traits::PrivTr` in public interface (error E0445)
-  --> $DIR/private-in-public-warn.rs:53:5
+error: trait `traits::PrivTr` is more private than the item `traits::Tr1`
+  --> $DIR/private-in-public-warn.rs:43:5
    |
 LL |     pub trait Tr1: PrivTr {}
-   |     ^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^ trait `traits::Tr1` is reachable at visibility `pub(crate)`
+   |
+note: but trait `traits::PrivTr` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public-warn.rs:37:5
    |
-   = 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>
+LL |     trait PrivTr {}
+   |     ^^^^^^^^^^^^
 
-error: private trait `traits::PrivTr` in public interface (error E0445)
-  --> $DIR/private-in-public-warn.rs:55:5
+error: trait `traits::PrivTr` is more private than the item `traits::Tr2`
+  --> $DIR/private-in-public-warn.rs:44:5
    |
 LL |     pub trait Tr2<T: PrivTr> {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^ trait `traits::Tr2` is reachable at visibility `pub(crate)`
+   |
+note: but trait `traits::PrivTr` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public-warn.rs:37:5
    |
-   = 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>
+LL |     trait PrivTr {}
+   |     ^^^^^^^^^^^^
 
-error: private trait `traits::PrivTr` in public interface (error E0445)
-  --> $DIR/private-in-public-warn.rs:58:9
+error: trait `traits::PrivTr` is more private than the item `traits::Tr3::Alias`
+  --> $DIR/private-in-public-warn.rs:46:9
    |
 LL |         type Alias: PrivTr;
-   |         ^^^^^^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^^^^^ associated type `traits::Tr3::Alias` is reachable at visibility `pub(crate)`
+   |
+note: but trait `traits::PrivTr` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public-warn.rs:37:5
    |
-   = 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>
+LL |     trait PrivTr {}
+   |     ^^^^^^^^^^^^
 
-error: private trait `traits::PrivTr` in public interface (error E0445)
-  --> $DIR/private-in-public-warn.rs:61:9
+error: trait `traits::PrivTr` is more private than the item `traits::Tr3::f`
+  --> $DIR/private-in-public-warn.rs:48:9
    |
 LL |         fn f<T: PrivTr>(arg: T) {}
-   |         ^^^^^^^^^^^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^^^^^^^^^^ associated function `traits::Tr3::f` is reachable at visibility `pub(crate)`
    |
-   = 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>
+note: but trait `traits::PrivTr` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public-warn.rs:37:5
+   |
+LL |     trait PrivTr {}
+   |     ^^^^^^^^^^^^
 
-error: private trait `traits::PrivTr` in public interface (error E0445)
-  --> $DIR/private-in-public-warn.rs:64:5
+error: trait `traits::PrivTr` is more private than the item `traits::Pub<T>`
+  --> $DIR/private-in-public-warn.rs:50:5
    |
 LL |     impl<T: PrivTr> Pub<T> {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^ implementation `traits::Pub<T>` is reachable at visibility `pub(crate)`
    |
-   = 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>
+note: but trait `traits::PrivTr` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public-warn.rs:37:5
+   |
+LL |     trait PrivTr {}
+   |     ^^^^^^^^^^^^
 
-error: private trait `traits_where::PrivTr` in public interface (error E0445)
-  --> $DIR/private-in-public-warn.rs:74:5
+error: trait `traits_where::PrivTr` is more private than the item `traits_where::Alias`
+  --> $DIR/private-in-public-warn.rs:59:5
    |
 LL |     pub type Alias<T> where T: PrivTr = T;
-   |     ^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^ type alias `traits_where::Alias` is reachable at visibility `pub(crate)`
    |
-   = 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>
+note: but trait `traits_where::PrivTr` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public-warn.rs:55:5
+   |
+LL |     trait PrivTr {}
+   |     ^^^^^^^^^^^^
 
-error: private trait `traits_where::PrivTr` in public interface (error E0445)
-  --> $DIR/private-in-public-warn.rs:78:5
+error: trait `traits_where::PrivTr` is more private than the item `traits_where::Tr2`
+  --> $DIR/private-in-public-warn.rs:62:5
    |
 LL |     pub trait Tr2<T> where T: PrivTr {}
-   |     ^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^ trait `traits_where::Tr2` is reachable at visibility `pub(crate)`
+   |
+note: but trait `traits_where::PrivTr` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public-warn.rs:55:5
    |
-   = 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>
+LL |     trait PrivTr {}
+   |     ^^^^^^^^^^^^
 
-error: private trait `traits_where::PrivTr` in public interface (error E0445)
-  --> $DIR/private-in-public-warn.rs:82:9
+error: trait `traits_where::PrivTr` is more private than the item `traits_where::Tr3::f`
+  --> $DIR/private-in-public-warn.rs:65:9
    |
 LL |         fn f<T>(arg: T) where T: PrivTr {}
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ associated function `traits_where::Tr3::f` is reachable at visibility `pub(crate)`
    |
-   = 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>
+note: but trait `traits_where::PrivTr` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public-warn.rs:55:5
+   |
+LL |     trait PrivTr {}
+   |     ^^^^^^^^^^^^
 
-error: private trait `traits_where::PrivTr` in public interface (error E0445)
-  --> $DIR/private-in-public-warn.rs:86:5
+error: trait `traits_where::PrivTr` is more private than the item `traits_where::Pub<T>`
+  --> $DIR/private-in-public-warn.rs:68:5
    |
 LL |     impl<T> Pub<T> where T: PrivTr {}
-   |     ^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^ implementation `traits_where::Pub<T>` is reachable at visibility `pub(crate)`
+   |
+note: but trait `traits_where::PrivTr` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public-warn.rs:55:5
    |
-   = 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>
+LL |     trait PrivTr {}
+   |     ^^^^^^^^^^^^
 
-error: private trait `generics::PrivTr<generics::Pub>` in public interface (error E0445)
-  --> $DIR/private-in-public-warn.rs:98:5
+error: trait `generics::PrivTr<generics::Pub>` is more private than the item `generics::Tr1`
+  --> $DIR/private-in-public-warn.rs:79:5
    |
 LL |     pub trait Tr1: PrivTr<Pub> {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ trait `generics::Tr1` is reachable at visibility `pub(crate)`
+   |
+note: but trait `generics::PrivTr<generics::Pub>` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public-warn.rs:76:5
    |
-   = 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>
+LL |     trait PrivTr<T> {}
+   |     ^^^^^^^^^^^^^^^
 
-error: private type `generics::Priv` in public interface (error E0446)
-  --> $DIR/private-in-public-warn.rs:101:5
+error: type `generics::Priv` is more private than the item `generics::Tr2`
+  --> $DIR/private-in-public-warn.rs:81:5
    |
 LL |     pub trait Tr2: PubTr<Priv> {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ trait `generics::Tr2` is reachable at visibility `pub(crate)`
+   |
+note: but type `generics::Priv` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public-warn.rs:74:5
    |
-   = 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>
+LL |     struct Priv<T = u8>(T);
+   |     ^^^^^^^^^^^^^^^^^^^
 
-error: private type `generics::Priv` in public interface (error E0446)
-  --> $DIR/private-in-public-warn.rs:103:5
+error: type `generics::Priv` is more private than the item `generics::Tr3`
+  --> $DIR/private-in-public-warn.rs:82:5
    |
 LL |     pub trait Tr3: PubTr<[Priv; 1]> {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait `generics::Tr3` is reachable at visibility `pub(crate)`
    |
-   = 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>
+note: but type `generics::Priv` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public-warn.rs:74:5
+   |
+LL |     struct Priv<T = u8>(T);
+   |     ^^^^^^^^^^^^^^^^^^^
 
-error: private type `generics::Priv` in public interface (error E0446)
-  --> $DIR/private-in-public-warn.rs:105:5
+error: type `generics::Priv` is more private than the item `Tr4`
+  --> $DIR/private-in-public-warn.rs:83:5
    |
 LL |     pub trait Tr4: PubTr<Pub<Priv>> {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait `Tr4` is reachable at visibility `pub(crate)`
+   |
+note: but type `generics::Priv` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public-warn.rs:74:5
    |
-   = 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>
+LL |     struct Priv<T = u8>(T);
+   |     ^^^^^^^^^^^^^^^^^^^
 
 error[E0446]: private type `impls::Priv` in public interface
-  --> $DIR/private-in-public-warn.rs:132:9
+  --> $DIR/private-in-public-warn.rs:109:9
    |
 LL |     struct Priv;
    |     ----------- `impls::Priv` declared as private
@@ -237,17 +311,20 @@ LL |     struct Priv;
 LL |         type Alias = Priv;
    |         ^^^^^^^^^^ can't leak private type
 
-error: private type `aliases_pub::Priv` in public interface (error E0446)
-  --> $DIR/private-in-public-warn.rs:203:9
+error: type `aliases_pub::Priv` is more private than the item `aliases_pub::<impl Pub2>::f`
+  --> $DIR/private-in-public-warn.rs:180:9
    |
 LL |         pub fn f(arg: Priv) {}
-   |         ^^^^^^^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^^^^^^ associated function `aliases_pub::<impl Pub2>::f` is reachable at visibility `pub(crate)`
    |
-   = 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>
+note: but type `aliases_pub::Priv` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public-warn.rs:153:5
+   |
+LL |     struct Priv;
+   |     ^^^^^^^^^^^
 
 error[E0446]: private type `aliases_pub::Priv` in public interface
-  --> $DIR/private-in-public-warn.rs:207:9
+  --> $DIR/private-in-public-warn.rs:183:9
    |
 LL |     struct Priv;
    |     ----------- `aliases_pub::Priv` declared as private
@@ -256,7 +333,7 @@ LL |         type Check = Priv;
    |         ^^^^^^^^^^ can't leak private type
 
 error[E0446]: private type `aliases_pub::Priv` in public interface
-  --> $DIR/private-in-public-warn.rs:210:9
+  --> $DIR/private-in-public-warn.rs:186:9
    |
 LL |     struct Priv;
    |     ----------- `aliases_pub::Priv` declared as private
@@ -265,7 +342,7 @@ LL |         type Check = Priv;
    |         ^^^^^^^^^^ can't leak private type
 
 error[E0446]: private type `aliases_pub::Priv` in public interface
-  --> $DIR/private-in-public-warn.rs:213:9
+  --> $DIR/private-in-public-warn.rs:189:9
    |
 LL |     struct Priv;
    |     ----------- `aliases_pub::Priv` declared as private
@@ -274,7 +351,7 @@ LL |         type Check = Priv;
    |         ^^^^^^^^^^ can't leak private type
 
 error[E0446]: private type `aliases_pub::Priv` in public interface
-  --> $DIR/private-in-public-warn.rs:216:9
+  --> $DIR/private-in-public-warn.rs:192:9
    |
 LL |     struct Priv;
    |     ----------- `aliases_pub::Priv` declared as private
@@ -282,35 +359,44 @@ LL |     struct Priv;
 LL |         type Check = Priv;
    |         ^^^^^^^^^^ can't leak private type
 
-error: private trait `PrivTr1` in public interface (error E0445)
-  --> $DIR/private-in-public-warn.rs:246:5
+error: trait `PrivTr1` is more private than the item `aliases_priv::Tr1`
+  --> $DIR/private-in-public-warn.rs:222:5
    |
 LL |     pub trait Tr1: PrivUseAliasTr {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait `aliases_priv::Tr1` is reachable at visibility `pub(crate)`
    |
-   = 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>
+note: but trait `PrivTr1` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public-warn.rs:208:5
+   |
+LL |     trait PrivTr1<T = u8> {
+   |     ^^^^^^^^^^^^^^^^^^^^^
 
-error: private trait `PrivTr1<Priv2>` in public interface (error E0445)
-  --> $DIR/private-in-public-warn.rs:249:5
+error: trait `PrivTr1<Priv2>` is more private than the item `aliases_priv::Tr2`
+  --> $DIR/private-in-public-warn.rs:224:5
    |
 LL |     pub trait Tr2: PrivUseAliasTr<PrivAlias> {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait `aliases_priv::Tr2` is reachable at visibility `pub(crate)`
    |
-   = 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>
+note: but trait `PrivTr1<Priv2>` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public-warn.rs:208:5
+   |
+LL |     trait PrivTr1<T = u8> {
+   |     ^^^^^^^^^^^^^^^^^^^^^
 
-error: private type `Priv2` in public interface (error E0446)
-  --> $DIR/private-in-public-warn.rs:249:5
+error: type `Priv2` is more private than the item `aliases_priv::Tr2`
+  --> $DIR/private-in-public-warn.rs:224:5
    |
 LL |     pub trait Tr2: PrivUseAliasTr<PrivAlias> {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait `aliases_priv::Tr2` is reachable at visibility `pub(crate)`
+   |
+note: but type `Priv2` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public-warn.rs:206:5
    |
-   = 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>
+LL |     struct Priv2;
+   |     ^^^^^^^^^^^^
 
 warning: bounds on generic parameters are not enforced in type aliases
-  --> $DIR/private-in-public-warn.rs:50:23
+  --> $DIR/private-in-public-warn.rs:41:23
    |
 LL |     pub type Alias<T: PrivTr> = T;
    |                       ^^^^^^
@@ -323,7 +409,7 @@ LL +     pub type Alias<T> = T;
    |
 
 warning: where clauses are not enforced in type aliases
-  --> $DIR/private-in-public-warn.rs:74:29
+  --> $DIR/private-in-public-warn.rs:59:29
    |
 LL |     pub type Alias<T> where T: PrivTr = T;
    |                             ^^^^^^^^^
diff --git a/tests/ui/privacy/private-in-public.rs b/tests/ui/privacy/private-in-public.rs
index dbd1c483f81..f54f9e38faa 100644
--- a/tests/ui/privacy/private-in-public.rs
+++ b/tests/ui/privacy/private-in-public.rs
@@ -1,3 +1,5 @@
+// check-pass
+
 // Private types and traits are not allowed in public interfaces.
 // This test also ensures that the checks are performed even inside private modules.
 
@@ -10,16 +12,16 @@ mod types {
         type Alias;
     }
 
-    pub const C: Priv = Priv; //~ ERROR private type `types::Priv` in public interface
-    pub static S: Priv = Priv; //~ ERROR private type `types::Priv` in public interface
-    pub fn f1(arg: Priv) {} //~ ERROR private type `types::Priv` in public interface
-    pub fn f2() -> Priv { panic!() } //~ ERROR private type `types::Priv` in public interface
-    pub struct S1(pub Priv); //~ ERROR private type `types::Priv` in public interface
-    pub struct S2 { pub field: Priv } //~ ERROR private type `types::Priv` in public interface
+    pub const C: Priv = Priv; //~ WARNING type `types::Priv` is more private than the item `C`
+    pub static S: Priv = Priv; //~ WARNING type `types::Priv` is more private than the item `S`
+    pub fn f1(arg: Priv) {} //~ WARNING `types::Priv` is more private than the item `types::f1`
+    pub fn f2() -> Priv { panic!() } //~ WARNING type `types::Priv` is more private than the item `types::f2`
+    pub struct S1(pub Priv); //~ WARNING type `types::Priv` is more private than the item `types::S1::0`
+    pub struct S2 { pub field: Priv } //~ WARNING `types::Priv` is more private than the item `S2::field`
     impl Pub {
-        pub const C: Priv = Priv; //~ ERROR private type `types::Priv` in public interface
-        pub fn f1(arg: Priv) {} //~ ERROR private type `types::Priv` in public interface
-        pub fn f2() -> Priv { panic!() } //~ ERROR private type `types::Priv` in public interface
+        pub const C: Priv = Priv; //~ WARNING type `types::Priv` is more private than the item `types::Pub::C`
+        pub fn f1(arg: Priv) {} //~ WARNING type `types::Priv` is more private than the item `types::Pub::f1`
+        pub fn f2() -> Priv { panic!() } //~ WARNING type `types::Priv` is more private than the item `types::Pub::f2`
     }
 }
 
@@ -28,11 +30,11 @@ mod traits {
     pub struct Pub<T>(T);
     pub trait PubTr {}
 
-    pub enum E<T: PrivTr> { V(T) } //~ ERROR private trait `traits::PrivTr` in public interface
-    pub fn f<T: PrivTr>(arg: T) {} //~ ERROR private trait `traits::PrivTr` in public interface
-    pub struct S1<T: PrivTr>(T); //~ ERROR private trait `traits::PrivTr` in public interface
-    impl<T: PrivTr> Pub<T> { //~ ERROR private trait `traits::PrivTr` in public interface
-        pub fn f<U: PrivTr>(arg: U) {} //~ ERROR private trait `traits::PrivTr` in public interface
+    pub enum E<T: PrivTr> { V(T) } //~ WARNING trait `traits::PrivTr` is more private than the item `traits::E`
+    pub fn f<T: PrivTr>(arg: T) {} //~ WARNING trait `traits::PrivTr` is more private than the item `traits::f`
+    pub struct S1<T: PrivTr>(T); //~ WARNING trait `traits::PrivTr` is more private than the item `traits::S1`
+    impl<T: PrivTr> Pub<T> { //~ WARNING trait `traits::PrivTr` is more private than the item `traits::Pub<T>`
+        pub fn f<U: PrivTr>(arg: U) {} //~ WARNING trait `traits::PrivTr` is more private than the item `traits::Pub::<T>::f`
     }
 }
 
@@ -42,15 +44,15 @@ mod traits_where {
     pub trait PubTr {}
 
     pub enum E<T> where T: PrivTr { V(T) }
-    //~^ ERROR private trait `traits_where::PrivTr` in public interface
+    //~^ WARNING trait `traits_where::PrivTr` is more private than the item `traits_where::E`
     pub fn f<T>(arg: T) where T: PrivTr {}
-    //~^ ERROR private trait `traits_where::PrivTr` in public interface
+    //~^ WARNING trait `traits_where::PrivTr` is more private than the item `traits_where::f`
     pub struct S1<T>(T) where T: PrivTr;
-    //~^ ERROR private trait `traits_where::PrivTr` in public interface
+    //~^ WARNING trait `traits_where::PrivTr` is more private than the item `traits_where::S1`
     impl<T> Pub<T> where T: PrivTr {
-    //~^ ERROR private trait `traits_where::PrivTr` in public interface
+    //~^ WARNING trait `traits_where::PrivTr` is more private than the item `traits_where::Pub<T>`
         pub fn f<U>(arg: U) where U: PrivTr {}
-        //~^ ERROR private trait `traits_where::PrivTr` in public interface
+        //~^ WARNING trait `traits_where::PrivTr` is more private than the item `traits_where::Pub::<T>::f`
     }
 }
 
@@ -60,10 +62,10 @@ mod generics {
     trait PrivTr<T> {}
     pub trait PubTr<T> {}
 
-    pub fn f1(arg: [Priv; 1]) {} //~ ERROR private type `generics::Priv` in public interface
-    pub fn f2(arg: Pub<Priv>) {} //~ ERROR private type `generics::Priv` in public interface
+    pub fn f1(arg: [Priv; 1]) {} //~ WARNING type `generics::Priv` is more private than the item `generics::f1`
+    pub fn f2(arg: Pub<Priv>) {} //~ WARNING type `generics::Priv` is more private than the item `generics::f2`
     pub fn f3(arg: Priv<Pub>) {}
-    //~^ ERROR private type `generics::Priv<generics::Pub>` in public interface
+    //~^ WARNING type `generics::Priv<generics::Pub>` is more private than the item `generics::f3`
 }
 
 mod impls {
@@ -77,7 +79,7 @@ mod impls {
     }
 
     impl Pub {
-        pub fn f(arg: Priv) {} //~ ERROR private type `impls::Priv` in public interface
+        pub fn f(arg: Priv) {} //~ WARNING type `impls::Priv` is more private than the item `impls::Pub::f`
     }
 }
 
@@ -102,11 +104,11 @@ mod aliases_pub {
 
     // This should be OK, but associated type aliases are not substituted yet
     pub fn f3(arg: <Priv as PrivTr>::Assoc) {}
-    //~^ ERROR private trait `aliases_pub::PrivTr` in public interface
-    //~| ERROR private type `aliases_pub::Priv` in public interface
+    //~^ WARNING trait `aliases_pub::PrivTr` is more private than the item `aliases_pub::f3`
+    //~| WARNING type `aliases_pub::Priv` is more private than the item `aliases_pub::f3`
 
     impl PrivUseAlias {
-        pub fn f(arg: Priv) {} //~ ERROR private type `aliases_pub::Priv` in public interface
+        pub fn f(arg: Priv) {}
     }
 }
 
@@ -128,11 +130,11 @@ mod aliases_priv {
     }
     impl PrivTr for Priv {}
 
-    pub fn f1(arg: PrivUseAlias) {} //~ ERROR private type `Priv1` in public interface
-    pub fn f2(arg: PrivAlias) {} //~ ERROR private type `Priv2` in public interface
+    pub fn f1(arg: PrivUseAlias) {} //~ WARNING type `Priv1` is more private than the item `aliases_priv::f1`
+    pub fn f2(arg: PrivAlias) {} //~ WARNING type `Priv2` is more private than the item `aliases_priv::f2`
     pub fn f3(arg: <Priv as PrivTr>::Assoc) {}
-    //~^ ERROR private trait `aliases_priv::PrivTr` in public interface
-    //~| ERROR private type `aliases_priv::Priv` in public interface
+    //~^ WARNING trait `aliases_priv::PrivTr` is more private than the item `aliases_priv::f3`
+    //~| WARNING type `aliases_priv::Priv` is more private than the item `aliases_priv::f3`
 }
 
 mod aliases_params {
@@ -141,8 +143,8 @@ mod aliases_params {
     type Result<T> = ::std::result::Result<T, Priv>;
 
     pub fn f2(arg: PrivAliasGeneric) {}
-    //~^ ERROR private type `aliases_params::Priv` in public interface
-    pub fn f3(arg: Result<u8>) {} //~ ERROR private type `aliases_params::Priv` in public interface
+    //~^ WARNING type `aliases_params::Priv` is more private than the item `aliases_params::f2`
+    pub fn f3(arg: Result<u8>) {} //~ WARNING type `aliases_params::Priv` is more private than the item `aliases_params::f3`
 }
 
 fn main() {}
diff --git a/tests/ui/privacy/private-in-public.stderr b/tests/ui/privacy/private-in-public.stderr
index 887eebf53ef..d8f9fd00716 100644
--- a/tests/ui/privacy/private-in-public.stderr
+++ b/tests/ui/privacy/private-in-public.stderr
@@ -1,292 +1,376 @@
-error[E0446]: private type `types::Priv` in public interface
-  --> $DIR/private-in-public.rs:13:5
+warning: type `types::Priv` is more private than the item `C`
+  --> $DIR/private-in-public.rs:15:5
    |
-LL |     struct Priv;
-   |     ----------- `types::Priv` declared as private
-...
 LL |     pub const C: Priv = Priv;
-   |     ^^^^^^^^^^^^^^^^^ can't leak private type
-
-error[E0446]: private type `types::Priv` in public interface
-  --> $DIR/private-in-public.rs:14:5
+   |     ^^^^^^^^^^^^^^^^^ constant `C` is reachable at visibility `pub(crate)`
    |
-LL |     struct Priv;
-   |     ----------- `types::Priv` declared as private
-...
-LL |     pub static S: Priv = Priv;
-   |     ^^^^^^^^^^^^^^^^^^ can't leak private type
-
-error[E0446]: private type `types::Priv` in public interface
-  --> $DIR/private-in-public.rs:15:5
+note: but type `types::Priv` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public.rs:9:5
    |
 LL |     struct Priv;
-   |     ----------- `types::Priv` declared as private
-...
-LL |     pub fn f1(arg: Priv) {}
-   |     ^^^^^^^^^^^^^^^^^^^^ can't leak private type
+   |     ^^^^^^^^^^^
+   = note: `#[warn(private_interfaces)]` on by default
 
-error[E0446]: private type `types::Priv` in public interface
+warning: type `types::Priv` is more private than the item `S`
   --> $DIR/private-in-public.rs:16:5
    |
+LL |     pub static S: Priv = Priv;
+   |     ^^^^^^^^^^^^^^^^^^ static `S` is reachable at visibility `pub(crate)`
+   |
+note: but type `types::Priv` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public.rs:9:5
+   |
 LL |     struct Priv;
-   |     ----------- `types::Priv` declared as private
-...
-LL |     pub fn f2() -> Priv { panic!() }
-   |     ^^^^^^^^^^^^^^^^^^^ can't leak private type
+   |     ^^^^^^^^^^^
 
-error[E0446]: private type `types::Priv` in public interface
-  --> $DIR/private-in-public.rs:17:19
+warning: type `types::Priv` is more private than the item `types::f1`
+  --> $DIR/private-in-public.rs:17:5
+   |
+LL |     pub fn f1(arg: Priv) {}
+   |     ^^^^^^^^^^^^^^^^^^^^ function `types::f1` is reachable at visibility `pub(crate)`
+   |
+note: but type `types::Priv` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public.rs:9:5
    |
 LL |     struct Priv;
-   |     ----------- `types::Priv` declared as private
-...
-LL |     pub struct S1(pub Priv);
-   |                   ^^^^^^^^ can't leak private type
+   |     ^^^^^^^^^^^
 
-error[E0446]: private type `types::Priv` in public interface
-  --> $DIR/private-in-public.rs:18:21
+warning: type `types::Priv` is more private than the item `types::f2`
+  --> $DIR/private-in-public.rs:18:5
+   |
+LL |     pub fn f2() -> Priv { panic!() }
+   |     ^^^^^^^^^^^^^^^^^^^ function `types::f2` is reachable at visibility `pub(crate)`
+   |
+note: but type `types::Priv` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public.rs:9:5
    |
 LL |     struct Priv;
-   |     ----------- `types::Priv` declared as private
-...
-LL |     pub struct S2 { pub field: Priv }
-   |                     ^^^^^^^^^^^^^^^ can't leak private type
+   |     ^^^^^^^^^^^
 
-error[E0446]: private type `types::Priv` in public interface
-  --> $DIR/private-in-public.rs:20:9
+warning: type `types::Priv` is more private than the item `types::S1::0`
+  --> $DIR/private-in-public.rs:19:19
+   |
+LL |     pub struct S1(pub Priv);
+   |                   ^^^^^^^^ field `types::S1::0` is reachable at visibility `pub(crate)`
+   |
+note: but type `types::Priv` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public.rs:9:5
    |
 LL |     struct Priv;
-   |     ----------- `types::Priv` declared as private
-...
-LL |         pub const C: Priv = Priv;
-   |         ^^^^^^^^^^^^^^^^^ can't leak private type
+   |     ^^^^^^^^^^^
 
-error[E0446]: private type `types::Priv` in public interface
-  --> $DIR/private-in-public.rs:21:9
+warning: type `types::Priv` is more private than the item `S2::field`
+  --> $DIR/private-in-public.rs:20:21
+   |
+LL |     pub struct S2 { pub field: Priv }
+   |                     ^^^^^^^^^^^^^^^ field `S2::field` is reachable at visibility `pub(crate)`
+   |
+note: but type `types::Priv` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public.rs:9:5
    |
 LL |     struct Priv;
-   |     ----------- `types::Priv` declared as private
-...
-LL |         pub fn f1(arg: Priv) {}
-   |         ^^^^^^^^^^^^^^^^^^^^ can't leak private type
+   |     ^^^^^^^^^^^
 
-error[E0446]: private type `types::Priv` in public interface
+warning: type `types::Priv` is more private than the item `types::Pub::C`
   --> $DIR/private-in-public.rs:22:9
    |
+LL |         pub const C: Priv = Priv;
+   |         ^^^^^^^^^^^^^^^^^ associated constant `types::Pub::C` is reachable at visibility `pub(crate)`
+   |
+note: but type `types::Priv` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public.rs:9:5
+   |
 LL |     struct Priv;
-   |     ----------- `types::Priv` declared as private
-...
-LL |         pub fn f2() -> Priv { panic!() }
-   |         ^^^^^^^^^^^^^^^^^^^ can't leak private type
+   |     ^^^^^^^^^^^
 
-error[E0445]: private trait `traits::PrivTr` in public interface
-  --> $DIR/private-in-public.rs:31:5
+warning: type `types::Priv` is more private than the item `types::Pub::f1`
+  --> $DIR/private-in-public.rs:23:9
    |
-LL |     trait PrivTr {}
-   |     ------------ `traits::PrivTr` declared as private
-...
-LL |     pub enum E<T: PrivTr> { V(T) }
-   |     ^^^^^^^^^^^^^^^^^^^^^ can't leak private trait
+LL |         pub fn f1(arg: Priv) {}
+   |         ^^^^^^^^^^^^^^^^^^^^ associated function `types::Pub::f1` is reachable at visibility `pub(crate)`
+   |
+note: but type `types::Priv` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public.rs:9:5
+   |
+LL |     struct Priv;
+   |     ^^^^^^^^^^^
 
-error[E0445]: private trait `traits::PrivTr` in public interface
-  --> $DIR/private-in-public.rs:32:5
+warning: type `types::Priv` is more private than the item `types::Pub::f2`
+  --> $DIR/private-in-public.rs:24:9
    |
-LL |     trait PrivTr {}
-   |     ------------ `traits::PrivTr` declared as private
-...
-LL |     pub fn f<T: PrivTr>(arg: T) {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private trait
+LL |         pub fn f2() -> Priv { panic!() }
+   |         ^^^^^^^^^^^^^^^^^^^ associated function `types::Pub::f2` is reachable at visibility `pub(crate)`
+   |
+note: but type `types::Priv` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public.rs:9:5
+   |
+LL |     struct Priv;
+   |     ^^^^^^^^^^^
 
-error[E0445]: private trait `traits::PrivTr` in public interface
+warning: trait `traits::PrivTr` is more private than the item `traits::E`
   --> $DIR/private-in-public.rs:33:5
    |
+LL |     pub enum E<T: PrivTr> { V(T) }
+   |     ^^^^^^^^^^^^^^^^^^^^^ enum `traits::E` is reachable at visibility `pub(crate)`
+   |
+note: but trait `traits::PrivTr` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public.rs:29:5
+   |
 LL |     trait PrivTr {}
-   |     ------------ `traits::PrivTr` declared as private
-...
-LL |     pub struct S1<T: PrivTr>(T);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private trait
+   |     ^^^^^^^^^^^^
+   = note: `#[warn(private_bounds)]` on by default
 
-error[E0445]: private trait `traits::PrivTr` in public interface
+warning: trait `traits::PrivTr` is more private than the item `traits::f`
   --> $DIR/private-in-public.rs:34:5
    |
+LL |     pub fn f<T: PrivTr>(arg: T) {}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ function `traits::f` is reachable at visibility `pub(crate)`
+   |
+note: but trait `traits::PrivTr` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public.rs:29:5
+   |
 LL |     trait PrivTr {}
-   |     ------------ `traits::PrivTr` declared as private
-...
-LL |     impl<T: PrivTr> Pub<T> {
-   |     ^^^^^^^^^^^^^^^^^^^^^^ can't leak private trait
+   |     ^^^^^^^^^^^^
 
-error[E0445]: private trait `traits::PrivTr` in public interface
-  --> $DIR/private-in-public.rs:35:9
+warning: trait `traits::PrivTr` is more private than the item `traits::S1`
+  --> $DIR/private-in-public.rs:35:5
+   |
+LL |     pub struct S1<T: PrivTr>(T);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^ struct `traits::S1` is reachable at visibility `pub(crate)`
+   |
+note: but trait `traits::PrivTr` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public.rs:29:5
    |
 LL |     trait PrivTr {}
-   |     ------------ `traits::PrivTr` declared as private
-...
-LL |         pub fn f<U: PrivTr>(arg: U) {}
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private trait
+   |     ^^^^^^^^^^^^
 
-error[E0445]: private trait `traits_where::PrivTr` in public interface
-  --> $DIR/private-in-public.rs:44:5
+warning: trait `traits::PrivTr` is more private than the item `traits::Pub<T>`
+  --> $DIR/private-in-public.rs:36:5
+   |
+LL |     impl<T: PrivTr> Pub<T> {
+   |     ^^^^^^^^^^^^^^^^^^^^^^ implementation `traits::Pub<T>` is reachable at visibility `pub(crate)`
+   |
+note: but trait `traits::PrivTr` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public.rs:29:5
    |
 LL |     trait PrivTr {}
-   |     ------------ `traits_where::PrivTr` declared as private
-...
-LL |     pub enum E<T> where T: PrivTr { V(T) }
-   |     ^^^^^^^^^^^^^ can't leak private trait
+   |     ^^^^^^^^^^^^
 
-error[E0445]: private trait `traits_where::PrivTr` in public interface
+warning: trait `traits::PrivTr` is more private than the item `traits::Pub::<T>::f`
+  --> $DIR/private-in-public.rs:37:9
+   |
+LL |         pub fn f<U: PrivTr>(arg: U) {}
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^ associated function `traits::Pub::<T>::f` is reachable at visibility `pub(crate)`
+   |
+note: but trait `traits::PrivTr` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public.rs:29:5
+   |
+LL |     trait PrivTr {}
+   |     ^^^^^^^^^^^^
+
+warning: trait `traits_where::PrivTr` is more private than the item `traits_where::E`
   --> $DIR/private-in-public.rs:46:5
    |
+LL |     pub enum E<T> where T: PrivTr { V(T) }
+   |     ^^^^^^^^^^^^^ enum `traits_where::E` is reachable at visibility `pub(crate)`
+   |
+note: but trait `traits_where::PrivTr` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public.rs:42:5
+   |
 LL |     trait PrivTr {}
-   |     ------------ `traits_where::PrivTr` declared as private
-...
-LL |     pub fn f<T>(arg: T) where T: PrivTr {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private trait
+   |     ^^^^^^^^^^^^
 
-error[E0445]: private trait `traits_where::PrivTr` in public interface
+warning: trait `traits_where::PrivTr` is more private than the item `traits_where::f`
   --> $DIR/private-in-public.rs:48:5
    |
+LL |     pub fn f<T>(arg: T) where T: PrivTr {}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function `traits_where::f` is reachable at visibility `pub(crate)`
+   |
+note: but trait `traits_where::PrivTr` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public.rs:42:5
+   |
 LL |     trait PrivTr {}
-   |     ------------ `traits_where::PrivTr` declared as private
-...
-LL |     pub struct S1<T>(T) where T: PrivTr;
-   |     ^^^^^^^^^^^^^^^^ can't leak private trait
+   |     ^^^^^^^^^^^^
 
-error[E0445]: private trait `traits_where::PrivTr` in public interface
+warning: trait `traits_where::PrivTr` is more private than the item `traits_where::S1`
   --> $DIR/private-in-public.rs:50:5
    |
+LL |     pub struct S1<T>(T) where T: PrivTr;
+   |     ^^^^^^^^^^^^^^^^ struct `traits_where::S1` is reachable at visibility `pub(crate)`
+   |
+note: but trait `traits_where::PrivTr` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public.rs:42:5
+   |
 LL |     trait PrivTr {}
-   |     ------------ `traits_where::PrivTr` declared as private
-...
-LL |     impl<T> Pub<T> where T: PrivTr {
-   |     ^^^^^^^^^^^^^^ can't leak private trait
+   |     ^^^^^^^^^^^^
 
-error[E0445]: private trait `traits_where::PrivTr` in public interface
-  --> $DIR/private-in-public.rs:52:9
+warning: trait `traits_where::PrivTr` is more private than the item `traits_where::Pub<T>`
+  --> $DIR/private-in-public.rs:52:5
+   |
+LL |     impl<T> Pub<T> where T: PrivTr {
+   |     ^^^^^^^^^^^^^^ implementation `traits_where::Pub<T>` is reachable at visibility `pub(crate)`
+   |
+note: but trait `traits_where::PrivTr` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public.rs:42:5
    |
 LL |     trait PrivTr {}
-   |     ------------ `traits_where::PrivTr` declared as private
-...
+   |     ^^^^^^^^^^^^
+
+warning: trait `traits_where::PrivTr` is more private than the item `traits_where::Pub::<T>::f`
+  --> $DIR/private-in-public.rs:54:9
+   |
 LL |         pub fn f<U>(arg: U) where U: PrivTr {}
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private trait
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ associated function `traits_where::Pub::<T>::f` is reachable at visibility `pub(crate)`
+   |
+note: but trait `traits_where::PrivTr` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public.rs:42:5
+   |
+LL |     trait PrivTr {}
+   |     ^^^^^^^^^^^^
 
-error[E0446]: private type `generics::Priv` in public interface
-  --> $DIR/private-in-public.rs:63:5
+warning: type `generics::Priv` is more private than the item `generics::f1`
+  --> $DIR/private-in-public.rs:65:5
    |
-LL |     struct Priv<T = u8>(T);
-   |     ------------------- `generics::Priv` declared as private
-...
 LL |     pub fn f1(arg: [Priv; 1]) {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private type
-
-error[E0446]: private type `generics::Priv` in public interface
-  --> $DIR/private-in-public.rs:64:5
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ function `generics::f1` is reachable at visibility `pub(crate)`
+   |
+note: but type `generics::Priv` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public.rs:60:5
    |
 LL |     struct Priv<T = u8>(T);
-   |     ------------------- `generics::Priv` declared as private
-...
-LL |     pub fn f2(arg: Pub<Priv>) {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private type
+   |     ^^^^^^^^^^^^^^^^^^^
 
-error[E0446]: private type `generics::Priv<generics::Pub>` in public interface
-  --> $DIR/private-in-public.rs:65:5
+warning: type `generics::Priv` is more private than the item `generics::f2`
+  --> $DIR/private-in-public.rs:66:5
+   |
+LL |     pub fn f2(arg: Pub<Priv>) {}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ function `generics::f2` is reachable at visibility `pub(crate)`
+   |
+note: but type `generics::Priv` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public.rs:60:5
    |
 LL |     struct Priv<T = u8>(T);
-   |     ------------------- `generics::Priv<generics::Pub>` declared as private
-...
+   |     ^^^^^^^^^^^^^^^^^^^
+
+warning: type `generics::Priv<generics::Pub>` is more private than the item `generics::f3`
+  --> $DIR/private-in-public.rs:67:5
+   |
 LL |     pub fn f3(arg: Priv<Pub>) {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private type
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ function `generics::f3` is reachable at visibility `pub(crate)`
+   |
+note: but type `generics::Priv<generics::Pub>` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public.rs:60:5
+   |
+LL |     struct Priv<T = u8>(T);
+   |     ^^^^^^^^^^^^^^^^^^^
 
-error[E0446]: private type `impls::Priv` in public interface
-  --> $DIR/private-in-public.rs:80:9
+warning: type `impls::Priv` is more private than the item `impls::Pub::f`
+  --> $DIR/private-in-public.rs:82:9
    |
-LL |     struct Priv;
-   |     ----------- `impls::Priv` declared as private
-...
 LL |         pub fn f(arg: Priv) {}
-   |         ^^^^^^^^^^^^^^^^^^^ can't leak private type
+   |         ^^^^^^^^^^^^^^^^^^^ associated function `impls::Pub::f` is reachable at visibility `pub(crate)`
+   |
+note: but type `impls::Priv` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public.rs:72:5
+   |
+LL |     struct Priv;
+   |     ^^^^^^^^^^^
 
-error[E0445]: private trait `aliases_pub::PrivTr` in public interface
-  --> $DIR/private-in-public.rs:104:5
+warning: trait `aliases_pub::PrivTr` is more private than the item `aliases_pub::f3`
+  --> $DIR/private-in-public.rs:106:5
    |
-LL |     trait PrivTr {
-   |     ------------ `aliases_pub::PrivTr` declared as private
-...
 LL |     pub fn f3(arg: <Priv as PrivTr>::Assoc) {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private trait
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function `aliases_pub::f3` is reachable at visibility `pub(crate)`
+   |
+note: but trait `aliases_pub::PrivTr` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public.rs:100:5
+   |
+LL |     trait PrivTr {
+   |     ^^^^^^^^^^^^
 
-error[E0446]: private type `aliases_pub::Priv` in public interface
-  --> $DIR/private-in-public.rs:104:5
+warning: type `aliases_pub::Priv` is more private than the item `aliases_pub::f3`
+  --> $DIR/private-in-public.rs:106:5
    |
-LL |     struct Priv;
-   |     ----------- `aliases_pub::Priv` declared as private
-...
 LL |     pub fn f3(arg: <Priv as PrivTr>::Assoc) {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private type
-
-error[E0446]: private type `aliases_pub::Priv` in public interface
-  --> $DIR/private-in-public.rs:109:9
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function `aliases_pub::f3` is reachable at visibility `pub(crate)`
+   |
+note: but type `aliases_pub::Priv` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public.rs:87:5
    |
 LL |     struct Priv;
-   |     ----------- `aliases_pub::Priv` declared as private
-...
-LL |         pub fn f(arg: Priv) {}
-   |         ^^^^^^^^^^^^^^^^^^^ can't leak private type
+   |     ^^^^^^^^^^^
 
-error[E0446]: private type `Priv1` in public interface
-  --> $DIR/private-in-public.rs:131:5
+warning: type `Priv1` is more private than the item `aliases_priv::f1`
+  --> $DIR/private-in-public.rs:133:5
    |
-LL |     struct Priv1;
-   |     ------------ `Priv1` declared as private
-...
 LL |     pub fn f1(arg: PrivUseAlias) {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private type
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function `aliases_priv::f1` is reachable at visibility `pub(crate)`
+   |
+note: but type `Priv1` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public.rs:118:5
+   |
+LL |     struct Priv1;
+   |     ^^^^^^^^^^^^
 
-error[E0446]: private type `Priv2` in public interface
-  --> $DIR/private-in-public.rs:132:5
+warning: type `Priv2` is more private than the item `aliases_priv::f2`
+  --> $DIR/private-in-public.rs:134:5
    |
-LL |     struct Priv2;
-   |     ------------ `Priv2` declared as private
-...
 LL |     pub fn f2(arg: PrivAlias) {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private type
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ function `aliases_priv::f2` is reachable at visibility `pub(crate)`
+   |
+note: but type `Priv2` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public.rs:119:5
+   |
+LL |     struct Priv2;
+   |     ^^^^^^^^^^^^
 
-error[E0445]: private trait `aliases_priv::PrivTr` in public interface
-  --> $DIR/private-in-public.rs:133:5
+warning: trait `aliases_priv::PrivTr` is more private than the item `aliases_priv::f3`
+  --> $DIR/private-in-public.rs:135:5
    |
-LL |     trait PrivTr {
-   |     ------------ `aliases_priv::PrivTr` declared as private
-...
 LL |     pub fn f3(arg: <Priv as PrivTr>::Assoc) {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private trait
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function `aliases_priv::f3` is reachable at visibility `pub(crate)`
+   |
+note: but trait `aliases_priv::PrivTr` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public.rs:128:5
+   |
+LL |     trait PrivTr {
+   |     ^^^^^^^^^^^^
 
-error[E0446]: private type `aliases_priv::Priv` in public interface
-  --> $DIR/private-in-public.rs:133:5
+warning: type `aliases_priv::Priv` is more private than the item `aliases_priv::f3`
+  --> $DIR/private-in-public.rs:135:5
    |
-LL |     struct Priv;
-   |     ----------- `aliases_priv::Priv` declared as private
-...
 LL |     pub fn f3(arg: <Priv as PrivTr>::Assoc) {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private type
-
-error[E0446]: private type `aliases_params::Priv` in public interface
-  --> $DIR/private-in-public.rs:143:5
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function `aliases_priv::f3` is reachable at visibility `pub(crate)`
+   |
+note: but type `aliases_priv::Priv` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public.rs:116:5
    |
 LL |     struct Priv;
-   |     ----------- `aliases_params::Priv` declared as private
-...
-LL |     pub fn f2(arg: PrivAliasGeneric) {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private type
+   |     ^^^^^^^^^^^
 
-error[E0446]: private type `aliases_params::Priv` in public interface
+warning: type `aliases_params::Priv` is more private than the item `aliases_params::f2`
   --> $DIR/private-in-public.rs:145:5
    |
+LL |     pub fn f2(arg: PrivAliasGeneric) {}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function `aliases_params::f2` is reachable at visibility `pub(crate)`
+   |
+note: but type `aliases_params::Priv` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public.rs:141:5
+   |
 LL |     struct Priv;
-   |     ----------- `aliases_params::Priv` declared as private
-...
+   |     ^^^^^^^^^^^
+
+warning: type `aliases_params::Priv` is more private than the item `aliases_params::f3`
+  --> $DIR/private-in-public.rs:147:5
+   |
 LL |     pub fn f3(arg: Result<u8>) {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private type
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ function `aliases_params::f3` is reachable at visibility `pub(crate)`
+   |
+note: but type `aliases_params::Priv` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public.rs:141:5
+   |
+LL |     struct Priv;
+   |     ^^^^^^^^^^^
 
-error: aborting due to 32 previous errors
+warning: 31 warnings emitted
 
-Some errors have detailed explanations: E0445, E0446.
-For more information about an error, try `rustc --explain E0445`.
diff --git a/tests/ui/privacy/private-inferred-type-2.rs b/tests/ui/privacy/private-inferred-type-2.rs
index 15b263b3814..1c4c52bea28 100644
--- a/tests/ui/privacy/private-inferred-type-2.rs
+++ b/tests/ui/privacy/private-inferred-type-2.rs
@@ -1,4 +1,5 @@
 // aux-build:private-inferred-type.rs
+#![allow(private_interfaces)]
 
 extern crate private_inferred_type as ext;
 
diff --git a/tests/ui/privacy/private-inferred-type-2.stderr b/tests/ui/privacy/private-inferred-type-2.stderr
index 3a0fc03b4d5..8a905f5d88a 100644
--- a/tests/ui/privacy/private-inferred-type-2.stderr
+++ b/tests/ui/privacy/private-inferred-type-2.stderr
@@ -1,17 +1,17 @@
 error: type `Priv` is private
-  --> $DIR/private-inferred-type-2.rs:16:5
+  --> $DIR/private-inferred-type-2.rs:17:5
    |
 LL |     m::Pub::get_priv;
    |     ^^^^^^^^^^^^^^^^ private type
 
 error: type `Priv` is private
-  --> $DIR/private-inferred-type-2.rs:17:5
+  --> $DIR/private-inferred-type-2.rs:18:5
    |
 LL |     m::Pub::static_method;
    |     ^^^^^^^^^^^^^^^^^^^^^ private type
 
 error: type `ext::Priv` is private
-  --> $DIR/private-inferred-type-2.rs:18:5
+  --> $DIR/private-inferred-type-2.rs:19:5
    |
 LL |     ext::Pub::static_method;
    |     ^^^^^^^^^^^^^^^^^^^^^^^ private type
diff --git a/tests/ui/privacy/private-inferred-type.rs b/tests/ui/privacy/private-inferred-type.rs
index e8743dd968f..8c07226fe0e 100644
--- a/tests/ui/privacy/private-inferred-type.rs
+++ b/tests/ui/privacy/private-inferred-type.rs
@@ -1,5 +1,5 @@
 #![feature(decl_macro)]
-#![allow(private_in_public)]
+#![allow(private_interfaces)]
 
 mod m {
     fn priv_fn() {}
diff --git a/tests/ui/privacy/private-type-in-interface.rs b/tests/ui/privacy/private-type-in-interface.rs
index 7fbdbaf5f31..39e0bf23cac 100644
--- a/tests/ui/privacy/private-type-in-interface.rs
+++ b/tests/ui/privacy/private-type-in-interface.rs
@@ -1,6 +1,7 @@
 // aux-build:private-inferred-type.rs
 
 #![allow(warnings)]
+#![allow(private_interfaces)]
 
 extern crate private_inferred_type as ext;
 
diff --git a/tests/ui/privacy/private-type-in-interface.stderr b/tests/ui/privacy/private-type-in-interface.stderr
index 4e87caa3415..03225d84fdb 100644
--- a/tests/ui/privacy/private-type-in-interface.stderr
+++ b/tests/ui/privacy/private-type-in-interface.stderr
@@ -1,53 +1,53 @@
 error: type `Priv` is private
-  --> $DIR/private-type-in-interface.rs:15:9
+  --> $DIR/private-type-in-interface.rs:16:9
    |
 LL | fn f(_: m::Alias) {}
    |         ^^^^^^^^ private type
 
 error: type `Priv` is private
-  --> $DIR/private-type-in-interface.rs:15:6
+  --> $DIR/private-type-in-interface.rs:16:6
    |
 LL | fn f(_: m::Alias) {}
    |      ^ private type
 
 error: type `ext::Priv` is private
-  --> $DIR/private-type-in-interface.rs:17:13
+  --> $DIR/private-type-in-interface.rs:18:13
    |
 LL | fn f_ext(_: ext::Alias) {}
    |             ^^^^^^^^^^ private type
 
 error: type `ext::Priv` is private
-  --> $DIR/private-type-in-interface.rs:17:10
+  --> $DIR/private-type-in-interface.rs:18:10
    |
 LL | fn f_ext(_: ext::Alias) {}
    |          ^ private type
 
 error: type `Priv` is private
-  --> $DIR/private-type-in-interface.rs:21:6
+  --> $DIR/private-type-in-interface.rs:22:6
    |
 LL | impl m::Alias {}
    |      ^^^^^^^^ private type
 
 error: type `ext::Priv` is private
-  --> $DIR/private-type-in-interface.rs:22:14
+  --> $DIR/private-type-in-interface.rs:23:14
    |
 LL | impl Tr1 for ext::Alias {}
    |              ^^^^^^^^^^ private type
 
 error: type `Priv` is private
-  --> $DIR/private-type-in-interface.rs:23:10
+  --> $DIR/private-type-in-interface.rs:24:10
    |
 LL | type A = <m::Alias as m::Trait>::X;
    |          ^^^^^^^^^^^^^^^^^^^^^^^^^ private type
 
 error: type `Priv` is private
-  --> $DIR/private-type-in-interface.rs:27:11
+  --> $DIR/private-type-in-interface.rs:28:11
    |
 LL | fn g() -> impl Tr2<m::Alias> { 0 }
    |           ^^^^^^^^^^^^^^^^^^ private type
 
 error: type `ext::Priv` is private
-  --> $DIR/private-type-in-interface.rs:28:15
+  --> $DIR/private-type-in-interface.rs:29:15
    |
 LL | fn g_ext() -> impl Tr2<ext::Alias> { 0 }
    |               ^^^^^^^^^^^^^^^^^^^^ private type
diff --git a/tests/ui/privacy/restricted/private-in-public.rs b/tests/ui/privacy/restricted/private-in-public.rs
index 1e3dbdf73b9..80a7e6ad0a7 100644
--- a/tests/ui/privacy/restricted/private-in-public.rs
+++ b/tests/ui/privacy/restricted/private-in-public.rs
@@ -1,10 +1,11 @@
+// check-pass
 mod foo {
     struct Priv;
     mod bar {
         use foo::Priv;
         pub(super) fn f(_: Priv) {}
-        pub(crate) fn g(_: Priv) {} //~ ERROR E0446
-        pub(crate) fn h(_: Priv) {} //~ ERROR E0446
+        pub(crate) fn g(_: Priv) {}
+        pub(crate) fn h(_: Priv) {}
     }
 }
 
diff --git a/tests/ui/privacy/restricted/private-in-public.stderr b/tests/ui/privacy/restricted/private-in-public.stderr
deleted file mode 100644
index 65d996f0f07..00000000000
--- a/tests/ui/privacy/restricted/private-in-public.stderr
+++ /dev/null
@@ -1,21 +0,0 @@
-error[E0446]: private type `Priv` in public interface
-  --> $DIR/private-in-public.rs:6:9
-   |
-LL |     struct Priv;
-   |     ----------- `Priv` declared as private
-...
-LL |         pub(crate) fn g(_: Priv) {}
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private type
-
-error[E0446]: private type `Priv` in public interface
-  --> $DIR/private-in-public.rs:7:9
-   |
-LL |     struct Priv;
-   |     ----------- `Priv` declared as private
-...
-LL |         pub(crate) fn h(_: Priv) {}
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private type
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0446`.
diff --git a/tests/ui/privacy/unnameable_types.rs b/tests/ui/privacy/unnameable_types.rs
index 46e24915259..e35aaec5b3b 100644
--- a/tests/ui/privacy/unnameable_types.rs
+++ b/tests/ui/privacy/unnameable_types.rs
@@ -1,5 +1,4 @@
 #![feature(type_privacy_lints)]
-#![allow(private_in_public)]
 #![deny(unnameable_types)]
 
 mod m {
diff --git a/tests/ui/privacy/unnameable_types.stderr b/tests/ui/privacy/unnameable_types.stderr
index 90412752575..d68a11c9728 100644
--- a/tests/ui/privacy/unnameable_types.stderr
+++ b/tests/ui/privacy/unnameable_types.stderr
@@ -1,23 +1,23 @@
 error: struct `PubStruct` is reachable but cannot be named
-  --> $DIR/unnameable_types.rs:6:5
+  --> $DIR/unnameable_types.rs:5: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
+  --> $DIR/unnameable_types.rs:2:9
    |
 LL | #![deny(unnameable_types)]
    |         ^^^^^^^^^^^^^^^^
 
 error: enum `PubE` is reachable but cannot be named
-  --> $DIR/unnameable_types.rs:8:5
+  --> $DIR/unnameable_types.rs:7: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
+  --> $DIR/unnameable_types.rs:11:5
    |
 LL |     pub trait PubTr {
    |     ^^^^^^^^^^^^^^^ reachable at visibility `pub`, but can only be named at visibility `pub(crate)`
diff --git a/tests/ui/privacy/where-priv-type.rs b/tests/ui/privacy/where-priv-type.rs
index 2e0a6b3e72c..cd9cce7ec3e 100644
--- a/tests/ui/privacy/where-priv-type.rs
+++ b/tests/ui/privacy/where-priv-type.rs
@@ -3,14 +3,7 @@
 
 #![crate_type = "lib"]
 #![feature(generic_const_exprs)]
-#![feature(type_privacy_lints)]
 #![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 {}
@@ -23,42 +16,33 @@ impl PubTrWithAssocTy for PrivTy { type AssocTy = PrivTy; }
 
 
 pub struct S
-//~^ WARNING private type `PrivTy` in public interface
-//~| WARNING hard error
-//~| WARNING type `PrivTy` is more private than the item `S`
+//~^ WARNING type `PrivTy` is more private than the item `S`
 where
     PrivTy:
 {}
 
 
 pub enum E
-//~^ WARNING private type `PrivTy` in public interface
-//~| WARNING hard error
-//~| WARNING type `PrivTy` is more private than the item `E`
+//~^ WARNING type `PrivTy` is more private than the item `E`
 where
     PrivTy:
 {}
 
 
 pub fn f()
-//~^ WARNING private type `PrivTy` in public interface
-//~| WARNING hard error
-//~| WARNING type `PrivTy` is more private than the item `f`
+//~^ WARNING type `PrivTy` is more private than the item `f`
 where
     PrivTy:
 {}
 
 
 impl S
-//~^ ERROR private type `PrivTy` in public interface
-//~| WARNING type `PrivTy` is more private than the item `S`
+//~^ WARNING type `PrivTy` is more private than the item `S`
 where
     PrivTy:
 {
     pub fn f()
-    //~^ WARNING private type `PrivTy` in public interface
-    //~| WARNING hard error
-    //~| WARNING type `PrivTy` is more private than the item `S::f`
+    //~^ WARNING type `PrivTy` is more private than the item `S::f`
     where
         PrivTy:
     {}
@@ -90,7 +74,6 @@ where
 {
     type AssocTy = Const<{ my_const_fn(U) }>;
     //~^ ERROR private type
-    //~| WARNING type `fn(u8) -> u8 {my_const_fn}` is more private than the item `<Const<U> as Trait>::AssocTy`
     fn assoc_fn() -> Self::AssocTy {
         Const
     }
diff --git a/tests/ui/privacy/where-priv-type.stderr b/tests/ui/privacy/where-priv-type.stderr
index d6baf22b3fb..dcc249c6351 100644
--- a/tests/ui/privacy/where-priv-type.stderr
+++ b/tests/ui/privacy/where-priv-type.stderr
@@ -1,136 +1,72 @@
-warning: private type `PrivTy` in public interface (error E0446)
-  --> $DIR/where-priv-type.rs:25:1
-   |
-LL | pub struct S
-   | ^^^^^^^^^^^^
-   |
-   = 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>
-   = note: `#[warn(private_in_public)]` on by default
-
 warning: type `PrivTy` is more private than the item `S`
-  --> $DIR/where-priv-type.rs:25:1
+  --> $DIR/where-priv-type.rs:18:1
    |
 LL | pub struct S
    | ^^^^^^^^^^^^ struct `S` is reachable at visibility `pub`
    |
 note: but type `PrivTy` is only usable at visibility `pub(crate)`
-  --> $DIR/where-priv-type.rs:15:1
+  --> $DIR/where-priv-type.rs:8: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:34:1
-   |
-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>
+   = note: `#[warn(private_bounds)]` on by default
 
 warning: type `PrivTy` is more private than the item `E`
-  --> $DIR/where-priv-type.rs:34:1
+  --> $DIR/where-priv-type.rs:25:1
    |
 LL | pub enum E
    | ^^^^^^^^^^ enum `E` is reachable at visibility `pub`
    |
 note: but type `PrivTy` is only usable at visibility `pub(crate)`
-  --> $DIR/where-priv-type.rs:15:1
+  --> $DIR/where-priv-type.rs:8:1
    |
 LL | struct PrivTy;
    | ^^^^^^^^^^^^^
 
-warning: private type `PrivTy` in public interface (error E0446)
-  --> $DIR/where-priv-type.rs:43:1
-   |
-LL | / pub fn f()
-LL | |
-LL | |
-LL | |
-LL | | where
-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`
-  --> $DIR/where-priv-type.rs:43:1
+  --> $DIR/where-priv-type.rs:32:1
    |
 LL | / pub fn f()
 LL | |
-LL | |
-LL | |
 LL | | where
 LL | |     PrivTy:
    | |___________^ function `f` is reachable at visibility `pub`
    |
 note: but type `PrivTy` is only usable at visibility `pub(crate)`
-  --> $DIR/where-priv-type.rs:15:1
+  --> $DIR/where-priv-type.rs:8:1
    |
 LL | struct PrivTy;
    | ^^^^^^^^^^^^^
 
-error[E0446]: private type `PrivTy` in public interface
-  --> $DIR/where-priv-type.rs:52:1
-   |
-LL | struct PrivTy;
-   | ------------- `PrivTy` declared as private
-...
-LL | impl S
-   | ^^^^^^ can't leak private type
-
 warning: type `PrivTy` is more private than the item `S`
-  --> $DIR/where-priv-type.rs:52:1
+  --> $DIR/where-priv-type.rs:39:1
    |
 LL | impl S
    | ^^^^^^ implementation `S` is reachable at visibility `pub`
    |
 note: but type `PrivTy` is only usable at visibility `pub(crate)`
-  --> $DIR/where-priv-type.rs:15:1
+  --> $DIR/where-priv-type.rs:8:1
    |
 LL | struct PrivTy;
    | ^^^^^^^^^^^^^
 
-warning: private type `PrivTy` in public interface (error E0446)
-  --> $DIR/where-priv-type.rs:58:5
-   |
-LL | /     pub fn f()
-LL | |
-LL | |
-LL | |
-LL | |     where
-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`
-  --> $DIR/where-priv-type.rs:58:5
+  --> $DIR/where-priv-type.rs:44:5
    |
 LL | /     pub fn f()
 LL | |
-LL | |
-LL | |
 LL | |     where
 LL | |         PrivTy:
    | |_______________^ associated function `S::f` is reachable at visibility `pub`
    |
 note: but type `PrivTy` is only usable at visibility `pub(crate)`
-  --> $DIR/where-priv-type.rs:15:1
+  --> $DIR/where-priv-type.rs:8:1
    |
 LL | struct PrivTy;
    | ^^^^^^^^^^^^^
 
 error[E0446]: private type `fn(u8) -> u8 {my_const_fn}` in public interface
-  --> $DIR/where-priv-type.rs:91:5
+  --> $DIR/where-priv-type.rs:75:5
    |
 LL |     type AssocTy = Const<{ my_const_fn(U) }>;
    |     ^^^^^^^^^^^^ can't leak private type
@@ -138,23 +74,6 @@ 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
 
-warning: type `fn(u8) -> u8 {my_const_fn}` is more private than the item `<Const<U> as Trait>::AssocTy`
-  --> $DIR/where-priv-type.rs:91:5
-   |
-LL |     type AssocTy = Const<{ my_const_fn(U) }>;
-   |     ^^^^^^^^^^^^ associated type `<Const<U> as Trait>::AssocTy` is reachable at visibility `pub`
-   |
-note: but type `fn(u8) -> u8 {my_const_fn}` is only usable at visibility `pub(crate)`
-  --> $DIR/where-priv-type.rs:99: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
+error: aborting due to previous error; 5 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 c59fdb7c7a9..d5e797b52b3 100644
--- a/tests/ui/privacy/where-pub-type-impls-priv-trait.rs
+++ b/tests/ui/privacy/where-pub-type-impls-priv-trait.rs
@@ -1,14 +1,10 @@
+// check-pass
+
 // priv-in-pub lint tests where the private trait bounds a public type
 
 #![crate_type = "lib"]
 #![feature(generic_const_exprs)]
-#![feature(type_privacy_lints)]
 #![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 {}
@@ -22,38 +18,33 @@ impl PubTrWithAssocTy for PrivTy { type AssocTy = PrivTy; }
 
 
 pub struct S
-//~^ ERROR private trait `PrivTr` in public interface
-//~| WARNING trait `PrivTr` is more private than the item `S`
+//~^ WARNING trait `PrivTr` is more private than the item `S`
 where
     PubTy: PrivTr
 {}
 
 
 pub enum E
-//~^ ERROR private trait `PrivTr` in public interface
-//~| WARNING trait `PrivTr` is more private than the item `E`
+//~^ WARNING trait `PrivTr` is more private than the item `E`
 where
     PubTy: PrivTr
 {}
 
 
 pub fn f()
-//~^ ERROR private trait `PrivTr` in public interface
-//~| WARNING trait `PrivTr` is more private than the item `f`
+//~^ WARNING trait `PrivTr` is more private than the item `f`
 where
     PubTy: PrivTr
 {}
 
 
 impl S
-//~^ ERROR private trait `PrivTr` in public interface
-//~| WARNING trait `PrivTr` is more private than the item `S`
+//~^ WARNING trait `PrivTr` is more private than the item `S`
 where
     PubTy: PrivTr
 {
     pub fn f()
-    //~^ ERROR private trait `PrivTr` in public interface
-    //~| WARNING trait `PrivTr` is more private than the item `S::f`
+    //~^ WARNING trait `PrivTr` is more private than the item `S::f`
     where
         PubTy: 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 e2d7ce44692..c476874332c 100644
--- a/tests/ui/privacy/where-pub-type-impls-priv-trait.stderr
+++ b/tests/ui/privacy/where-pub-type-impls-priv-trait.stderr
@@ -1,129 +1,69 @@
-error[E0445]: private trait `PrivTr` in public interface
-  --> $DIR/where-pub-type-impls-priv-trait.rs:24:1
-   |
-LL | trait PrivTr {}
-   | ------------ `PrivTr` declared as private
-...
-LL | pub struct S
-   | ^^^^^^^^^^^^ can't leak private trait
-
 warning: trait `PrivTr` is more private than the item `S`
-  --> $DIR/where-pub-type-impls-priv-trait.rs:24:1
+  --> $DIR/where-pub-type-impls-priv-trait.rs:20:1
    |
 LL | pub struct S
    | ^^^^^^^^^^^^ struct `S` is reachable at visibility `pub`
    |
 note: but trait `PrivTr` is only usable at visibility `pub(crate)`
-  --> $DIR/where-pub-type-impls-priv-trait.rs:14:1
+  --> $DIR/where-pub-type-impls-priv-trait.rs:10: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:32:1
-   |
-LL | trait PrivTr {}
-   | ------------ `PrivTr` declared as private
-...
-LL | pub enum E
-   | ^^^^^^^^^^ can't leak private trait
+   = note: `#[warn(private_bounds)]` on by default
 
 warning: trait `PrivTr` is more private than the item `E`
-  --> $DIR/where-pub-type-impls-priv-trait.rs:32:1
+  --> $DIR/where-pub-type-impls-priv-trait.rs:27:1
    |
 LL | pub enum E
    | ^^^^^^^^^^ enum `E` is reachable at visibility `pub`
    |
 note: but trait `PrivTr` is only usable at visibility `pub(crate)`
-  --> $DIR/where-pub-type-impls-priv-trait.rs:14:1
+  --> $DIR/where-pub-type-impls-priv-trait.rs:10:1
    |
 LL | trait PrivTr {}
    | ^^^^^^^^^^^^
 
-error[E0445]: private trait `PrivTr` in public interface
-  --> $DIR/where-pub-type-impls-priv-trait.rs:40:1
-   |
-LL |   trait PrivTr {}
-   |   ------------ `PrivTr` declared as private
-...
-LL | / pub fn f()
-LL | |
-LL | |
-LL | | where
-LL | |     PubTy: PrivTr
-   | |_________________^ can't leak private trait
-
 warning: trait `PrivTr` is more private than the item `f`
-  --> $DIR/where-pub-type-impls-priv-trait.rs:40:1
+  --> $DIR/where-pub-type-impls-priv-trait.rs:34:1
    |
 LL | / pub fn f()
 LL | |
-LL | |
 LL | | where
 LL | |     PubTy: PrivTr
    | |_________________^ function `f` is reachable at visibility `pub`
    |
 note: but trait `PrivTr` is only usable at visibility `pub(crate)`
-  --> $DIR/where-pub-type-impls-priv-trait.rs:14:1
+  --> $DIR/where-pub-type-impls-priv-trait.rs:10:1
    |
 LL | trait PrivTr {}
    | ^^^^^^^^^^^^
 
-error[E0445]: private trait `PrivTr` in public interface
-  --> $DIR/where-pub-type-impls-priv-trait.rs:48:1
-   |
-LL | trait PrivTr {}
-   | ------------ `PrivTr` declared as private
-...
-LL | impl S
-   | ^^^^^^ can't leak private trait
-
 warning: trait `PrivTr` is more private than the item `S`
-  --> $DIR/where-pub-type-impls-priv-trait.rs:48:1
+  --> $DIR/where-pub-type-impls-priv-trait.rs:41:1
    |
 LL | impl S
    | ^^^^^^ implementation `S` is reachable at visibility `pub`
    |
 note: but trait `PrivTr` is only usable at visibility `pub(crate)`
-  --> $DIR/where-pub-type-impls-priv-trait.rs:14:1
+  --> $DIR/where-pub-type-impls-priv-trait.rs:10:1
    |
 LL | trait PrivTr {}
    | ^^^^^^^^^^^^
 
-error[E0445]: private trait `PrivTr` in public interface
-  --> $DIR/where-pub-type-impls-priv-trait.rs:54:5
-   |
-LL |   trait PrivTr {}
-   |   ------------ `PrivTr` declared as private
-...
-LL | /     pub fn f()
-LL | |
-LL | |
-LL | |     where
-LL | |         PubTy: PrivTr
-   | |_____________________^ can't leak private trait
-
 warning: trait `PrivTr` is more private than the item `S::f`
-  --> $DIR/where-pub-type-impls-priv-trait.rs:54:5
+  --> $DIR/where-pub-type-impls-priv-trait.rs:46:5
    |
 LL | /     pub fn f()
 LL | |
-LL | |
 LL | |     where
 LL | |         PubTy: PrivTr
    | |_____________________^ associated function `S::f` is reachable at visibility `pub`
    |
 note: but trait `PrivTr` is only usable at visibility `pub(crate)`
-  --> $DIR/where-pub-type-impls-priv-trait.rs:14:1
+  --> $DIR/where-pub-type-impls-priv-trait.rs:10:1
    |
 LL | trait PrivTr {}
    | ^^^^^^^^^^^^
 
-error: aborting due to 5 previous errors; 5 warnings emitted
+warning: 5 warnings emitted
 
-For more information about this error, try `rustc --explain E0445`.
diff --git a/tests/ui/proc-macro/allowed-signatures.rs b/tests/ui/proc-macro/allowed-signatures.rs
index 86850876112..ce327901b1a 100644
--- a/tests/ui/proc-macro/allowed-signatures.rs
+++ b/tests/ui/proc-macro/allowed-signatures.rs
@@ -3,7 +3,7 @@
 // no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
-#![allow(private_in_public)]
+#![allow(private_interfaces)]
 extern crate proc_macro;
 use proc_macro::TokenStream;
 
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 cdeea6224b2..7930964c83b 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,44 +1,24 @@
-#![feature(type_privacy_lints)]
-#![allow(non_camel_case_types)] // genus is always capitalized
-#![warn(private_interfaces)]
-//~^ NOTE the lint level is defined here
+// check-pass
 
-// 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.
+#![allow(non_camel_case_types)] // genus is always capitalized
 
 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,
 }
 
 pub type Helix_pomatia = Shell<Snail>;
-//~^ ERROR private type `Snail` in public interface
-//~| WARNING type `Snail` is more private than the item `Helix_pomatia`
-//~| NOTE can't leak private type
-//~| NOTE type alias `Helix_pomatia` is reachable at visibility `pub`
+//~^ WARNING type `Snail` is more private than the item `Helix_pomatia`
 pub type Dermochelys_coriacea = Shell<sea::Turtle>;
-//~^ ERROR crate-private type `Turtle` in public interface
-//~| WARNING type `Turtle` is more private than the item `Dermochelys_coriacea`
-//~| NOTE can't leak crate-private type
-//~| NOTE type alias `Dermochelys_coriacea` is reachable at visibility `pub`
+//~^ WARNING type `Turtle` is more private than the item `Dermochelys_coriacea`
 pub type Testudo_graeca = Shell<Tortoise>;
-//~^ ERROR private type `Tortoise` in public interface
-//~| WARNING type `Tortoise` is more private than the item `Testudo_graeca`
-//~| NOTE can't leak private type
-//~| NOTE type alias `Testudo_graeca` is reachable at visibility `pub`
+//~^ WARNING type `Tortoise` is more private than the item `Testudo_graeca`
 
 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 20e51e1901f..26dfa2e7d4f 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,71 +1,39 @@
-error[E0446]: private type `Snail` in public interface
-  --> $DIR/issue-33174-restricted-type-in-public-interface.rs:28:1
-   |
-LL | pub(crate) struct Snail;
-   | ----------------------- `Snail` declared as private
-...
-LL | pub type Helix_pomatia = Shell<Snail>;
-   | ^^^^^^^^^^^^^^^^^^^^^^ can't leak private type
-
 warning: type `Snail` is more private than the item `Helix_pomatia`
-  --> $DIR/issue-33174-restricted-type-in-public-interface.rs:28:1
+  --> $DIR/issue-33174-restricted-type-in-public-interface.rs:17:1
    |
 LL | pub type Helix_pomatia = Shell<Snail>;
    | ^^^^^^^^^^^^^^^^^^^^^^ type alias `Helix_pomatia` is reachable at visibility `pub`
    |
 note: but type `Snail` is only usable at visibility `pub(crate)`
-  --> $DIR/issue-33174-restricted-type-in-public-interface.rs:10:1
+  --> $DIR/issue-33174-restricted-type-in-public-interface.rs:5:1
    |
 LL | pub(crate) struct Snail;
    | ^^^^^^^^^^^^^^^^^^^^^^^
-note: the lint level is defined here
-  --> $DIR/issue-33174-restricted-type-in-public-interface.rs:3:9
-   |
-LL | #![warn(private_interfaces)]
-   |         ^^^^^^^^^^^^^^^^^^
-
-error[E0446]: crate-private type `Turtle` in public interface
-  --> $DIR/issue-33174-restricted-type-in-public-interface.rs:33:1
-   |
-LL |     pub(super) struct Turtle;
-   |     ------------------------ `Turtle` declared as crate-private
-...
-LL | pub type Dermochelys_coriacea = Shell<sea::Turtle>;
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't leak crate-private type
+   = note: `#[warn(private_interfaces)]` on by default
 
 warning: type `Turtle` is more private than the item `Dermochelys_coriacea`
-  --> $DIR/issue-33174-restricted-type-in-public-interface.rs:33:1
+  --> $DIR/issue-33174-restricted-type-in-public-interface.rs:19:1
    |
 LL | pub type Dermochelys_coriacea = Shell<sea::Turtle>;
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type alias `Dermochelys_coriacea` is reachable at visibility `pub`
    |
 note: but type `Turtle` is only usable at visibility `pub(crate)`
-  --> $DIR/issue-33174-restricted-type-in-public-interface.rs:15:5
+  --> $DIR/issue-33174-restricted-type-in-public-interface.rs:8:5
    |
 LL |     pub(super) struct Turtle;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0446]: private type `Tortoise` in public interface
-  --> $DIR/issue-33174-restricted-type-in-public-interface.rs:38:1
-   |
-LL | struct Tortoise;
-   | --------------- `Tortoise` declared as private
-...
-LL | pub type Testudo_graeca = Shell<Tortoise>;
-   | ^^^^^^^^^^^^^^^^^^^^^^^ can't leak private type
-
 warning: type `Tortoise` is more private than the item `Testudo_graeca`
-  --> $DIR/issue-33174-restricted-type-in-public-interface.rs:38:1
+  --> $DIR/issue-33174-restricted-type-in-public-interface.rs:21:1
    |
 LL | pub type Testudo_graeca = Shell<Tortoise>;
    | ^^^^^^^^^^^^^^^^^^^^^^^ type alias `Testudo_graeca` is reachable at visibility `pub`
    |
 note: but type `Tortoise` is only usable at visibility `pub(crate)`
-  --> $DIR/issue-33174-restricted-type-in-public-interface.rs:20:1
+  --> $DIR/issue-33174-restricted-type-in-public-interface.rs:11:1
    |
 LL | struct Tortoise;
    | ^^^^^^^^^^^^^^^
 
-error: aborting due to 3 previous errors; 3 warnings emitted
+warning: 3 warnings emitted
 
-For more information about this error, try `rustc --explain E0446`.
diff --git a/tests/ui/range/range-1.stderr b/tests/ui/range/range-1.stderr
index 277d9b2682d..ecfc56961ee 100644
--- a/tests/ui/range/range-1.stderr
+++ b/tests/ui/range/range-1.stderr
@@ -19,7 +19,7 @@ LL |     for i in false..true {}
              i64
              i128
              usize
-           and 5 others
+           and 6 others
    = note: required for `std::ops::Range<bool>` to implement `Iterator`
    = note: required for `std::ops::Range<bool>` to implement `IntoIterator`
 
diff --git a/tests/ui/regions/region-lifetime-bounds-on-fns-where-clause.stderr b/tests/ui/regions/region-lifetime-bounds-on-fns-where-clause.stderr
index f2328cf3b24..a9a92b7a695 100644
--- a/tests/ui/regions/region-lifetime-bounds-on-fns-where-clause.stderr
+++ b/tests/ui/regions/region-lifetime-bounds-on-fns-where-clause.stderr
@@ -8,7 +8,6 @@ LL |     let _: fn(&mut &isize, &mut &isize) = a;
    |
    = note: expected fn pointer `for<'a, 'b, 'c, 'd> fn(&'a mut &'b isize, &'c mut &'d isize)`
                  found fn item `for<'a, 'b> fn(&'a mut &isize, &'b mut &isize) {a::<'_, '_>}`
-   = note: when the arguments and return types match, functions can be coerced to function pointers
 
 error: aborting due to previous error
 
diff --git a/tests/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.stderr b/tests/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.stderr
index 9c5004981d5..e96559937d4 100644
--- a/tests/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.stderr
+++ b/tests/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.stderr
@@ -8,7 +8,6 @@ LL |     let _: fn(&mut &isize, &mut &isize, &mut &isize) = a;
    |
    = note: expected fn pointer `for<'a, 'b, 'c, 'd, 'e, 'f> fn(&'a mut &'b isize, &'c mut &'d isize, &'e mut &'f isize)`
                  found fn item `for<'a, 'b, 'c> fn(&'a mut &isize, &'b mut &isize, &'c mut &isize) {a::<'_, '_, '_>}`
-   = note: when the arguments and return types match, functions can be coerced to function pointers
 
 error: aborting due to previous error
 
diff --git a/tests/ui/regions/regions-fn-subtyping-return-static-fail.stderr b/tests/ui/regions/regions-fn-subtyping-return-static-fail.stderr
index 766a3d0337c..8d82ff958ff 100644
--- a/tests/ui/regions/regions-fn-subtyping-return-static-fail.stderr
+++ b/tests/ui/regions/regions-fn-subtyping-return-static-fail.stderr
@@ -8,7 +8,6 @@ LL |     want_G(baz);
    |
    = note: expected fn pointer `for<'cx> fn(&'cx S) -> &'static S`
                  found fn item `for<'a> fn(&'a S) -> &'a S {baz}`
-   = note: when the arguments and return types match, functions can be coerced to function pointers
 note: function defined here
   --> $DIR/regions-fn-subtyping-return-static-fail.rs:20:4
    |
diff --git a/tests/ui/regions/regions-lifetime-bounds-on-fns.stderr b/tests/ui/regions/regions-lifetime-bounds-on-fns.stderr
index 2fab2986567..53a5612d24f 100644
--- a/tests/ui/regions/regions-lifetime-bounds-on-fns.stderr
+++ b/tests/ui/regions/regions-lifetime-bounds-on-fns.stderr
@@ -8,7 +8,6 @@ LL |     let _: fn(&mut &isize, &mut &isize) = a;
    |
    = note: expected fn pointer `for<'a, 'b, 'c, 'd> fn(&'a mut &'b isize, &'c mut &'d isize)`
                  found fn item `for<'a, 'b> fn(&'a mut &isize, &'b mut &isize) {a::<'_, '_>}`
-   = note: when the arguments and return types match, functions can be coerced to function pointers
 
 error: aborting due to previous error
 
diff --git a/tests/ui/reify-intrinsic.stderr b/tests/ui/reify-intrinsic.stderr
index 9f9034a30c7..310b6c224e0 100644
--- a/tests/ui/reify-intrinsic.stderr
+++ b/tests/ui/reify-intrinsic.stderr
@@ -8,7 +8,6 @@ LL |     let _: unsafe extern "rust-intrinsic" fn(isize) -> usize = std::mem::tr
    |
    = note: expected fn pointer `unsafe extern "rust-intrinsic" fn(isize) -> usize`
                  found fn item `unsafe extern "rust-intrinsic" fn(_) -> _ {transmute::<_, _>}`
-   = note: when the arguments and return types match, functions can be coerced to function pointers
 
 error[E0606]: casting `unsafe extern "rust-intrinsic" fn(_) -> _ {transmute::<_, _>}` as `unsafe extern "rust-intrinsic" fn(isize) -> usize` is invalid
   --> $DIR/reify-intrinsic.rs:11:13
diff --git a/tests/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.mir.stderr b/tests/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.mir.stderr
index b0ac5dc44ad..e08ffe42d6a 100644
--- a/tests/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.mir.stderr
+++ b/tests/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.mir.stderr
@@ -13,7 +13,6 @@ LL |     let foo: fn() = foo;
                  found fn item `fn() {foo}`
    = note: fn items are distinct from fn pointers
    = note: functions with `#[target_feature]` can only be coerced to `unsafe` function pointers
-   = note: when the arguments and return types match, functions can be coerced to function pointers
 help: consider casting to a fn pointer
    |
 LL |     let foo: fn() = foo as fn();
diff --git a/tests/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.thir.stderr b/tests/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.thir.stderr
index b0ac5dc44ad..e08ffe42d6a 100644
--- a/tests/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.thir.stderr
+++ b/tests/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.thir.stderr
@@ -13,7 +13,6 @@ LL |     let foo: fn() = foo;
                  found fn item `fn() {foo}`
    = note: fn items are distinct from fn pointers
    = note: functions with `#[target_feature]` can only be coerced to `unsafe` function pointers
-   = note: when the arguments and return types match, functions can be coerced to function pointers
 help: consider casting to a fn pointer
    |
 LL |     let foo: fn() = foo as fn();
diff --git a/tests/ui/rfcs/rfc-2497-if-let-chains/chains-without-let.rs b/tests/ui/rfcs/rfc-2497-if-let-chains/chains-without-let.rs
index e0dded15217..2c0571a7bdd 100644
--- a/tests/ui/rfcs/rfc-2497-if-let-chains/chains-without-let.rs
+++ b/tests/ui/rfcs/rfc-2497-if-let-chains/chains-without-let.rs
@@ -1,19 +1,18 @@
+// check-pass
+
 fn and_chain() {
     let z;
     if true && { z = 3; true} && z == 3 {}
-    //~^ ERROR E0381
 }
 
 fn and_chain_2() {
     let z;
     true && { z = 3; true} && z == 3;
-    //~^ ERROR E0381
 }
 
 fn or_chain() {
     let z;
     if false || { z = 3; false} || z == 3 {}
-    //~^ ERROR E0381
 }
 
 fn main() {
diff --git a/tests/ui/rfcs/rfc-2497-if-let-chains/chains-without-let.stderr b/tests/ui/rfcs/rfc-2497-if-let-chains/chains-without-let.stderr
deleted file mode 100644
index 30d5a6779fc..00000000000
--- a/tests/ui/rfcs/rfc-2497-if-let-chains/chains-without-let.stderr
+++ /dev/null
@@ -1,33 +0,0 @@
-error[E0381]: used binding `z` is possibly-uninitialized
-  --> $DIR/chains-without-let.rs:3:34
-   |
-LL |     let z;
-   |         - binding declared here but left uninitialized
-LL |     if true && { z = 3; true} && z == 3 {}
-   |                  -----           ^ `z` used here but it is possibly-uninitialized
-   |                  |
-   |                  binding initialized here in some conditions
-
-error[E0381]: used binding `z` is possibly-uninitialized
-  --> $DIR/chains-without-let.rs:9:31
-   |
-LL |     let z;
-   |         - binding declared here but left uninitialized
-LL |     true && { z = 3; true} && z == 3;
-   |               -----           ^ `z` used here but it is possibly-uninitialized
-   |               |
-   |               binding initialized here in some conditions
-
-error[E0381]: used binding `z` is possibly-uninitialized
-  --> $DIR/chains-without-let.rs:15:36
-   |
-LL |     let z;
-   |         - binding declared here but left uninitialized
-LL |     if false || { z = 3; false} || z == 3 {}
-   |                   -----            ^ `z` used here but it is possibly-uninitialized
-   |                   |
-   |                   binding initialized here in some conditions
-
-error: aborting due to 3 previous errors
-
-For more information about this error, try `rustc --explain E0381`.
diff --git a/tests/ui/static/static-reference-to-fn-1.stderr b/tests/ui/static/static-reference-to-fn-1.stderr
index b68352b5183..86c4eaa7eb4 100644
--- a/tests/ui/static/static-reference-to-fn-1.stderr
+++ b/tests/ui/static/static-reference-to-fn-1.stderr
@@ -7,7 +7,6 @@ LL |         func: &foo,
    = note: expected reference `&fn() -> Option<isize>`
               found reference `&fn() -> Option<isize> {foo}`
    = note: fn items are distinct from fn pointers
-   = note: when the arguments and return types match, functions can be coerced to function pointers
 help: consider casting to a fn pointer
    |
 LL |         func: &(foo as fn() -> Option<isize>),
diff --git a/tests/ui/test-attrs/issue-36768.rs b/tests/ui/test-attrs/issue-36768.rs
index f671cbc8205..7531f3621f5 100644
--- a/tests/ui/test-attrs/issue-36768.rs
+++ b/tests/ui/test-attrs/issue-36768.rs
@@ -1,6 +1,6 @@
 // run-pass
 // compile-flags:--test
-#![deny(private_in_public)]
+#![deny(private_interfaces)]
 
 #[test] fn foo() {}
 mod foo {}
diff --git a/tests/ui/transmutability/visibility/assume/should_accept_if_dst_has_unreachable_field.rs b/tests/ui/transmutability/visibility/assume/should_accept_if_dst_has_unreachable_field.rs
index 546fcbaa3de..b6129163333 100644
--- a/tests/ui/transmutability/visibility/assume/should_accept_if_dst_has_unreachable_field.rs
+++ b/tests/ui/transmutability/visibility/assume/should_accept_if_dst_has_unreachable_field.rs
@@ -1,3 +1,5 @@
+// check-pass
+
 //! If visibility is assumed, a transmutation should be accepted even if the
 //! destination type contains an unreachable field (e.g., a public field with a
 //! private type). (This rule is distinct from type privacy, which still may
@@ -29,7 +31,7 @@ mod dst {
     #[repr(C)] pub(self) struct Zst; // <- unreachable type
 
     #[repr(C)] pub(in super) struct Dst {
-        pub(in super) field: Zst, //~ ERROR private type
+        pub(in super) field: Zst, //~ WARNING type `dst::Zst` is more private than the item `Dst::field`
     }
 }
 
diff --git a/tests/ui/transmutability/visibility/assume/should_accept_if_dst_has_unreachable_field.stderr b/tests/ui/transmutability/visibility/assume/should_accept_if_dst_has_unreachable_field.stderr
index be83b7ce33f..80099388d63 100644
--- a/tests/ui/transmutability/visibility/assume/should_accept_if_dst_has_unreachable_field.stderr
+++ b/tests/ui/transmutability/visibility/assume/should_accept_if_dst_has_unreachable_field.stderr
@@ -1,12 +1,15 @@
-error[E0446]: private type `dst::Zst` in public interface
-  --> $DIR/should_accept_if_dst_has_unreachable_field.rs:32:9
+warning: type `dst::Zst` is more private than the item `Dst::field`
+  --> $DIR/should_accept_if_dst_has_unreachable_field.rs:34:9
    |
-LL |     #[repr(C)] pub(self) struct Zst; // <- unreachable type
-   |                -------------------- `dst::Zst` declared as private
-...
 LL |         pub(in super) field: Zst,
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private type
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^ field `Dst::field` is reachable at visibility `pub(crate)`
+   |
+note: but type `dst::Zst` is only usable at visibility `pub(self)`
+  --> $DIR/should_accept_if_dst_has_unreachable_field.rs:31:16
+   |
+LL |     #[repr(C)] pub(self) struct Zst; // <- unreachable type
+   |                ^^^^^^^^^^^^^^^^^^^^
+   = note: `#[warn(private_interfaces)]` on by default
 
-error: aborting due to previous error
+warning: 1 warning emitted
 
-For more information about this error, try `rustc --explain E0446`.
diff --git a/tests/ui/transmutability/visibility/should_accept_if_src_has_unreachable_field.rs b/tests/ui/transmutability/visibility/should_accept_if_src_has_unreachable_field.rs
index 9c8345a8e91..e7742058c57 100644
--- a/tests/ui/transmutability/visibility/should_accept_if_src_has_unreachable_field.rs
+++ b/tests/ui/transmutability/visibility/should_accept_if_src_has_unreachable_field.rs
@@ -1,3 +1,5 @@
+// check-pass
+
 //! The presence of an unreachable field in the source type (e.g., a public
 //! field with a private type does not affect transmutability. (This rule is
 //! distinct from type privacy, which still may forbid naming such types.)
@@ -19,7 +21,7 @@ mod src {
     #[repr(C)] pub(self) struct Zst; // <- unreachable type
 
     #[repr(C)] pub(in super) struct Src {
-        pub(in super) field: Zst, //~ ERROR private type
+        pub(in super) field: Zst, //~ WARNING type `src::Zst` is more private than the item `Src::field`
     }
 }
 
diff --git a/tests/ui/transmutability/visibility/should_accept_if_src_has_unreachable_field.stderr b/tests/ui/transmutability/visibility/should_accept_if_src_has_unreachable_field.stderr
index 39b73302e36..55fb3392305 100644
--- a/tests/ui/transmutability/visibility/should_accept_if_src_has_unreachable_field.stderr
+++ b/tests/ui/transmutability/visibility/should_accept_if_src_has_unreachable_field.stderr
@@ -1,12 +1,15 @@
-error[E0446]: private type `src::Zst` in public interface
-  --> $DIR/should_accept_if_src_has_unreachable_field.rs:22:9
+warning: type `src::Zst` is more private than the item `Src::field`
+  --> $DIR/should_accept_if_src_has_unreachable_field.rs:24:9
    |
-LL |     #[repr(C)] pub(self) struct Zst; // <- unreachable type
-   |                -------------------- `src::Zst` declared as private
-...
 LL |         pub(in super) field: Zst,
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private type
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^ field `Src::field` is reachable at visibility `pub(crate)`
+   |
+note: but type `src::Zst` is only usable at visibility `pub(self)`
+  --> $DIR/should_accept_if_src_has_unreachable_field.rs:21:16
+   |
+LL |     #[repr(C)] pub(self) struct Zst; // <- unreachable type
+   |                ^^^^^^^^^^^^^^^^^^^^
+   = note: `#[warn(private_interfaces)]` on by default
 
-error: aborting due to previous error
+warning: 1 warning emitted
 
-For more information about this error, try `rustc --explain E0446`.
diff --git a/tests/ui/type-alias-impl-trait/privacy.rs b/tests/ui/type-alias-impl-trait/privacy.rs
index aa092f6f8ec..3efbfaf0916 100644
--- a/tests/ui/type-alias-impl-trait/privacy.rs
+++ b/tests/ui/type-alias-impl-trait/privacy.rs
@@ -1,8 +1,10 @@
+// check-pass
+
 #![feature(type_alias_impl_trait)]
 
 type Foo = (impl Sized, u8);
 pub fn foo() -> Foo {
-    //~^ ERROR private type alias `Foo` in public interface
+    //~^ WARNING type alias `Foo` is more private than the item `foo`
     (42, 42)
 }
 fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/privacy.stderr b/tests/ui/type-alias-impl-trait/privacy.stderr
index e8c6039cdc8..50870905c30 100644
--- a/tests/ui/type-alias-impl-trait/privacy.stderr
+++ b/tests/ui/type-alias-impl-trait/privacy.stderr
@@ -1,11 +1,15 @@
-error[E0446]: private type alias `Foo` in public interface
-  --> $DIR/privacy.rs:4:1
+warning: type alias `Foo` is more private than the item `foo`
+  --> $DIR/privacy.rs:6:1
    |
-LL | type Foo = (impl Sized, u8);
-   | -------- `Foo` declared as private
 LL | pub fn foo() -> Foo {
-   | ^^^^^^^^^^^^^^^^^^^ can't leak private type alias
+   | ^^^^^^^^^^^^^^^^^^^ function `foo` is reachable at visibility `pub`
+   |
+note: but type alias `Foo` is only usable at visibility `pub(crate)`
+  --> $DIR/privacy.rs:5:1
+   |
+LL | type Foo = (impl Sized, u8);
+   | ^^^^^^^^
+   = note: `#[warn(private_interfaces)]` on by default
 
-error: aborting due to previous error
+warning: 1 warning emitted
 
-For more information about this error, try `rustc --explain E0446`.
diff --git a/tests/ui/unsafe/initializing-ranged-via-ctor.rs b/tests/ui/unsafe/initializing-ranged-via-ctor.rs
new file mode 100644
index 00000000000..ca44fa7e4e7
--- /dev/null
+++ b/tests/ui/unsafe/initializing-ranged-via-ctor.rs
@@ -0,0 +1,11 @@
+#![feature(rustc_attrs)]
+#![allow(internal_features)]
+
+#[derive(Debug)]
+#[rustc_layout_scalar_valid_range_start(2)]
+struct NonZeroAndOneU8(u8);
+
+fn main() {
+    println!("{:?}", Some(1).map(NonZeroAndOneU8).unwrap());
+    //~^ ERROR found `unsafe fn(u8) -> NonZeroAndOneU8 {NonZeroAndOneU8}`
+}
diff --git a/tests/ui/unsafe/initializing-ranged-via-ctor.stderr b/tests/ui/unsafe/initializing-ranged-via-ctor.stderr
new file mode 100644
index 00000000000..d34554c6641
--- /dev/null
+++ b/tests/ui/unsafe/initializing-ranged-via-ctor.stderr
@@ -0,0 +1,16 @@
+error[E0277]: expected a `FnOnce<({integer},)>` closure, found `unsafe fn(u8) -> NonZeroAndOneU8 {NonZeroAndOneU8}`
+  --> $DIR/initializing-ranged-via-ctor.rs:9:34
+   |
+LL |     println!("{:?}", Some(1).map(NonZeroAndOneU8).unwrap());
+   |                              --- ^^^^^^^^^^^^^^^ call the function in a closure: `|| unsafe { /* code */ }`
+   |                              |
+   |                              required by a bound introduced by this call
+   |
+   = help: the trait `FnOnce<({integer},)>` is not implemented for fn item `unsafe fn(u8) -> NonZeroAndOneU8 {NonZeroAndOneU8}`
+   = note: unsafe function cannot be called generically without an unsafe block
+note: required by a bound in `Option::<T>::map`
+  --> $SRC_DIR/core/src/option.rs:LL:COL
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/unsafe/ranged-ctor-as-fn-ptr.rs b/tests/ui/unsafe/ranged-ctor-as-fn-ptr.rs
new file mode 100644
index 00000000000..a91e579510d
--- /dev/null
+++ b/tests/ui/unsafe/ranged-ctor-as-fn-ptr.rs
@@ -0,0 +1,10 @@
+#![feature(rustc_attrs)]
+
+#[derive(Debug)]
+#[rustc_layout_scalar_valid_range_start(2)]
+struct NonZeroAndOneU8(u8);
+
+fn main() {
+    let x: fn(u8) -> NonZeroAndOneU8 = NonZeroAndOneU8;
+    //~^ ERROR mismatched types
+}
diff --git a/tests/ui/unsafe/ranged-ctor-as-fn-ptr.stderr b/tests/ui/unsafe/ranged-ctor-as-fn-ptr.stderr
new file mode 100644
index 00000000000..660c4070451
--- /dev/null
+++ b/tests/ui/unsafe/ranged-ctor-as-fn-ptr.stderr
@@ -0,0 +1,15 @@
+error[E0308]: mismatched types
+  --> $DIR/ranged-ctor-as-fn-ptr.rs:8:40
+   |
+LL |     let x: fn(u8) -> NonZeroAndOneU8 = NonZeroAndOneU8;
+   |            -------------------------   ^^^^^^^^^^^^^^^ expected normal fn, found unsafe fn
+   |            |
+   |            expected due to this
+   |
+   = note:      expected fn pointer `fn(_) -> NonZeroAndOneU8`
+           found struct constructor `unsafe fn(_) -> NonZeroAndOneU8 {NonZeroAndOneU8}`
+   = note: unsafe functions cannot be coerced into safe function pointers
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/triagebot.toml b/triagebot.toml
index 6f7efd4c3db..6847e8a00be 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -585,7 +585,7 @@ cc = ["@nnethercote"]
 [assign]
 warn_non_default_branch = true
 contributing_url = "https://rustc-dev-guide.rust-lang.org/getting-started.html"
-users_on_vacation = ["jyn514", "clubby789"]
+users_on_vacation = ["jyn514", "clubby789", "spastorino"]
 
 [assign.adhoc_groups]
 compiler-team = [