about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_borrowck/src/renumber.rs1
-rw-r--r--compiler/rustc_borrowck/src/type_check/free_region_relations.rs67
-rw-r--r--compiler/rustc_borrowck/src/universal_regions.rs65
-rw-r--r--compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch4
-rw-r--r--compiler/rustc_hir_analysis/messages.ftl2
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/builtin.rs42
-rw-r--r--compiler/rustc_monomorphize/src/collector.rs7
-rw-r--r--compiler/rustc_symbol_mangling/src/legacy.rs8
-rw-r--r--compiler/rustc_trait_selection/src/solve/fulfill.rs5
-rw-r--r--compiler/rustc_trait_selection/src/traits/mod.rs15
-rw-r--r--compiler/rustc_ty_utils/src/layout.rs32
-rw-r--r--library/Cargo.lock4
-rw-r--r--library/alloc/Cargo.toml2
-rw-r--r--library/std/Cargo.toml2
-rw-r--r--src/bootstrap/src/core/build_steps/format.rs2
-rw-r--r--src/bootstrap/src/core/build_steps/test.rs14
-rw-r--r--src/bootstrap/src/core/builder/cargo.rs12
-rw-r--r--src/bootstrap/src/utils/helpers.rs25
-rw-r--r--src/ci/docker/scripts/emscripten.sh24
-rw-r--r--src/librustdoc/config.rs6
-rw-r--r--src/librustdoc/html/highlight.rs15
-rw-r--r--src/librustdoc/html/render/span_map.rs33
-rw-r--r--src/librustdoc/html/render/write_shared.rs10
-rw-r--r--src/librustdoc/html/static/js/search.js46
-rw-r--r--src/librustdoc/json/conversions.rs2
-rw-r--r--src/librustdoc/lib.rs9
-rw-r--r--src/rustdoc-json-types/lib.rs2
-rw-r--r--tests/codegen-units/item-collection/closures.rs6
-rw-r--r--tests/codegen-units/item-collection/drop-glue-eager.rs43
-rw-r--r--tests/run-make/rustdoc-default-output/output-default.stdout3
-rw-r--r--tests/rustdoc-js-std/return-based-sort.js30
-rw-r--r--tests/rustdoc-json/return_private.rs2
-rw-r--r--tests/rustdoc/jump-to-def-pats.rs52
-rw-r--r--tests/ui/closures/binder/nested-closures-regions.stderr4
-rw-r--r--tests/ui/const-generics/type-mismatch-in-nested-goal.current.stderr45
-rw-r--r--tests/ui/const-generics/type-mismatch-in-nested-goal.next.stderr45
-rw-r--r--tests/ui/const-generics/type-mismatch-in-nested-goal.rs17
-rw-r--r--tests/ui/enum-discriminant/eval-error.rs37
-rw-r--r--tests/ui/enum-discriminant/eval-error.stderr51
-rw-r--r--tests/ui/invalid_dispatch_from_dyn_impls.stderr4
-rw-r--r--tests/ui/layout/base-layout-is-sized-ice-123078.rs1
-rw-r--r--tests/ui/layout/base-layout-is-sized-ice-123078.stderr14
-rw-r--r--tests/ui/layout/debug.stderr2
-rw-r--r--tests/ui/nll/closure-requirements/escape-argument-callee.stderr2
-rw-r--r--tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr2
-rw-r--r--tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr4
-rw-r--r--tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr4
-rw-r--r--tests/ui/self/dispatch-from-dyn-zst-transmute-zst-nonzst.rs25
-rw-r--r--tests/ui/self/dispatch-from-dyn-zst-transmute-zst-nonzst.stderr16
-rw-r--r--tests/ui/self/dispatch-from-dyn-zst-transmute.rs34
-rw-r--r--tests/ui/self/dispatch-from-dyn-zst-transmute.stderr16
-rw-r--r--tests/ui/self/phantomdata-in-coerce-and-dispatch-impls.rs25
-rw-r--r--tests/ui/traits/next-solver/known-type-outlives-has-constraints.rs13
-rw-r--r--tests/ui/traits/trait-upcasting/impossible-method-modulo-binders-2.rs39
-rw-r--r--tests/ui/traits/trait-upcasting/impossible-method-modulo-binders.rs40
55 files changed, 837 insertions, 195 deletions
diff --git a/compiler/rustc_borrowck/src/renumber.rs b/compiler/rustc_borrowck/src/renumber.rs
index d83d6ade203..e355d2b415b 100644
--- a/compiler/rustc_borrowck/src/renumber.rs
+++ b/compiler/rustc_borrowck/src/renumber.rs
@@ -34,7 +34,6 @@ pub(crate) enum RegionCtxt {
     Location(Location),
     TyContext(TyContext),
     Free(Symbol),
-    Bound(Symbol),
     LateBound(Symbol),
     Existential(Option<Symbol>),
     Placeholder(Symbol),
diff --git a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs
index ea965eb6545..edf612f4e97 100644
--- a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs
+++ b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs
@@ -5,13 +5,14 @@ use rustc_infer::infer::canonical::QueryRegionConstraints;
 use rustc_infer::infer::outlives::env::RegionBoundPairs;
 use rustc_infer::infer::region_constraints::GenericKind;
 use rustc_infer::infer::{InferCtxt, outlives};
+use rustc_infer::traits::ScrubbedTraitError;
 use rustc_middle::mir::ConstraintCategory;
 use rustc_middle::traits::ObligationCause;
 use rustc_middle::traits::query::OutlivesBound;
 use rustc_middle::ty::{self, RegionVid, Ty, TypeVisitableExt};
 use rustc_span::{ErrorGuaranteed, Span};
-use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
-use rustc_trait_selection::solve::deeply_normalize;
+use rustc_trait_selection::solve::NoSolution;
+use rustc_trait_selection::traits::query::type_op::custom::CustomTypeOp;
 use rustc_trait_selection::traits::query::type_op::{self, TypeOp};
 use tracing::{debug, instrument};
 use type_op::TypeOpOutput;
@@ -229,24 +230,14 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
         let mut constraints = vec![];
         let mut known_type_outlives_obligations = vec![];
         for bound in param_env.caller_bounds() {
-            let Some(mut outlives) = bound.as_type_outlives_clause() else { continue };
-
-            // In the new solver, normalize the type-outlives obligation assumptions.
-            if self.infcx.next_trait_solver() {
-                match deeply_normalize(
-                    self.infcx.at(&ObligationCause::misc(span, defining_ty_def_id), param_env),
+            if let Some(outlives) = bound.as_type_outlives_clause() {
+                self.normalize_and_push_type_outlives_obligation(
                     outlives,
-                ) {
-                    Ok(normalized_outlives) => {
-                        outlives = normalized_outlives;
-                    }
-                    Err(e) => {
-                        self.infcx.err_ctxt().report_fulfillment_errors(e);
-                    }
-                }
-            }
-
-            known_type_outlives_obligations.push(outlives);
+                    span,
+                    &mut known_type_outlives_obligations,
+                    &mut constraints,
+                );
+            };
         }
 
         let unnormalized_input_output_tys = self
@@ -356,6 +347,44 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
         }
     }
 
+    fn normalize_and_push_type_outlives_obligation(
+        &self,
+        mut outlives: ty::PolyTypeOutlivesPredicate<'tcx>,
+        span: Span,
+        known_type_outlives_obligations: &mut Vec<ty::PolyTypeOutlivesPredicate<'tcx>>,
+        constraints: &mut Vec<&QueryRegionConstraints<'tcx>>,
+    ) {
+        // In the new solver, normalize the type-outlives obligation assumptions.
+        if self.infcx.next_trait_solver() {
+            let Ok(TypeOpOutput {
+                output: normalized_outlives,
+                constraints: constraints_normalize,
+                error_info: _,
+            }) = CustomTypeOp::new(
+                |ocx| {
+                    ocx.deeply_normalize(
+                        &ObligationCause::dummy_with_span(span),
+                        self.param_env,
+                        outlives,
+                    )
+                    .map_err(|_: Vec<ScrubbedTraitError<'tcx>>| NoSolution)
+                },
+                "normalize type outlives obligation",
+            )
+            .fully_perform(self.infcx, span)
+            else {
+                self.infcx.dcx().delayed_bug(format!("could not normalize {outlives:?}"));
+                return;
+            };
+            outlives = normalized_outlives;
+            if let Some(c) = constraints_normalize {
+                constraints.push(c);
+            }
+        }
+
+        known_type_outlives_obligations.push(outlives);
+    }
+
     /// Update the type of a single local, which should represent
     /// either the return type of the MIR or one of its arguments. At
     /// the same time, compute and add any implied bounds that come
diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs
index 3dc4569c57b..26af86c0cdd 100644
--- a/compiler/rustc_borrowck/src/universal_regions.rs
+++ b/compiler/rustc_borrowck/src/universal_regions.rs
@@ -467,15 +467,13 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
                 self.infcx.tcx.local_parent(self.mir_def),
                 |r| {
                     debug!(?r);
-                    if !indices.indices.contains_key(&r) {
-                        let region_vid = {
-                            let name = r.get_name_or_anon();
-                            self.infcx.next_nll_region_var(FR, || RegionCtxt::LateBound(name))
-                        };
-
-                        debug!(?region_vid);
-                        indices.insert_late_bound_region(r, region_vid.as_var());
-                    }
+                    let region_vid = {
+                        let name = r.get_name_or_anon();
+                        self.infcx.next_nll_region_var(FR, || RegionCtxt::LateBound(name))
+                    };
+
+                    debug!(?region_vid);
+                    indices.insert_late_bound_region(r, region_vid.as_var());
                 },
             );
 
@@ -484,21 +482,17 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
             self.infcx.num_region_vars()
         };
 
-        // "Liberate" the late-bound regions. These correspond to
-        // "local" free regions.
+        // Converse of above, if this is a function/closure then the late-bound regions declared
+        // on its signature are local.
+        //
+        // We manually loop over `bound_inputs_and_output` instead of using
+        // `for_each_late_bound_region_in_item` as we may need to add the otherwise
+        // implicit `ClosureEnv` region.
         let bound_inputs_and_output = self.compute_inputs_and_output(&indices, defining_ty);
-
-        let inputs_and_output = self.infcx.replace_bound_regions_with_nll_infer_vars(
-            FR,
-            self.mir_def,
-            bound_inputs_and_output,
-            &mut indices,
-        );
-        // Converse of above, if this is a function/closure then the late-bound regions declared on its
-        // signature are local.
-        for_each_late_bound_region_in_item(self.infcx.tcx, self.mir_def, |r| {
-            debug!(?r);
-            if !indices.indices.contains_key(&r) {
+        for (idx, bound_var) in bound_inputs_and_output.bound_vars().iter().enumerate() {
+            if let ty::BoundVariableKind::Region(kind) = bound_var {
+                let kind = ty::LateParamRegionKind::from_bound(ty::BoundVar::from_usize(idx), kind);
+                let r = ty::Region::new_late_param(self.infcx.tcx, self.mir_def.to_def_id(), kind);
                 let region_vid = {
                     let name = r.get_name_or_anon();
                     self.infcx.next_nll_region_var(FR, || RegionCtxt::LateBound(name))
@@ -507,7 +501,12 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
                 debug!(?region_vid);
                 indices.insert_late_bound_region(r, region_vid.as_var());
             }
-        });
+        }
+        let inputs_and_output = self.infcx.replace_bound_regions_with_nll_infer_vars(
+            self.mir_def,
+            bound_inputs_and_output,
+            &indices,
+        );
 
         let (unnormalized_output_ty, mut unnormalized_input_tys) =
             inputs_and_output.split_last().unwrap();
@@ -832,10 +831,9 @@ impl<'tcx> BorrowckInferCtxt<'tcx> {
     #[instrument(level = "debug", skip(self, indices))]
     fn replace_bound_regions_with_nll_infer_vars<T>(
         &self,
-        origin: NllRegionVariableOrigin,
         all_outlive_scope: LocalDefId,
         value: ty::Binder<'tcx, T>,
-        indices: &mut UniversalRegionIndices<'tcx>,
+        indices: &UniversalRegionIndices<'tcx>,
     ) -> T
     where
         T: TypeFoldable<TyCtxt<'tcx>>,
@@ -845,18 +843,7 @@ impl<'tcx> BorrowckInferCtxt<'tcx> {
             let kind = ty::LateParamRegionKind::from_bound(br.var, br.kind);
             let liberated_region =
                 ty::Region::new_late_param(self.tcx, all_outlive_scope.to_def_id(), kind);
-            let region_vid = {
-                let name = match br.kind.get_name() {
-                    Some(name) => name,
-                    _ => sym::anon,
-                };
-
-                self.next_nll_region_var(origin, || RegionCtxt::Bound(name))
-            };
-
-            indices.insert_late_bound_region(liberated_region, region_vid.as_var());
-            debug!(?liberated_region, ?region_vid);
-            region_vid
+            ty::Region::new_var(self.tcx, indices.to_region_vid(liberated_region))
         });
         value
     }
@@ -870,7 +857,7 @@ impl<'tcx> UniversalRegionIndices<'tcx> {
     /// well. These are used for error reporting.
     fn insert_late_bound_region(&mut self, r: ty::Region<'tcx>, vid: ty::RegionVid) {
         debug!("insert_late_bound_region({:?}, {:?})", r, vid);
-        self.indices.insert(r, vid);
+        assert_eq!(self.indices.insert(r, vid), None);
     }
 
     /// Converts `r` into a local inference variable: `r` can either
diff --git a/compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch b/compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch
index bf07e455a75..b2eeb526336 100644
--- a/compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch
+++ b/compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch
@@ -16,8 +16,8 @@ index 7165c3e48af..968552ad435 100644
  
  [dependencies]
  core = { path = "../core" }
--compiler_builtins = { version = "=0.1.140", features = ['rustc-dep-of-std'] }
-+compiler_builtins = { version = "=0.1.140", features = ['rustc-dep-of-std', 'no-f16-f128'] }
+-compiler_builtins = { version = "=0.1.141", features = ['rustc-dep-of-std'] }
++compiler_builtins = { version = "=0.1.141", features = ['rustc-dep-of-std', 'no-f16-f128'] }
  
  [dev-dependencies]
  rand = { version = "0.8.5", default-features = false, features = ["alloc"] }
diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl
index 0c3ed9b5c60..d7ab6eca84b 100644
--- a/compiler/rustc_hir_analysis/messages.ftl
+++ b/compiler/rustc_hir_analysis/messages.ftl
@@ -135,7 +135,7 @@ hir_analysis_dispatch_from_dyn_multi = implementing the `DispatchFromDyn` trait
 
 hir_analysis_dispatch_from_dyn_repr = structs implementing `DispatchFromDyn` may not have `#[repr(packed)]` or `#[repr(C)]`
 
-hir_analysis_dispatch_from_dyn_zst = the trait `DispatchFromDyn` may only be implemented for structs containing the field being coerced, ZST fields with 1 byte alignment, and nothing else
+hir_analysis_dispatch_from_dyn_zst = the trait `DispatchFromDyn` may only be implemented for structs containing the field being coerced, ZST fields with 1 byte alignment that don't mention type/const generics, and nothing else
     .note = extra field `{$name}` of type `{$ty}` is not allowed
 
 hir_analysis_drop_impl_negative = negative `Drop` impls are not supported
diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs
index 3b98f358b1e..b43a808ccdc 100644
--- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs
@@ -259,19 +259,37 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<()
             let coerced_fields = fields
                 .iter()
                 .filter(|field| {
+                    // Ignore PhantomData fields
+                    let unnormalized_ty = tcx.type_of(field.did).instantiate_identity();
+                    if tcx
+                        .try_normalize_erasing_regions(
+                            ty::TypingEnv::non_body_analysis(tcx, def_a.did()),
+                            unnormalized_ty,
+                        )
+                        .unwrap_or(unnormalized_ty)
+                        .is_phantom_data()
+                    {
+                        return false;
+                    }
+
                     let ty_a = field.ty(tcx, args_a);
                     let ty_b = field.ty(tcx, args_b);
 
-                    if let Ok(layout) =
-                        tcx.layout_of(infcx.typing_env(param_env).as_query_input(ty_a))
-                    {
-                        if layout.is_1zst() {
+                    // FIXME: We could do normalization here, but is it really worth it?
+                    if ty_a == ty_b {
+                        // Allow 1-ZSTs that don't mention type params.
+                        //
+                        // Allowing type params here would allow us to possibly transmute
+                        // between ZSTs, which may be used to create library unsoundness.
+                        if let Ok(layout) =
+                            tcx.layout_of(infcx.typing_env(param_env).as_query_input(ty_a))
+                            && layout.is_1zst()
+                            && !ty_a.has_non_region_param()
+                        {
                             // ignore 1-ZST fields
                             return false;
                         }
-                    }
 
-                    if ty_a == ty_b {
                         res = Err(tcx.dcx().emit_err(errors::DispatchFromDynZST {
                             span,
                             name: field.name,
@@ -460,8 +478,16 @@ pub(crate) fn coerce_unsized_info<'tcx>(
                 .filter_map(|(i, f)| {
                     let (a, b) = (f.ty(tcx, args_a), f.ty(tcx, args_b));
 
-                    if tcx.type_of(f.did).instantiate_identity().is_phantom_data() {
-                        // Ignore PhantomData fields
+                    // Ignore PhantomData fields
+                    let unnormalized_ty = tcx.type_of(f.did).instantiate_identity();
+                    if tcx
+                        .try_normalize_erasing_regions(
+                            ty::TypingEnv::non_body_analysis(tcx, def_a.did()),
+                            unnormalized_ty,
+                        )
+                        .unwrap_or(unnormalized_ty)
+                        .is_phantom_data()
+                    {
                         return None;
                     }
 
diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs
index c2e9498908c..0f3943cfe6a 100644
--- a/compiler/rustc_monomorphize/src/collector.rs
+++ b/compiler/rustc_monomorphize/src/collector.rs
@@ -1407,7 +1407,7 @@ impl<'v> RootCollector<'_, 'v> {
         match self.tcx.def_kind(id.owner_id) {
             DefKind::Enum | DefKind::Struct | DefKind::Union => {
                 if self.strategy == MonoItemCollectionStrategy::Eager
-                    && self.tcx.generics_of(id.owner_id).is_empty()
+                    && !self.tcx.generics_of(id.owner_id).requires_monomorphization(self.tcx)
                 {
                     debug!("RootCollector: ADT drop-glue for `{id:?}`",);
 
@@ -1420,7 +1420,10 @@ impl<'v> RootCollector<'_, 'v> {
                         return;
                     }
 
-                    let ty = self.tcx.type_of(id.owner_id.to_def_id()).no_bound_vars().unwrap();
+                    let ty = self.tcx.erase_regions(
+                        self.tcx.type_of(id.owner_id.to_def_id()).instantiate_identity(),
+                    );
+                    assert!(!ty.has_non_region_param());
                     visit_drop_use(self.tcx, ty, true, DUMMY_SP, self.output);
                 }
             }
diff --git a/compiler/rustc_symbol_mangling/src/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs
index 58c0a05df1f..879f3fac21f 100644
--- a/compiler/rustc_symbol_mangling/src/legacy.rs
+++ b/compiler/rustc_symbol_mangling/src/legacy.rs
@@ -19,15 +19,15 @@ pub(super) fn mangle<'tcx>(
     let def_id = instance.def_id();
 
     // We want to compute the "type" of this item. Unfortunately, some
-    // kinds of items (e.g., closures) don't have an entry in the
-    // item-type array. So walk back up the find the closest parent
-    // that DOES have an entry.
+    // kinds of items (e.g., synthetic static allocations from const eval)
+    // don't have a proper implementation for the `type_of` query. So walk
+    // back up the find the closest parent that DOES have a type.
     let mut ty_def_id = def_id;
     let instance_ty;
     loop {
         let key = tcx.def_key(ty_def_id);
         match key.disambiguated_data.data {
-            DefPathData::TypeNs(_) | DefPathData::ValueNs(_) => {
+            DefPathData::TypeNs(_) | DefPathData::ValueNs(_) | DefPathData::Closure => {
                 instance_ty = tcx.type_of(ty_def_id).instantiate_identity();
                 debug!(?instance_ty);
                 break;
diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs
index 7db0f2bb5a7..4498beff4ea 100644
--- a/compiler/rustc_trait_selection/src/solve/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs
@@ -264,9 +264,10 @@ fn fulfillment_error_for_no_solution<'tcx>(
                     infcx.tcx.type_of(uv.def).instantiate(infcx.tcx, uv.args)
                 }
                 ty::ConstKind::Param(param_ct) => param_ct.find_ty_from_env(obligation.param_env),
-                _ => span_bug!(
+                ty::ConstKind::Value(ty, _) => ty,
+                kind => span_bug!(
                     obligation.cause.span,
-                    "ConstArgHasWrongType failed but we don't know how to compute type"
+                    "ConstArgHasWrongType failed but we don't know how to compute type for {kind:?}"
                 ),
             };
             FulfillmentErrorCode::Select(SelectionError::ConstArgHasWrongType {
diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs
index 1dcd0d0dfb8..da16a742099 100644
--- a/compiler/rustc_trait_selection/src/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/mod.rs
@@ -714,9 +714,18 @@ pub fn impossible_predicates<'tcx>(tcx: TyCtxt<'tcx>, predicates: Vec<ty::Clause
     }
     let errors = ocx.select_all_or_error();
 
-    let result = !errors.is_empty();
-    debug!("impossible_predicates = {:?}", result);
-    result
+    if !errors.is_empty() {
+        return true;
+    }
+
+    // Leak check for any higher-ranked trait mismatches.
+    // We only need to do this in the old solver, since the new solver already
+    // leak-checks.
+    if !infcx.next_trait_solver() && infcx.leak_check(ty::UniverseIndex::ROOT, None).is_err() {
+        return true;
+    }
+
+    false
 }
 
 fn instantiate_and_check_impossible_predicates<'tcx>(
diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs
index ab606478c51..17be0bd0ab9 100644
--- a/compiler/rustc_ty_utils/src/layout.rs
+++ b/compiler/rustc_ty_utils/src/layout.rs
@@ -105,21 +105,27 @@ fn map_error<'tcx>(
             // See `tests/ui/layout/trivial-bounds-sized.rs` for an example.
             assert!(field.layout.is_unsized(), "invalid layout error {err:#?}");
             if !field.ty.is_sized(cx.tcx(), cx.typing_env) {
-                cx.tcx().dcx().delayed_bug(format!(
+                let guar = cx.tcx().dcx().delayed_bug(format!(
                     "encountered unexpected unsized field in layout of {ty:?}: {field:#?}"
                 ));
+                LayoutError::ReferencesError(guar)
+            } else {
+                LayoutError::Unknown(ty)
             }
-            LayoutError::Unknown(ty)
         }
         LayoutCalculatorError::EmptyUnion => {
             // This is always a compile error.
-            cx.tcx().dcx().delayed_bug(format!("computed layout of empty union: {ty:?}"));
-            LayoutError::Unknown(ty)
+            let guar =
+                cx.tcx().dcx().delayed_bug(format!("computed layout of empty union: {ty:?}"));
+            LayoutError::ReferencesError(guar)
         }
         LayoutCalculatorError::ReprConflict => {
             // packed enums are the only known trigger of this, but others might arise
-            cx.tcx().dcx().delayed_bug(format!("computed impossible repr (packed enum?): {ty:?}"));
-            LayoutError::Unknown(ty)
+            let guar = cx
+                .tcx()
+                .dcx()
+                .delayed_bug(format!("computed impossible repr (packed enum?): {ty:?}"));
+            LayoutError::ReferencesError(guar)
         }
     };
     error(cx, err)
@@ -432,8 +438,10 @@ fn layout_of_uncached<'tcx>(
         ty::Adt(def, args) if def.repr().simd() => {
             if !def.is_struct() {
                 // Should have yielded E0517 by now.
-                tcx.dcx().delayed_bug("#[repr(simd)] was applied to an ADT that is not a struct");
-                return Err(error(cx, LayoutError::Unknown(ty)));
+                let guar = tcx
+                    .dcx()
+                    .delayed_bug("#[repr(simd)] was applied to an ADT that is not a struct");
+                return Err(error(cx, LayoutError::ReferencesError(guar)));
             }
 
             let fields = &def.non_enum_variant().fields;
@@ -459,10 +467,10 @@ fn layout_of_uncached<'tcx>(
             // (should be caught by typeck)
             for fi in fields {
                 if fi.ty(tcx, args) != f0_ty {
-                    tcx.dcx().delayed_bug(
+                    let guar = tcx.dcx().delayed_bug(
                         "#[repr(simd)] was applied to an ADT with heterogeneous field type",
                     );
-                    return Err(error(cx, LayoutError::Unknown(ty)));
+                    return Err(error(cx, LayoutError::ReferencesError(guar)));
                 }
             }
 
@@ -567,11 +575,11 @@ fn layout_of_uncached<'tcx>(
 
             if def.is_union() {
                 if def.repr().pack.is_some() && def.repr().align.is_some() {
-                    tcx.dcx().span_delayed_bug(
+                    let guar = tcx.dcx().span_delayed_bug(
                         tcx.def_span(def.did()),
                         "union cannot be packed and aligned",
                     );
-                    return Err(error(cx, LayoutError::Unknown(ty)));
+                    return Err(error(cx, LayoutError::ReferencesError(guar)));
                 }
 
                 return Ok(tcx.mk_layout(
diff --git a/library/Cargo.lock b/library/Cargo.lock
index 207c744ee22..b01fec9b8f5 100644
--- a/library/Cargo.lock
+++ b/library/Cargo.lock
@@ -61,9 +61,9 @@ dependencies = [
 
 [[package]]
 name = "compiler_builtins"
-version = "0.1.140"
+version = "0.1.141"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "df14d41c5d172a886df3753d54238eefb0f61c96cbd8b363c33ccc92c457bee3"
+checksum = "b5e7a0206befe4e574e37d6d7a0fe82e88fdf54bedb0608f239cb11b7a6aa6be"
 dependencies = [
  "cc",
  "rustc-std-workspace-core",
diff --git a/library/alloc/Cargo.toml b/library/alloc/Cargo.toml
index 07596fa16f9..36f617b4526 100644
--- a/library/alloc/Cargo.toml
+++ b/library/alloc/Cargo.toml
@@ -10,7 +10,7 @@ edition = "2021"
 
 [dependencies]
 core = { path = "../core" }
-compiler_builtins = { version = "=0.1.140", features = ['rustc-dep-of-std'] }
+compiler_builtins = { version = "=0.1.141", features = ['rustc-dep-of-std'] }
 
 [dev-dependencies]
 rand = { version = "0.8.5", default-features = false, features = ["alloc"] }
diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml
index e7f7f38cb41..f34dc185eb1 100644
--- a/library/std/Cargo.toml
+++ b/library/std/Cargo.toml
@@ -17,7 +17,7 @@ cfg-if = { version = "1.0", features = ['rustc-dep-of-std'] }
 panic_unwind = { path = "../panic_unwind", optional = true }
 panic_abort = { path = "../panic_abort" }
 core = { path = "../core", public = true }
-compiler_builtins = { version = "=0.1.140" }
+compiler_builtins = { version = "=0.1.141" }
 unwind = { path = "../unwind" }
 hashbrown = { version = "0.15", default-features = false, features = [
     'rustc-dep-of-std',
diff --git a/src/bootstrap/src/core/build_steps/format.rs b/src/bootstrap/src/core/build_steps/format.rs
index 40c908c3fa9..c7eafadee2d 100644
--- a/src/bootstrap/src/core/build_steps/format.rs
+++ b/src/bootstrap/src/core/build_steps/format.rs
@@ -116,7 +116,7 @@ fn print_paths(verb: &str, adjective: Option<&str>, paths: &[String]) {
         println!("fmt: {verb} {len} {adjective}files");
     }
     if len > 1000 && !CiEnv::is_ci() {
-        println!("hint: if this number seems too high, try running `git fetch origin master");
+        println!("hint: if this number seems too high, try running `git fetch origin master`");
     }
 }
 
diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs
index 5af05c395d8..fdc1f30b859 100644
--- a/src/bootstrap/src/core/build_steps/test.rs
+++ b/src/bootstrap/src/core/build_steps/test.rs
@@ -24,8 +24,8 @@ use crate::core::config::flags::{Subcommand, get_completion};
 use crate::utils::build_stamp::{self, BuildStamp};
 use crate::utils::exec::{BootstrapCommand, command};
 use crate::utils::helpers::{
-    self, LldThreads, add_link_lib_path, add_rustdoc_cargo_linker_args, dylib_path, dylib_path_var,
-    linker_args, linker_flags, t, target_supports_cranelift_backend, up_to_date,
+    self, LldThreads, add_rustdoc_cargo_linker_args, dylib_path, dylib_path_var, linker_args,
+    linker_flags, t, target_supports_cranelift_backend, up_to_date,
 };
 use crate::utils::render_tests::{add_flags_and_try_run_tests, try_run_tests};
 use crate::{CLang, DocTests, GitRepo, Mode, PathSet, envify};
@@ -1975,11 +1975,17 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
             // Tests that use compiler libraries may inherit the `-lLLVM` link
             // requirement, but the `-L` library path is not propagated across
             // separate compilations. We can add LLVM's library path to the
-            // platform-specific environment variable as a workaround.
+            // rustc args as a workaround.
             if !builder.config.dry_run() && suite.ends_with("fulldeps") {
                 let llvm_libdir =
                     command(&llvm_config).arg("--libdir").run_capture_stdout(builder).stdout();
-                add_link_lib_path(vec![llvm_libdir.trim().into()], &mut cmd);
+                let mut rustflags = env::var("RUSTFLAGS").unwrap_or_default();
+                if target.is_msvc() {
+                    rustflags.push_str(&format!("-Clink-arg=-LIBPATH:{llvm_libdir}"));
+                } else {
+                    rustflags.push_str(&format!("-Clink-arg=-L{llvm_libdir}"));
+                }
+                cmd.env("RUSTFLAGS", rustflags);
             }
 
             if !builder.config.dry_run() && matches!(mode, "run-make" | "coverage-run") {
diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs
index 2692a129ef3..f9fb19ddb09 100644
--- a/src/bootstrap/src/core/builder/cargo.rs
+++ b/src/bootstrap/src/core/builder/cargo.rs
@@ -8,9 +8,7 @@ use crate::core::build_steps::{compile, test};
 use crate::core::config::SplitDebuginfo;
 use crate::core::config::flags::Color;
 use crate::utils::build_stamp;
-use crate::utils::helpers::{
-    self, LldThreads, add_link_lib_path, check_cfg_arg, linker_args, linker_flags,
-};
+use crate::utils::helpers::{self, LldThreads, check_cfg_arg, linker_args, linker_flags};
 use crate::{
     BootstrapCommand, CLang, Compiler, DocTests, DryRun, EXTRA_CHECK_CFGS, GitRepo, Mode,
     TargetSelection, command, prepare_behaviour_dump_dir, t,
@@ -947,12 +945,16 @@ impl Builder<'_> {
         // Tools that use compiler libraries may inherit the `-lLLVM` link
         // requirement, but the `-L` library path is not propagated across
         // separate Cargo projects. We can add LLVM's library path to the
-        // platform-specific environment variable as a workaround.
+        // rustc args as a workaround.
         if mode == Mode::ToolRustc || mode == Mode::Codegen {
             if let Some(llvm_config) = self.llvm_config(target) {
                 let llvm_libdir =
                     command(llvm_config).arg("--libdir").run_capture_stdout(self).stdout();
-                add_link_lib_path(vec![llvm_libdir.trim().into()], &mut cargo);
+                if target.is_msvc() {
+                    rustflags.arg(&format!("-Clink-arg=-LIBPATH:{llvm_libdir}"));
+                } else {
+                    rustflags.arg(&format!("-Clink-arg=-L{llvm_libdir}"));
+                }
             }
         }
 
diff --git a/src/bootstrap/src/utils/helpers.rs b/src/bootstrap/src/utils/helpers.rs
index 516c314024b..a1b1748c85b 100644
--- a/src/bootstrap/src/utils/helpers.rs
+++ b/src/bootstrap/src/utils/helpers.rs
@@ -106,31 +106,6 @@ pub fn add_dylib_path(path: Vec<PathBuf>, cmd: &mut BootstrapCommand) {
     cmd.env(dylib_path_var(), t!(env::join_paths(list)));
 }
 
-/// Adds a list of lookup paths to `cmd`'s link library lookup path.
-pub fn add_link_lib_path(path: Vec<PathBuf>, cmd: &mut BootstrapCommand) {
-    let mut list = link_lib_path();
-    for path in path {
-        list.insert(0, path);
-    }
-    cmd.env(link_lib_path_var(), t!(env::join_paths(list)));
-}
-
-/// Returns the environment variable which the link library lookup path
-/// resides in for this platform.
-fn link_lib_path_var() -> &'static str {
-    if cfg!(target_env = "msvc") { "LIB" } else { "LIBRARY_PATH" }
-}
-
-/// Parses the `link_lib_path_var()` environment variable, returning a list of
-/// paths that are members of this lookup path.
-fn link_lib_path() -> Vec<PathBuf> {
-    let var = match env::var_os(link_lib_path_var()) {
-        Some(v) => v,
-        None => return vec![],
-    };
-    env::split_paths(&var).collect()
-}
-
 pub struct TimeIt(bool, Instant);
 
 /// Returns an RAII structure that prints out how long it took to drop.
diff --git a/src/ci/docker/scripts/emscripten.sh b/src/ci/docker/scripts/emscripten.sh
deleted file mode 100644
index 8b2b39ee162..00000000000
--- a/src/ci/docker/scripts/emscripten.sh
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/bin/sh
-set -ex
-
-hide_output() {
-  set +x
-  on_err="
-echo ERROR: An error was encountered with the build.
-cat /tmp/build.log
-exit 1
-"
-  trap "$on_err" ERR
-  bash -c "while true; do sleep 30; echo \$(date) - building ...; done" &
-  PING_LOOP_PID=$!
-  "$@" &> /tmp/build.log
-  trap - ERR
-  kill $PING_LOOP_PID
-  rm -f /tmp/build.log
-  set -x
-}
-
-git clone https://github.com/emscripten-core/emsdk.git /emsdk-portable
-cd /emsdk-portable
-hide_output ./emsdk install 3.1.68
-./emsdk activate 3.1.68
diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs
index af3c7cc7be3..80bc6cebd2a 100644
--- a/src/librustdoc/config.rs
+++ b/src/librustdoc/config.rs
@@ -303,6 +303,8 @@ pub(crate) struct RenderOptions {
     pub(crate) include_parts_dir: Vec<PathToParts>,
     /// Where to write crate-info
     pub(crate) parts_out_dir: Option<PathToParts>,
+    /// disable minification of CSS/JS
+    pub(crate) disable_minification: bool,
 }
 
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
@@ -781,6 +783,9 @@ impl Options {
 
         let unstable_features =
             rustc_feature::UnstableFeatures::from_environment(crate_name.as_deref());
+
+        let disable_minification = matches.opt_present("disable-minification");
+
         let options = Options {
             bin_crate,
             proc_macro_crate,
@@ -857,6 +862,7 @@ impl Options {
             should_merge,
             include_parts_dir,
             parts_out_dir,
+            disable_minification,
         };
         Some((input, options, render_options))
     }
diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs
index 48a537ad5e7..62cf2b63f7f 100644
--- a/src/librustdoc/html/highlight.rs
+++ b/src/librustdoc/html/highlight.rs
@@ -337,7 +337,7 @@ enum Class {
     Ident(Span),
     Lifetime,
     PreludeTy(Span),
-    PreludeVal,
+    PreludeVal(Span),
     QuestionMark,
     Decoration(&'static str),
 }
@@ -385,7 +385,7 @@ impl Class {
             Class::Ident(_) => "",
             Class::Lifetime => "lifetime",
             Class::PreludeTy(_) => "prelude-ty",
-            Class::PreludeVal => "prelude-val",
+            Class::PreludeVal(_) => "prelude-val",
             Class::QuestionMark => "question-mark",
             Class::Decoration(kind) => kind,
         }
@@ -395,7 +395,11 @@ impl Class {
     /// a "span" (a tuple representing `(lo, hi)` equivalent of `Span`).
     fn get_span(self) -> Option<Span> {
         match self {
-            Self::Ident(sp) | Self::Self_(sp) | Self::Macro(sp) | Self::PreludeTy(sp) => Some(sp),
+            Self::Ident(sp)
+            | Self::Self_(sp)
+            | Self::Macro(sp)
+            | Self::PreludeTy(sp)
+            | Self::PreludeVal(sp) => Some(sp),
             Self::Comment
             | Self::DocComment
             | Self::Attribute
@@ -406,7 +410,6 @@ impl Class {
             | Self::Number
             | Self::Bool
             | Self::Lifetime
-            | Self::PreludeVal
             | Self::QuestionMark
             | Self::Decoration(_) => None,
         }
@@ -851,7 +854,9 @@ impl<'src> Classifier<'src> {
             TokenKind::Ident => match get_real_ident_class(text, false) {
                 None => match text {
                     "Option" | "Result" => Class::PreludeTy(self.new_span(before, text)),
-                    "Some" | "None" | "Ok" | "Err" => Class::PreludeVal,
+                    "Some" | "None" | "Ok" | "Err" => {
+                        Class::PreludeVal(self.new_span(before, text))
+                    }
                     // "union" is a weak keyword and is only considered as a keyword when declaring
                     // a union type.
                     "union" if self.check_if_is_union_keyword() => Class::KeyWord,
diff --git a/src/librustdoc/html/render/span_map.rs b/src/librustdoc/html/render/span_map.rs
index 26f75fa241c..85f87f01afd 100644
--- a/src/librustdoc/html/render/span_map.rs
+++ b/src/librustdoc/html/render/span_map.rs
@@ -4,7 +4,7 @@ use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::{DefId, LOCAL_CRATE};
 use rustc_hir::intravisit::{self, Visitor};
-use rustc_hir::{ExprKind, HirId, Item, ItemKind, Mod, Node};
+use rustc_hir::{ExprKind, HirId, Item, ItemKind, Mod, Node, Pat, PatKind, QPath};
 use rustc_middle::hir::nested_filter;
 use rustc_middle::ty::TyCtxt;
 use rustc_span::hygiene::MacroKind;
@@ -170,7 +170,7 @@ impl SpanMapVisitor<'_> {
         true
     }
 
-    fn handle_call(&mut self, hir_id: HirId, expr_hir_id: Option<HirId>, span: Span) {
+    fn infer_id(&mut self, hir_id: HirId, expr_hir_id: Option<HirId>, span: Span) {
         let hir = self.tcx.hir();
         let body_id = hir.enclosing_body_owner(hir_id);
         // FIXME: this is showing error messages for parts of the code that are not
@@ -189,6 +189,27 @@ impl SpanMapVisitor<'_> {
             self.matches.insert(span, link);
         }
     }
+
+    fn handle_pat(&mut self, p: &Pat<'_>) {
+        match p.kind {
+            PatKind::Binding(_, _, _, Some(p)) => self.handle_pat(p),
+            PatKind::Struct(qpath, _, _)
+            | PatKind::TupleStruct(qpath, _, _)
+            | PatKind::Path(qpath) => match qpath {
+                QPath::TypeRelative(_, path) if matches!(path.res, Res::Err) => {
+                    self.infer_id(path.hir_id, Some(p.hir_id), qpath.span());
+                }
+                QPath::Resolved(_, path) => self.handle_path(path),
+                _ => {}
+            },
+            PatKind::Or(pats) => {
+                for pat in pats {
+                    self.handle_pat(pat);
+                }
+            }
+            _ => {}
+        }
+    }
 }
 
 impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> {
@@ -206,6 +227,10 @@ impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> {
         intravisit::walk_path(self, path);
     }
 
+    fn visit_pat(&mut self, p: &Pat<'tcx>) {
+        self.handle_pat(p);
+    }
+
     fn visit_mod(&mut self, m: &'tcx Mod<'tcx>, span: Span, id: HirId) {
         // To make the difference between "mod foo {}" and "mod foo;". In case we "import" another
         // file, we want to link to it. Otherwise no need to create a link.
@@ -228,9 +253,9 @@ impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> {
     fn visit_expr(&mut self, expr: &'tcx rustc_hir::Expr<'tcx>) {
         match expr.kind {
             ExprKind::MethodCall(segment, ..) => {
-                self.handle_call(segment.hir_id, Some(expr.hir_id), segment.ident.span)
+                self.infer_id(segment.hir_id, Some(expr.hir_id), segment.ident.span)
             }
-            ExprKind::Call(call, ..) => self.handle_call(call.hir_id, None, call.span),
+            ExprKind::Call(call, ..) => self.infer_id(call.hir_id, None, call.span),
             _ => {
                 if self.handle_macro(expr.span) {
                     // We don't want to go deeper into the macro.
diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs
index ce10e5ecc24..fb6f3bc2c76 100644
--- a/src/librustdoc/html/render/write_shared.rs
+++ b/src/librustdoc/html/render/write_shared.rs
@@ -207,7 +207,15 @@ fn write_static_files(
     if opt.emit.is_empty() || opt.emit.contains(&EmitType::Toolchain) {
         static_files::for_each(|f: &static_files::StaticFile| {
             let filename = static_dir.join(f.output_filename());
-            fs::write(&filename, f.minified()).map_err(|e| PathError::new(e, &filename))
+            let contents: &[u8];
+            let contents_vec: Vec<u8>;
+            if opt.disable_minification {
+                contents = f.bytes;
+            } else {
+                contents_vec = f.minified();
+                contents = &contents_vec;
+            };
+            fs::write(&filename, contents).map_err(|e| PathError::new(e, &filename))
         })?;
     }
 
diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js
index 5fd5eb14478..0a0550ab82f 100644
--- a/src/librustdoc/html/static/js/search.js
+++ b/src/librustdoc/html/static/js/search.js
@@ -2717,9 +2717,26 @@ class DocSearch {
             const normalizedUserQuery = parsedQuery.userQuery.toLowerCase();
             const isMixedCase = normalizedUserQuery !== userQuery;
             const result_list = [];
+            const isReturnTypeQuery = parsedQuery.elems.length === 0 ||
+                typeInfo === "returned";
             for (const result of results.values()) {
                 result.item = this.searchIndex[result.id];
                 result.word = this.searchIndex[result.id].word;
+                if (isReturnTypeQuery) {
+                    // we are doing a return-type based search,
+                    // deprioritize "clone-like" results,
+                    // ie. functions that also take the queried type as an argument.
+                    const hasType = result.item && result.item.type;
+                    if (!hasType) {
+                        continue;
+                    }
+                    const inputs = result.item.type.inputs;
+                    const where_clause = result.item.type.where_clause;
+                    if (containsTypeFromQuery(inputs, where_clause)) {
+                        result.path_dist *= 100;
+                        result.dist *= 100;
+                    }
+                }
                 result_list.push(result);
             }
 
@@ -3541,6 +3558,35 @@ class DocSearch {
         }
 
         /**
+         * This function checks if the given list contains any
+         * (non-generic) types mentioned in the query.
+         *
+         * @param {Array<FunctionType>} list    - A list of function types.
+         * @param {[FunctionType]} where_clause - Trait bounds for generic items.
+         */
+        function containsTypeFromQuery(list, where_clause) {
+            if (!list) return false;
+            for (const ty of parsedQuery.returned) {
+                // negative type ids are generics
+                if (ty.id < 0) {
+                    continue;
+                }
+                if (checkIfInList(list, ty, where_clause, null, 0)) {
+                    return true;
+                }
+            }
+            for (const ty of parsedQuery.elems) {
+                if (ty.id < 0) {
+                    continue;
+                }
+                if (checkIfInList(list, ty, where_clause, null, 0)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        /**
          * This function checks if the object (`row`) matches the given type (`elem`) and its
          * generics (if any).
          *
diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs
index 7fcdfe3fb22..33166a39574 100644
--- a/src/librustdoc/json/conversions.rs
+++ b/src/librustdoc/json/conversions.rs
@@ -622,7 +622,7 @@ impl FromClean<clean::Type> for Type {
 impl FromClean<clean::Path> for Path {
     fn from_clean(path: clean::Path, renderer: &JsonRenderer<'_>) -> Path {
         Path {
-            name: path.whole_name(),
+            name: path.last_opt().map_or(String::from(""), |s| String::from(s.as_str())),
             id: renderer.id_from_item_default(path.def_id().into()),
             args: path.segments.last().map(|args| Box::new(args.clone().args.into_json(renderer))),
         }
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 96ca96ee6bc..ba620b6cb6b 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -651,8 +651,15 @@ fn opts() -> Vec<RustcOptGroup> {
             "",
             "add arguments to be used when compiling doctests",
         ),
+        opt(
+            Unstable,
+            FlagMulti,
+            "",
+            "disable-minification",
+            "disable the minification of CSS/JS files (perma-unstable, do not use with cached files)",
+            "",
+        ),
         // deprecated / removed options
-        opt(Unstable, FlagMulti, "", "disable-minification", "removed", ""),
         opt(
             Stable,
             Multi,
diff --git a/src/rustdoc-json-types/lib.rs b/src/rustdoc-json-types/lib.rs
index 84b33e3d860..5a99977ded5 100644
--- a/src/rustdoc-json-types/lib.rs
+++ b/src/rustdoc-json-types/lib.rs
@@ -30,7 +30,7 @@ pub type FxHashMap<K, V> = HashMap<K, V>; // re-export for use in src/librustdoc
 /// This integer is incremented with every breaking change to the API,
 /// and is returned along with the JSON blob as [`Crate::format_version`].
 /// Consuming code should assert that this value matches the format version(s) that it supports.
-pub const FORMAT_VERSION: u32 = 37;
+pub const FORMAT_VERSION: u32 = 38;
 
 /// The root of the emitted JSON blob.
 ///
diff --git a/tests/codegen-units/item-collection/closures.rs b/tests/codegen-units/item-collection/closures.rs
index 5fc80230925..864f98817a8 100644
--- a/tests/codegen-units/item-collection/closures.rs
+++ b/tests/codegen-units/item-collection/closures.rs
@@ -10,3 +10,9 @@ pub async fn async_fn() {}
 pub fn closure() {
     let _ = || {};
 }
+
+//~ MONO_ITEM fn A::{constant#0}::{closure#0} @@
+trait A where
+    [(); (|| {}, 1).1]: Sized,
+{
+}
diff --git a/tests/codegen-units/item-collection/drop-glue-eager.rs b/tests/codegen-units/item-collection/drop-glue-eager.rs
new file mode 100644
index 00000000000..77470767ee1
--- /dev/null
+++ b/tests/codegen-units/item-collection/drop-glue-eager.rs
@@ -0,0 +1,43 @@
+// Ensure that we *eagerly* monomorphize drop instances for structs with lifetimes.
+
+//@ compile-flags:-Zprint-mono-items=eager
+//@ compile-flags:--crate-type=lib
+
+//~ MONO_ITEM fn std::ptr::drop_in_place::<StructWithDrop> - shim(Some(StructWithDrop))
+struct StructWithDrop {
+    x: i32,
+}
+
+impl Drop for StructWithDrop {
+    //~ MONO_ITEM fn <StructWithDrop as std::ops::Drop>::drop
+    fn drop(&mut self) {}
+}
+
+struct StructNoDrop {
+    x: i32,
+}
+
+//~ MONO_ITEM fn std::ptr::drop_in_place::<EnumWithDrop> - shim(Some(EnumWithDrop))
+enum EnumWithDrop {
+    A(i32),
+}
+
+impl Drop for EnumWithDrop {
+    //~ MONO_ITEM fn <EnumWithDrop as std::ops::Drop>::drop
+    fn drop(&mut self) {}
+}
+
+enum EnumNoDrop {
+    A(i32),
+}
+
+// We should be able to monomorphize drops for struct with lifetimes.
+impl<'a> Drop for StructWithDropAndLt<'a> {
+    //~ MONO_ITEM fn <StructWithDropAndLt<'_> as std::ops::Drop>::drop
+    fn drop(&mut self) {}
+}
+
+//~ MONO_ITEM fn std::ptr::drop_in_place::<StructWithDropAndLt<'_>> - shim(Some(StructWithDropAndLt<'_>))
+struct StructWithDropAndLt<'a> {
+    x: &'a i32,
+}
diff --git a/tests/run-make/rustdoc-default-output/output-default.stdout b/tests/run-make/rustdoc-default-output/output-default.stdout
index c2d9309ba2e..c1b246e849c 100644
--- a/tests/run-make/rustdoc-default-output/output-default.stdout
+++ b/tests/run-make/rustdoc-default-output/output-default.stdout
@@ -194,7 +194,8 @@ Options:
         --doctest-compilation-args add arguments to be used when compiling doctests
                         
         --disable-minification 
-                        removed
+                        disable the minification of CSS/JS files
+                        (perma-unstable, do not use with cached files)
         --plugin-path DIR
                         removed, see issue #44136
                         <https://github.com/rust-lang/rust/issues/44136> for
diff --git a/tests/rustdoc-js-std/return-based-sort.js b/tests/rustdoc-js-std/return-based-sort.js
new file mode 100644
index 00000000000..30baf1cd36e
--- /dev/null
+++ b/tests/rustdoc-js-std/return-based-sort.js
@@ -0,0 +1,30 @@
+// test that `clone`-like functions are sorted lower when
+// a search is based soley on return type
+
+const FILTER_CRATE = "core";
+
+const EXPECTED = [
+    {
+        'query': '-> AllocError',
+        'others': [
+            { 'path': 'core::alloc::Allocator', 'name': 'allocate' },
+            { 'path': 'core::alloc::AllocError', 'name': 'clone' },
+        ],
+    },
+    {
+        'query': 'AllocError',
+        'returned': [
+            { 'path': 'core::alloc::Allocator', 'name': 'allocate' },
+            { 'path': 'core::alloc::AllocError', 'name': 'clone' },
+         ],
+    },
+    {
+        'query': '-> &str',
+        'others': [
+            // type_name_of_val should not be consider clone-like
+            { 'path': 'core::any', 'name': 'type_name_of_val' },
+            // this returns `Option<&str>`, and thus should be sorted lower
+            { 'path': 'core::str::Split', 'name': 'next' },
+         ],
+    },
+]
diff --git a/tests/rustdoc-json/return_private.rs b/tests/rustdoc-json/return_private.rs
index 0b341e2bda7..c238a536e0d 100644
--- a/tests/rustdoc-json/return_private.rs
+++ b/tests/rustdoc-json/return_private.rs
@@ -6,7 +6,7 @@ mod secret {
 }
 
 //@ has "$.index[*][?(@.name=='get_secret')].inner.function"
-//@ is "$.index[*][?(@.name=='get_secret')].inner.function.sig.output.resolved_path.name" \"secret::Secret\"
+//@ is "$.index[*][?(@.name=='get_secret')].inner.function.sig.output.resolved_path.name" \"Secret\"
 pub fn get_secret() -> secret::Secret {
     secret::Secret
 }
diff --git a/tests/rustdoc/jump-to-def-pats.rs b/tests/rustdoc/jump-to-def-pats.rs
new file mode 100644
index 00000000000..147902b44cf
--- /dev/null
+++ b/tests/rustdoc/jump-to-def-pats.rs
@@ -0,0 +1,52 @@
+// This test ensures that patterns also get a link generated.
+
+//@ compile-flags: -Zunstable-options --generate-link-to-definition
+
+#![crate_name = "foo"]
+
+//@ has 'src/foo/jump-to-def-pats.rs.html'
+
+use std::fmt;
+
+pub enum MyEnum<T, E> {
+    Ok(T),
+    Err(E),
+    Some(T),
+    None,
+}
+
+pub enum X {
+    A,
+}
+
+pub fn foo() -> Result<(), ()> {
+    // FIXME: would be nice to be able to check both the class and the href at the same time so
+    // we could check the text as well...
+    //@ has - '//a[@class="prelude-val"]/@href' '{{channel}}/core/result/enum.Result.html#variant.Ok'
+    //@ has - '//a[@href="{{channel}}/core/result/enum.Result.html#variant.Ok"]' 'Ok'
+    Ok(())
+}
+
+impl<T, E> fmt::Display for MyEnum<T, E> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match self {
+            //@ has - '//a[@href="#12"]' 'Self::Ok'
+            Self::Ok(_) => f.write_str("MyEnum::Ok"),
+            //@ has - '//a[@href="#13"]' 'MyEnum::Err'
+            MyEnum::Err(_) => f.write_str("MyEnum::Err"),
+            //@ has - '//a[@href="#14"]' 'Self::Some'
+            Self::Some(_) => f.write_str("MyEnum::Some"),
+            //@ has - '//a[@href="#15"]' 'Self::None'
+            Self::None => f.write_str("MyEnum::None"),
+        }
+    }
+}
+
+impl X {
+    fn p(&self) -> &str {
+        match self {
+            //@ has - '//a[@href="#19"]' 'Self::A'
+            Self::A => "X::A",
+        }
+    }
+}
diff --git a/tests/ui/closures/binder/nested-closures-regions.stderr b/tests/ui/closures/binder/nested-closures-regions.stderr
index a30339ac67b..909cbcaa808 100644
--- a/tests/ui/closures/binder/nested-closures-regions.stderr
+++ b/tests/ui/closures/binder/nested-closures-regions.stderr
@@ -9,7 +9,7 @@ LL |     for<'a> || -> () { for<'c> |_: &'a ()| -> () {}; };
                extern "rust-call" fn((&(),)),
                (),
            ]
-   = note: late-bound region is '?4
+   = note: late-bound region is '?3
    = note: late-bound region is '?2
    = note: number of external vids: 3
    = note: where '?1: '?2
@@ -26,7 +26,7 @@ LL |     for<'a> || -> () { for<'c> |_: &'a ()| -> () {}; };
                extern "rust-call" fn(()),
                (),
            ]
-   = note: late-bound region is '?2
+   = note: late-bound region is '?1
 
 note: no external requirements
   --> $DIR/nested-closures-regions.rs:7:1
diff --git a/tests/ui/const-generics/type-mismatch-in-nested-goal.current.stderr b/tests/ui/const-generics/type-mismatch-in-nested-goal.current.stderr
new file mode 100644
index 00000000000..c6fb07926c8
--- /dev/null
+++ b/tests/ui/const-generics/type-mismatch-in-nested-goal.current.stderr
@@ -0,0 +1,45 @@
+error: the constant `N` is not of type `bool`
+  --> $DIR/type-mismatch-in-nested-goal.rs:9:50
+   |
+LL | fn needs_a<const N: usize>(_: [u8; N]) where (): A<N> {}
+   |                                                  ^^^^ expected `bool`, found `usize`
+   |
+note: required by a const generic parameter in `A`
+  --> $DIR/type-mismatch-in-nested-goal.rs:5:9
+   |
+LL | trait A<const B: bool> {}
+   |         ^^^^^^^^^^^^^ required by this const generic parameter in `A`
+
+error: the constant `true` is not of type `usize`
+  --> $DIR/type-mismatch-in-nested-goal.rs:13:13
+   |
+LL |     needs_a([]);
+   |     ------- ^^ expected `usize`, found `bool`
+   |     |
+   |     required by a bound introduced by this call
+   |
+note: required by a const generic parameter in `needs_a`
+  --> $DIR/type-mismatch-in-nested-goal.rs:9:12
+   |
+LL | fn needs_a<const N: usize>(_: [u8; N]) where (): A<N> {}
+   |            ^^^^^^^^^^^^^^ required by this const generic parameter in `needs_a`
+
+error[E0308]: mismatched types
+  --> $DIR/type-mismatch-in-nested-goal.rs:13:13
+   |
+LL |     needs_a([]);
+   |     ------- ^^ expected an array with a size of true, found one with a size of 0
+   |     |
+   |     arguments to this function are incorrect
+   |
+   = note: expected array `[u8; true]`
+              found array `[_; 0]`
+note: function defined here
+  --> $DIR/type-mismatch-in-nested-goal.rs:9:4
+   |
+LL | fn needs_a<const N: usize>(_: [u8; N]) where (): A<N> {}
+   |    ^^^^^^^                 ----------
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/const-generics/type-mismatch-in-nested-goal.next.stderr b/tests/ui/const-generics/type-mismatch-in-nested-goal.next.stderr
new file mode 100644
index 00000000000..c6fb07926c8
--- /dev/null
+++ b/tests/ui/const-generics/type-mismatch-in-nested-goal.next.stderr
@@ -0,0 +1,45 @@
+error: the constant `N` is not of type `bool`
+  --> $DIR/type-mismatch-in-nested-goal.rs:9:50
+   |
+LL | fn needs_a<const N: usize>(_: [u8; N]) where (): A<N> {}
+   |                                                  ^^^^ expected `bool`, found `usize`
+   |
+note: required by a const generic parameter in `A`
+  --> $DIR/type-mismatch-in-nested-goal.rs:5:9
+   |
+LL | trait A<const B: bool> {}
+   |         ^^^^^^^^^^^^^ required by this const generic parameter in `A`
+
+error: the constant `true` is not of type `usize`
+  --> $DIR/type-mismatch-in-nested-goal.rs:13:13
+   |
+LL |     needs_a([]);
+   |     ------- ^^ expected `usize`, found `bool`
+   |     |
+   |     required by a bound introduced by this call
+   |
+note: required by a const generic parameter in `needs_a`
+  --> $DIR/type-mismatch-in-nested-goal.rs:9:12
+   |
+LL | fn needs_a<const N: usize>(_: [u8; N]) where (): A<N> {}
+   |            ^^^^^^^^^^^^^^ required by this const generic parameter in `needs_a`
+
+error[E0308]: mismatched types
+  --> $DIR/type-mismatch-in-nested-goal.rs:13:13
+   |
+LL |     needs_a([]);
+   |     ------- ^^ expected an array with a size of true, found one with a size of 0
+   |     |
+   |     arguments to this function are incorrect
+   |
+   = note: expected array `[u8; true]`
+              found array `[_; 0]`
+note: function defined here
+  --> $DIR/type-mismatch-in-nested-goal.rs:9:4
+   |
+LL | fn needs_a<const N: usize>(_: [u8; N]) where (): A<N> {}
+   |    ^^^^^^^                 ----------
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/const-generics/type-mismatch-in-nested-goal.rs b/tests/ui/const-generics/type-mismatch-in-nested-goal.rs
new file mode 100644
index 00000000000..fd29019f89b
--- /dev/null
+++ b/tests/ui/const-generics/type-mismatch-in-nested-goal.rs
@@ -0,0 +1,17 @@
+//@ revisions: current next
+//@[next] compile-flags: -Znext-solver
+//@ ignore-compare-mode-next-solver (explicit revisions)
+
+trait A<const B: bool> {}
+
+impl A<true> for () {}
+
+fn needs_a<const N: usize>(_: [u8; N]) where (): A<N> {}
+//~^ ERROR the constant `N` is not of type `bool`
+
+pub fn main() {
+    needs_a([]);
+    //~^ ERROR the constant `true` is not of type `usize`
+    //~| ERROR mismatched types
+    // FIXME(const_generics): we should hide this error as we've already errored above
+}
diff --git a/tests/ui/enum-discriminant/eval-error.rs b/tests/ui/enum-discriminant/eval-error.rs
new file mode 100644
index 00000000000..f2c3b581627
--- /dev/null
+++ b/tests/ui/enum-discriminant/eval-error.rs
@@ -0,0 +1,37 @@
+union Foo {
+    a: str,
+    //~^ ERROR the size for values of type `str` cannot be known at compilation time
+    //~| ERROR field must implement `Copy` or be wrapped in `ManuallyDrop<...>`
+}
+
+enum Bar {
+    Boo = {
+        let _: Option<Foo> = None;
+        0
+    },
+}
+
+union Foo2 {}
+//~^ ERROR unions cannot have zero fields
+
+enum Bar2 {
+    Boo = {
+        let _: Option<Foo2> = None;
+        0
+    },
+}
+
+#[repr(u8, packed)]
+//~^ ERROR attribute should be applied to a struct or union
+enum Foo3 {
+    A
+}
+
+enum Bar3 {
+    Boo = {
+        let _: Option<Foo3> = None;
+        0
+    },
+}
+
+fn main() {}
diff --git a/tests/ui/enum-discriminant/eval-error.stderr b/tests/ui/enum-discriminant/eval-error.stderr
new file mode 100644
index 00000000000..0f12308de3c
--- /dev/null
+++ b/tests/ui/enum-discriminant/eval-error.stderr
@@ -0,0 +1,51 @@
+error: unions cannot have zero fields
+  --> $DIR/eval-error.rs:14:1
+   |
+LL | union Foo2 {}
+   | ^^^^^^^^^^^^^
+
+error[E0517]: attribute should be applied to a struct or union
+  --> $DIR/eval-error.rs:24:12
+   |
+LL |   #[repr(u8, packed)]
+   |              ^^^^^^
+LL |
+LL | / enum Foo3 {
+LL | |     A
+LL | | }
+   | |_- not a struct or union
+
+error[E0277]: the size for values of type `str` cannot be known at compilation time
+  --> $DIR/eval-error.rs:2:8
+   |
+LL |     a: str,
+   |        ^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `str`
+   = note: no field of a union may have a dynamically sized type
+   = help: change the field's type to have a statically known size
+help: borrowed types always have a statically known size
+   |
+LL |     a: &str,
+   |        +
+help: the `Box` type always has a statically known size and allocates its contents in the heap
+   |
+LL |     a: Box<str>,
+   |        ++++   +
+
+error[E0740]: field must implement `Copy` or be wrapped in `ManuallyDrop<...>` to be used in a union
+  --> $DIR/eval-error.rs:2:5
+   |
+LL |     a: str,
+   |     ^^^^^^
+   |
+   = note: union fields must not have drop side-effects, which is currently enforced via either `Copy` or `ManuallyDrop<...>`
+help: wrap the field type in `ManuallyDrop<...>`
+   |
+LL |     a: std::mem::ManuallyDrop<str>,
+   |        +++++++++++++++++++++++   +
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0277, E0517, E0740.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/invalid_dispatch_from_dyn_impls.stderr b/tests/ui/invalid_dispatch_from_dyn_impls.stderr
index 168ed37d0e6..02718334c73 100644
--- a/tests/ui/invalid_dispatch_from_dyn_impls.stderr
+++ b/tests/ui/invalid_dispatch_from_dyn_impls.stderr
@@ -1,4 +1,4 @@
-error[E0378]: the trait `DispatchFromDyn` may only be implemented for structs containing the field being coerced, ZST fields with 1 byte alignment, and nothing else
+error[E0378]: the trait `DispatchFromDyn` may only be implemented for structs containing the field being coerced, ZST fields with 1 byte alignment that don't mention type/const generics, and nothing else
   --> $DIR/invalid_dispatch_from_dyn_impls.rs:10:1
    |
 LL | / impl<T, U> DispatchFromDyn<WrapperWithExtraField<U>> for WrapperWithExtraField<T>
@@ -35,7 +35,7 @@ LL | | where
 LL | |     T: Unsize<U>,
    | |_________________^
 
-error[E0378]: the trait `DispatchFromDyn` may only be implemented for structs containing the field being coerced, ZST fields with 1 byte alignment, and nothing else
+error[E0378]: the trait `DispatchFromDyn` may only be implemented for structs containing the field being coerced, ZST fields with 1 byte alignment that don't mention type/const generics, and nothing else
   --> $DIR/invalid_dispatch_from_dyn_impls.rs:46:1
    |
 LL | / impl<T: ?Sized, U: ?Sized> DispatchFromDyn<OverAligned<U>> for OverAligned<T>
diff --git a/tests/ui/layout/base-layout-is-sized-ice-123078.rs b/tests/ui/layout/base-layout-is-sized-ice-123078.rs
index b1c33e15075..15f11145f84 100644
--- a/tests/ui/layout/base-layout-is-sized-ice-123078.rs
+++ b/tests/ui/layout/base-layout-is-sized-ice-123078.rs
@@ -8,7 +8,6 @@ struct S {
 }
 
 const C: S = unsafe { std::mem::transmute(()) };
-//~^ ERROR cannot transmute between types of different sizes, or dependently-sized types
 const _: [(); {
     C;
     0
diff --git a/tests/ui/layout/base-layout-is-sized-ice-123078.stderr b/tests/ui/layout/base-layout-is-sized-ice-123078.stderr
index 455bd2cbf8b..9181368533a 100644
--- a/tests/ui/layout/base-layout-is-sized-ice-123078.stderr
+++ b/tests/ui/layout/base-layout-is-sized-ice-123078.stderr
@@ -16,16 +16,6 @@ help: the `Box` type always has a statically known size and allocates its conten
 LL |     a: Box<[u8]>,
    |        ++++    +
 
-error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
-  --> $DIR/base-layout-is-sized-ice-123078.rs:10:23
-   |
-LL | const C: S = unsafe { std::mem::transmute(()) };
-   |                       ^^^^^^^^^^^^^^^^^^^
-   |
-   = note: source type: `()` (0 bits)
-   = note: target type: `S` (size can vary because of [u8])
-
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
-Some errors have detailed explanations: E0277, E0512.
-For more information about an error, try `rustc --explain E0277`.
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/layout/debug.stderr b/tests/ui/layout/debug.stderr
index 1fc55511384..319c0de26a9 100644
--- a/tests/ui/layout/debug.stderr
+++ b/tests/ui/layout/debug.stderr
@@ -590,7 +590,7 @@ LL | type Impossible = (str, str);
    = help: the trait `Sized` is not implemented for `str`
    = note: only the last element of a tuple may have a dynamically sized type
 
-error: the type `EmptyUnion` has an unknown layout
+error: the type has an unknown layout
   --> $DIR/debug.rs:83:1
    |
 LL | union EmptyUnion {}
diff --git a/tests/ui/nll/closure-requirements/escape-argument-callee.stderr b/tests/ui/nll/closure-requirements/escape-argument-callee.stderr
index a7a59dccf22..a445534c8d8 100644
--- a/tests/ui/nll/closure-requirements/escape-argument-callee.stderr
+++ b/tests/ui/nll/closure-requirements/escape-argument-callee.stderr
@@ -17,7 +17,7 @@ LL |         let mut closure = expect_sig(|p, y| *p = y);
    |                                       -  -  ^^^^^^ assignment requires that `'1` must outlive `'2`
    |                                       |  |
    |                                       |  has type `&'1 i32`
-   |                                       has type `&'?2 mut &'2 i32`
+   |                                       has type `&'?1 mut &'2 i32`
 
 note: no external requirements
   --> $DIR/escape-argument-callee.rs:20:1
diff --git a/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr b/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr
index 0094d7a50d3..621c1ea083b 100644
--- a/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr
+++ b/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr
@@ -20,7 +20,7 @@ LL |     foo(cell, |cell_a, cell_x| {
 LL |         cell_a.set(cell_x.get()); // forces 'x: 'a, error in closure
    |         ^^^^^^^^^^^^^^^^^^^^^^^^ `cell_x` escapes the closure body here
    |
-   = note: requirement occurs because of the type `Cell<&'?8 u32>`, which makes the generic argument `&'?8 u32` invariant
+   = note: requirement occurs because of the type `Cell<&'?9 u32>`, which makes the generic argument `&'?9 u32` invariant
    = note: the struct `Cell<T>` is invariant over the parameter `T`
    = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
 
diff --git a/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr b/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr
index 4558ff50674..f48ed2823dd 100644
--- a/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr
+++ b/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr
@@ -16,9 +16,9 @@ error: lifetime may not live long enough
   --> $DIR/propagate-fail-to-approximate-longer-no-bounds.rs:37:9
    |
 LL |     establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
-   |                                                ---------  - has type `&'?7 Cell<&'1 u32>`
+   |                                                ---------  - has type `&'?6 Cell<&'1 u32>`
    |                                                |
-   |                                                has type `&'?5 Cell<&'2 &'?1 u32>`
+   |                                                has type `&'?4 Cell<&'2 &'?1 u32>`
 LL |         // Only works if 'x: 'y:
 LL |         demand_y(x, y, x.get())
    |         ^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
diff --git a/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr b/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr
index 83173ae80c0..a090e94593f 100644
--- a/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr
+++ b/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr
@@ -16,9 +16,9 @@ error: lifetime may not live long enough
   --> $DIR/propagate-fail-to-approximate-longer-wrong-bounds.rs:41:9
    |
 LL |     establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| {
-   |                                                ----------  ---------- has type `&'?8 Cell<&'2 &'?2 u32>`
+   |                                                ----------  ---------- has type `&'?7 Cell<&'2 &'?2 u32>`
    |                                                |
-   |                                                has type `&'?6 Cell<&'1 &'?1 u32>`
+   |                                                has type `&'?5 Cell<&'1 &'?1 u32>`
 LL |         // Only works if 'x: 'y:
 LL |         demand_y(x, y, x.get())
    |         ^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
diff --git a/tests/ui/self/dispatch-from-dyn-zst-transmute-zst-nonzst.rs b/tests/ui/self/dispatch-from-dyn-zst-transmute-zst-nonzst.rs
new file mode 100644
index 00000000000..71f198f7dc7
--- /dev/null
+++ b/tests/ui/self/dispatch-from-dyn-zst-transmute-zst-nonzst.rs
@@ -0,0 +1,25 @@
+// We used to allow erroneous `DispatchFromDyn` impls whose RHS type contained
+// fields that weren't ZSTs. I don't believe this was possible to abuse, but
+// it's at least nice to give users better errors.
+
+#![feature(arbitrary_self_types)]
+#![feature(unsize)]
+#![feature(dispatch_from_dyn)]
+
+use std::marker::Unsize;
+use std::ops::DispatchFromDyn;
+
+struct Dispatchable<T: ?Sized, Z> {
+    _ptr: Box<T>,
+    z: Z,
+}
+
+impl<T, U> DispatchFromDyn<Dispatchable<U, i32>> for Dispatchable<T, ()>
+//~^ ERROR implementing the `DispatchFromDyn` trait requires multiple coercions
+where
+    T: Unsize<U> + ?Sized,
+    U: ?Sized,
+{
+}
+
+fn main() {}
diff --git a/tests/ui/self/dispatch-from-dyn-zst-transmute-zst-nonzst.stderr b/tests/ui/self/dispatch-from-dyn-zst-transmute-zst-nonzst.stderr
new file mode 100644
index 00000000000..1f13c51f679
--- /dev/null
+++ b/tests/ui/self/dispatch-from-dyn-zst-transmute-zst-nonzst.stderr
@@ -0,0 +1,16 @@
+error[E0378]: implementing the `DispatchFromDyn` trait requires multiple coercions
+  --> $DIR/dispatch-from-dyn-zst-transmute-zst-nonzst.rs:17:1
+   |
+LL | / impl<T, U> DispatchFromDyn<Dispatchable<U, i32>> for Dispatchable<T, ()>
+LL | |
+LL | | where
+LL | |     T: Unsize<U> + ?Sized,
+LL | |     U: ?Sized,
+   | |______________^
+   |
+   = note: the trait `DispatchFromDyn` may only be implemented for a coercion between structures with a single field being coerced
+   = note: currently, 2 fields need coercions: `_ptr` (`Box<T>` to `Box<U>`), `z` (`()` to `i32`)
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0378`.
diff --git a/tests/ui/self/dispatch-from-dyn-zst-transmute.rs b/tests/ui/self/dispatch-from-dyn-zst-transmute.rs
new file mode 100644
index 00000000000..57c255b4d7b
--- /dev/null
+++ b/tests/ui/self/dispatch-from-dyn-zst-transmute.rs
@@ -0,0 +1,34 @@
+#![feature(arbitrary_self_types)]
+#![feature(unsize)]
+#![feature(dispatch_from_dyn)]
+
+use std::marker::PhantomData;
+use std::marker::Unsize;
+use std::ops::DispatchFromDyn;
+use std::ops::Deref;
+
+struct IsSendToken<T: ?Sized>(PhantomData<fn(T) -> T>);
+
+struct Foo<'a, U: ?Sized> {
+    token: IsSendToken<U>,
+    ptr: &'a U,
+}
+
+impl<'a, T, U> DispatchFromDyn<Foo<'a, U>> for Foo<'a, T>
+//~^ ERROR implementing the `DispatchFromDyn` trait requires multiple coercions
+where
+    T: Unsize<U> + ?Sized,
+    U: ?Sized {}
+
+trait Bar {
+    fn f(self: Foo<'_, Self>);
+}
+
+impl<U: ?Sized> Deref for Foo<'_, U> {
+    type Target = U;
+    fn deref(&self) -> &U {
+        self.ptr
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/self/dispatch-from-dyn-zst-transmute.stderr b/tests/ui/self/dispatch-from-dyn-zst-transmute.stderr
new file mode 100644
index 00000000000..5a8ae88b5f1
--- /dev/null
+++ b/tests/ui/self/dispatch-from-dyn-zst-transmute.stderr
@@ -0,0 +1,16 @@
+error[E0378]: implementing the `DispatchFromDyn` trait requires multiple coercions
+  --> $DIR/dispatch-from-dyn-zst-transmute.rs:17:1
+   |
+LL | / impl<'a, T, U> DispatchFromDyn<Foo<'a, U>> for Foo<'a, T>
+LL | |
+LL | | where
+LL | |     T: Unsize<U> + ?Sized,
+LL | |     U: ?Sized {}
+   | |_____________^
+   |
+   = note: the trait `DispatchFromDyn` may only be implemented for a coercion between structures with a single field being coerced
+   = note: currently, 2 fields need coercions: `token` (`IsSendToken<T>` to `IsSendToken<U>`), `ptr` (`&'a T` to `&'a U`)
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0378`.
diff --git a/tests/ui/self/phantomdata-in-coerce-and-dispatch-impls.rs b/tests/ui/self/phantomdata-in-coerce-and-dispatch-impls.rs
new file mode 100644
index 00000000000..9c7e33830f5
--- /dev/null
+++ b/tests/ui/self/phantomdata-in-coerce-and-dispatch-impls.rs
@@ -0,0 +1,25 @@
+//@ check-pass
+
+#![feature(coerce_unsized, dispatch_from_dyn, unsize)]
+
+use std::marker::Unsize;
+use std::ops::{CoerceUnsized, DispatchFromDyn};
+use std::marker::PhantomData;
+
+trait Mirror {
+    type Assoc;
+}
+impl<T> Mirror for T {
+    type Assoc = T;
+}
+
+struct W<T: 'static> {
+    t: &'static T,
+    f: <PhantomData<T> as Mirror>::Assoc,
+}
+
+impl<T, U> CoerceUnsized<W<U>> for W<T> where T: Unsize<U> {}
+
+impl<T, U> DispatchFromDyn<W<U>> for W<T> where T: Unsize<U> {}
+
+fn main() {}
diff --git a/tests/ui/traits/next-solver/known-type-outlives-has-constraints.rs b/tests/ui/traits/next-solver/known-type-outlives-has-constraints.rs
new file mode 100644
index 00000000000..55fea005ea1
--- /dev/null
+++ b/tests/ui/traits/next-solver/known-type-outlives-has-constraints.rs
@@ -0,0 +1,13 @@
+//@ compile-flags: -Znext-solver
+//@ check-pass
+
+trait Norm {
+    type Out;
+}
+impl<'a, T: 'a> Norm for &'a T {
+    type Out = T;
+}
+
+fn hello<'a, T: 'a>() where <&'a T as Norm>::Out: 'a {}
+
+fn main() {}
diff --git a/tests/ui/traits/trait-upcasting/impossible-method-modulo-binders-2.rs b/tests/ui/traits/trait-upcasting/impossible-method-modulo-binders-2.rs
new file mode 100644
index 00000000000..c03b5145aa7
--- /dev/null
+++ b/tests/ui/traits/trait-upcasting/impossible-method-modulo-binders-2.rs
@@ -0,0 +1,39 @@
+//@ build-pass
+//@ revisions: current next
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@[next] compile-flags: -Znext-solver
+// Regression test for #135462.
+#![allow(coherence_leak_check)]
+
+type A = fn(&'static ());
+type B = fn(&());
+
+trait Bound<P: WithAssoc>: From<GetAssoc<P>> {
+}
+impl Bound<B> for String {}
+
+trait Trt<T> {
+    fn __(&self, x: T) where T: Bound<A> {
+        T::from(());
+    }
+}
+
+impl<T, S> Trt<T> for S {}
+
+type GetAssoc<T> = <T as WithAssoc>::Ty;
+
+trait WithAssoc {
+    type Ty;
+}
+
+impl WithAssoc for B {
+    type Ty = String;
+}
+
+impl WithAssoc for A {
+    type Ty = ();
+}
+
+fn main() {
+    let x: &'static dyn Trt<String> = &();
+}
diff --git a/tests/ui/traits/trait-upcasting/impossible-method-modulo-binders.rs b/tests/ui/traits/trait-upcasting/impossible-method-modulo-binders.rs
new file mode 100644
index 00000000000..63ad1c0a060
--- /dev/null
+++ b/tests/ui/traits/trait-upcasting/impossible-method-modulo-binders.rs
@@ -0,0 +1,40 @@
+//@ build-pass
+//@ revisions: current next
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@[next] compile-flags: -Znext-solver
+
+trait Foo {}
+impl Foo for fn(&'static ()) {}
+
+trait Bar {
+    type Assoc: Default;
+}
+impl<T: Foo> Bar for T {
+    type Assoc = usize;
+}
+impl Bar for fn(&()) {
+    type Assoc = ();
+}
+
+fn needs_foo<T: Foo>() -> usize {
+    needs_bar::<T>()
+}
+
+fn needs_bar<T: Bar>() -> <T as Bar>::Assoc {
+    Default::default()
+}
+
+trait Evil<T> {
+    fn bad(&self)
+    where
+        T: Foo,
+    {
+        needs_foo::<T>();
+    }
+}
+
+impl Evil<fn(&())> for () {}
+
+fn main() {
+    let x: &dyn Evil<fn(&())> = &();
+}