about summary refs log tree commit diff
path: root/compiler/rustc_middle
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_middle')
-rw-r--r--compiler/rustc_middle/Cargo.toml2
-rw-r--r--compiler/rustc_middle/src/macros.rs4
-rw-r--r--compiler/rustc_middle/src/mir/basic_blocks.rs4
-rw-r--r--compiler/rustc_middle/src/mir/interpret/allocation.rs2
-rw-r--r--compiler/rustc_middle/src/mir/interpret/error.rs18
-rw-r--r--compiler/rustc_middle/src/mir/interpret/pointer.rs30
-rw-r--r--compiler/rustc_middle/src/mir/interpret/queries.rs9
-rw-r--r--compiler/rustc_middle/src/mir/interpret/value.rs8
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs4
-rw-r--r--compiler/rustc_middle/src/query/erase.rs6
-rw-r--r--compiler/rustc_middle/src/query/mod.rs21
-rw-r--r--compiler/rustc_middle/src/traits/mod.rs74
-rw-r--r--compiler/rustc_middle/src/traits/select.rs4
-rw-r--r--compiler/rustc_middle/src/traits/solve/inspect.rs6
-rw-r--r--compiler/rustc_middle/src/traits/solve/inspect/format.rs7
-rw-r--r--compiler/rustc_middle/src/traits/structural_impls.rs34
-rw-r--r--compiler/rustc_middle/src/ty/abstract_const.rs4
-rw-r--r--compiler/rustc_middle/src/ty/binding.rs2
-rw-r--r--compiler/rustc_middle/src/ty/codec.rs4
-rw-r--r--compiler/rustc_middle/src/ty/error.rs9
-rw-r--r--compiler/rustc_middle/src/ty/layout.rs290
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs85
-rw-r--r--compiler/rustc_middle/src/ty/structural_impls.rs2
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs5
24 files changed, 137 insertions, 497 deletions
diff --git a/compiler/rustc_middle/Cargo.toml b/compiler/rustc_middle/Cargo.toml
index 4c238308fe8..bb8e774cea3 100644
--- a/compiler/rustc_middle/Cargo.toml
+++ b/compiler/rustc_middle/Cargo.toml
@@ -13,7 +13,7 @@ gsgdt = "0.1.2"
 field-offset = "0.3.5"
 measureme = "10.0.0"
 polonius-engine = "0.13.0"
-rustc_apfloat = { path = "../rustc_apfloat" }
+rustc_apfloat = "0.2.0"
 rustc_arena = { path = "../rustc_arena" }
 rustc_ast = { path = "../rustc_ast" }
 rustc_attr = { path = "../rustc_attr" }
diff --git a/compiler/rustc_middle/src/macros.rs b/compiler/rustc_middle/src/macros.rs
index cd1c6c330bc..fca16d8e509 100644
--- a/compiler/rustc_middle/src/macros.rs
+++ b/compiler/rustc_middle/src/macros.rs
@@ -43,7 +43,7 @@ macro_rules! span_bug {
 
 #[macro_export]
 macro_rules! CloneLiftImpls {
-    ($($ty:ty,)+) => {
+    ($($ty:ty),+ $(,)?) => {
         $(
             impl<'tcx> $crate::ty::Lift<'tcx> for $ty {
                 type Lifted = Self;
@@ -59,7 +59,7 @@ macro_rules! CloneLiftImpls {
 /// allocated data** (i.e., don't need to be folded).
 #[macro_export]
 macro_rules! TrivialTypeTraversalImpls {
-    ($($ty:ty,)+) => {
+    ($($ty:ty),+ $(,)?) => {
         $(
             impl<'tcx> $crate::ty::fold::TypeFoldable<$crate::ty::TyCtxt<'tcx>> for $ty {
                 fn try_fold_with<F: $crate::ty::fold::FallibleTypeFolder<$crate::ty::TyCtxt<'tcx>>>(
diff --git a/compiler/rustc_middle/src/mir/basic_blocks.rs b/compiler/rustc_middle/src/mir/basic_blocks.rs
index 7722e7b47cf..0ad17e819c7 100644
--- a/compiler/rustc_middle/src/mir/basic_blocks.rs
+++ b/compiler/rustc_middle/src/mir/basic_blocks.rs
@@ -178,9 +178,7 @@ impl<'tcx> graph::WithPredecessors for BasicBlocks<'tcx> {
     }
 }
 
-TrivialTypeTraversalAndLiftImpls! {
-    Cache,
-}
+TrivialTypeTraversalAndLiftImpls! { Cache }
 
 impl<S: Encoder> Encodable<S> for Cache {
     #[inline]
diff --git a/compiler/rustc_middle/src/mir/interpret/allocation.rs b/compiler/rustc_middle/src/mir/interpret/allocation.rs
index b8030d9db13..c1cb2f2e497 100644
--- a/compiler/rustc_middle/src/mir/interpret/allocation.rs
+++ b/compiler/rustc_middle/src/mir/interpret/allocation.rs
@@ -571,7 +571,7 @@ impl<Prov: Provenance, Extra, Bytes: AllocBytes> Allocation<Prov, Extra, Bytes>
         assert!(self.mutability == Mutability::Mut);
 
         // `to_bits_or_ptr_internal` is the right method because we just want to store this data
-        // as-is into memory.
+        // as-is into memory. This also double-checks that `val.size()` matches `range.size`.
         let (bytes, provenance) = match val.to_bits_or_ptr_internal(range.size)? {
             Right(ptr) => {
                 let (provenance, offset) = ptr.into_parts();
diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs
index 1bcef17d73b..6161b16fc46 100644
--- a/compiler/rustc_middle/src/mir/interpret/error.rs
+++ b/compiler/rustc_middle/src/mir/interpret/error.rs
@@ -12,7 +12,8 @@ use rustc_errors::{
 use rustc_macros::HashStable;
 use rustc_session::CtfeBacktrace;
 use rustc_span::def_id::DefId;
-use rustc_target::abi::{call, Align, Size, WrappingRange};
+use rustc_target::abi::{call, Align, Size, VariantIdx, WrappingRange};
+
 use std::borrow::Cow;
 use std::{any::Any, backtrace::Backtrace, fmt};
 
@@ -66,9 +67,7 @@ impl Into<ErrorGuaranteed> for ReportedErrorInfo {
     }
 }
 
-TrivialTypeTraversalAndLiftImpls! {
-    ErrorHandled,
-}
+TrivialTypeTraversalAndLiftImpls! { ErrorHandled }
 
 pub type EvalToAllocationRawResult<'tcx> = Result<ConstAlloc<'tcx>, ErrorHandled>;
 pub type EvalToConstValueResult<'tcx> = Result<ConstValue<'tcx>, ErrorHandled>;
@@ -191,9 +190,8 @@ pub enum InvalidProgramInfo<'tcx> {
     FnAbiAdjustForForeignAbi(call::AdjustForForeignAbiError),
     /// SizeOf of unsized type was requested.
     SizeOfUnsizedType(Ty<'tcx>),
-    /// An unsized local was accessed without having been initialized.
-    /// This is not meaningful as we can't even have backing memory for such locals.
-    UninitUnsizedLocal,
+    /// We are runnning into a nonsense situation due to ConstProp violating our invariants.
+    ConstPropNonsense,
 }
 
 /// Details of why a pointer had to be in-bounds.
@@ -324,7 +322,9 @@ pub enum UndefinedBehaviorInfo<'a> {
     /// Data size is not equal to target size.
     ScalarSizeMismatch(ScalarSizeMismatch),
     /// A discriminant of an uninhabited enum variant is written.
-    UninhabitedEnumVariantWritten,
+    UninhabitedEnumVariantWritten(VariantIdx),
+    /// An uninhabited enum variant is projected.
+    UninhabitedEnumVariantRead(VariantIdx),
     /// Validation error.
     Validation(ValidationErrorInfo<'a>),
     // FIXME(fee1-dead) these should all be actual variants of the enum instead of dynamically
@@ -388,11 +388,13 @@ pub enum ValidationErrorKind<'tcx> {
     MutableRefInConst,
     NullFnPtr,
     NeverVal,
+    NullablePtrOutOfRange { range: WrappingRange, max_value: u128 },
     PtrOutOfRange { range: WrappingRange, max_value: u128 },
     OutOfRange { value: String, range: WrappingRange, max_value: u128 },
     UnsafeCell,
     UninhabitedVal { ty: Ty<'tcx> },
     InvalidEnumTag { value: String },
+    UninhabitedEnumTag,
     UninitEnumTag,
     UninitStr,
     Uninit { expected: ExpectedKind },
diff --git a/compiler/rustc_middle/src/mir/interpret/pointer.rs b/compiler/rustc_middle/src/mir/interpret/pointer.rs
index c8133bcc387..65d04919357 100644
--- a/compiler/rustc_middle/src/mir/interpret/pointer.rs
+++ b/compiler/rustc_middle/src/mir/interpret/pointer.rs
@@ -19,19 +19,33 @@ pub trait PointerArithmetic: HasDataLayout {
 
     #[inline(always)]
     fn max_size_of_val(&self) -> Size {
-        Size::from_bytes(self.data_layout().target_isize_max())
+        Size::from_bytes(self.target_isize_max())
+    }
+
+    #[inline]
+    fn target_usize_max(&self) -> u64 {
+        self.pointer_size().unsigned_int_max().try_into().unwrap()
+    }
+
+    #[inline]
+    fn target_isize_min(&self) -> i64 {
+        self.pointer_size().signed_int_min().try_into().unwrap()
+    }
+
+    #[inline]
+    fn target_isize_max(&self) -> i64 {
+        self.pointer_size().signed_int_max().try_into().unwrap()
     }
 
     #[inline]
     fn target_usize_to_isize(&self, val: u64) -> i64 {
-        let dl = self.data_layout();
         let val = val as i64;
         // Now wrap-around into the machine_isize range.
-        if val > dl.target_isize_max() {
+        if val > self.target_isize_max() {
             // This can only happen if the ptr size is < 64, so we know max_usize_plus_1 fits into
             // i64.
-            debug_assert!(dl.pointer_size.bits() < 64);
-            let max_usize_plus_1 = 1u128 << dl.pointer_size.bits();
+            debug_assert!(self.pointer_size().bits() < 64);
+            let max_usize_plus_1 = 1u128 << self.pointer_size().bits();
             val - i64::try_from(max_usize_plus_1).unwrap()
         } else {
             val
@@ -44,7 +58,7 @@ pub trait PointerArithmetic: HasDataLayout {
     #[inline]
     fn truncate_to_ptr(&self, (val, over): (u64, bool)) -> (u64, bool) {
         let val = u128::from(val);
-        let max_ptr_plus_1 = 1u128 << self.data_layout().pointer_size.bits();
+        let max_ptr_plus_1 = 1u128 << self.pointer_size().bits();
         (u64::try_from(val % max_ptr_plus_1).unwrap(), over || val >= max_ptr_plus_1)
     }
 
@@ -62,11 +76,11 @@ pub trait PointerArithmetic: HasDataLayout {
         let n = i.unsigned_abs();
         if i >= 0 {
             let (val, over) = self.overflowing_offset(val, n);
-            (val, over || i > self.data_layout().target_isize_max())
+            (val, over || i > self.target_isize_max())
         } else {
             let res = val.overflowing_sub(n);
             let (val, over) = self.truncate_to_ptr(res);
-            (val, over || i < self.data_layout().target_isize_min())
+            (val, over || i < self.target_isize_min())
         }
     }
 
diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs
index c9db0e7c11d..fc659ce18a4 100644
--- a/compiler/rustc_middle/src/mir/interpret/queries.rs
+++ b/compiler/rustc_middle/src/mir/interpret/queries.rs
@@ -139,7 +139,6 @@ impl<'tcx> TyCtxt<'tcx> {
         cid: GlobalId<'tcx>,
         span: Option<Span>,
     ) -> EvalToConstValueResult<'tcx> {
-        let param_env = param_env.with_const();
         // Const-eval shouldn't depend on lifetimes at all, so we can erase them, which should
         // improve caching of queries.
         let inputs = self.erase_regions(param_env.and(cid));
@@ -158,8 +157,6 @@ impl<'tcx> TyCtxt<'tcx> {
         cid: GlobalId<'tcx>,
         span: Option<Span>,
     ) -> EvalToValTreeResult<'tcx> {
-        let param_env = param_env.with_const();
-        debug!(?param_env);
         // Const-eval shouldn't depend on lifetimes at all, so we can erase them, which should
         // improve caching of queries.
         let inputs = self.erase_regions(param_env.and(cid));
@@ -204,7 +201,6 @@ impl<'tcx> TyCtxtAt<'tcx> {
         gid: GlobalId<'tcx>,
         param_env: ty::ParamEnv<'tcx>,
     ) -> Result<mir::ConstAllocation<'tcx>, ErrorHandled> {
-        let param_env = param_env.with_const();
         trace!("eval_to_allocation: Need to compute {:?}", gid);
         let raw_const = self.eval_to_allocation_raw(param_env.and(gid))?;
         Ok(self.global_alloc(raw_const.alloc_id).unwrap_memory())
@@ -224,8 +220,7 @@ impl<'tcx> TyCtxtEnsure<'tcx> {
         let args = GenericArgs::identity_for_item(self.tcx, def_id);
         let instance = ty::Instance::new(def_id, args);
         let cid = GlobalId { instance, promoted: None };
-        let param_env =
-            self.tcx.param_env(def_id).with_reveal_all_normalized(self.tcx).with_const();
+        let param_env = self.tcx.param_env(def_id).with_reveal_all_normalized(self.tcx);
         // Const-eval shouldn't depend on lifetimes at all, so we can erase them, which should
         // improve caching of queries.
         let inputs = self.tcx.erase_regions(param_env.and(cid));
@@ -238,7 +233,7 @@ impl<'tcx> TyCtxtEnsure<'tcx> {
         assert!(self.tcx.is_static(def_id));
         let instance = ty::Instance::mono(self.tcx, def_id);
         let gid = GlobalId { instance, promoted: None };
-        let param_env = ty::ParamEnv::reveal_all().with_const();
+        let param_env = ty::ParamEnv::reveal_all();
         trace!("eval_to_allocation: Need to compute {:?}", gid);
         self.eval_to_allocation_raw(param_env.and(gid))
     }
diff --git a/compiler/rustc_middle/src/mir/interpret/value.rs b/compiler/rustc_middle/src/mir/interpret/value.rs
index 0416411dfe1..47421d0f037 100644
--- a/compiler/rustc_middle/src/mir/interpret/value.rs
+++ b/compiler/rustc_middle/src/mir/interpret/value.rs
@@ -320,6 +320,14 @@ impl<Prov> Scalar<Prov> {
             }
         })
     }
+
+    #[inline]
+    pub fn size(self) -> Size {
+        match self {
+            Scalar::Int(int) => int.size(),
+            Scalar::Ptr(_ptr, sz) => Size::from_bytes(sz),
+        }
+    }
 }
 
 impl<'tcx, Prov: Provenance> Scalar<Prov> {
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index 97f53a59fd6..3a958548515 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -706,9 +706,7 @@ pub enum BindingForm<'tcx> {
     RefForGuard,
 }
 
-TrivialTypeTraversalAndLiftImpls! {
-    BindingForm<'tcx>,
-}
+TrivialTypeTraversalAndLiftImpls! { BindingForm<'tcx> }
 
 mod binding_form_impl {
     use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs
index 9bf02267005..2c481745d98 100644
--- a/compiler/rustc_middle/src/query/erase.rs
+++ b/compiler/rustc_middle/src/query/erase.rs
@@ -111,11 +111,6 @@ impl EraseType
     >()];
 }
 
-impl EraseType for Result<ty::layout::TyAndNaiveLayout<'_>, &ty::layout::LayoutError<'_>> {
-    type Result =
-        [u8; size_of::<Result<ty::layout::TyAndNaiveLayout<'_>, &ty::layout::LayoutError<'_>>>()];
-}
-
 impl EraseType for Result<ty::Const<'_>, mir::interpret::LitToConstError> {
     type Result = [u8; size_of::<Result<ty::Const<'static>, mir::interpret::LitToConstError>>()];
 }
@@ -296,7 +291,6 @@ trivial! {
     rustc_span::Symbol,
     rustc_span::symbol::Ident,
     rustc_target::spec::PanicStrategy,
-    rustc_target::abi::ReferenceNichePolicy,
     rustc_type_ir::Variance,
     u32,
     usize,
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index b5b00b7b640..fb796587352 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -1394,18 +1394,6 @@ rustc_queries! {
         desc { "computing layout of `{}`", key.value }
     }
 
-    /// Computes the naive layout approximation of a type. Note that this implicitly
-    /// executes in "reveal all" mode, and will normalize the input type.
-    ///
-    /// Unlike `layout_of`, this doesn't look past references (beyond the `Pointee::Metadata`
-    /// projection), and as such can be called on generic types like `Option<&T>`.
-    query naive_layout_of(
-        key: ty::ParamEnvAnd<'tcx, Ty<'tcx>>
-    ) -> Result<ty::layout::TyAndNaiveLayout<'tcx>, &'tcx ty::layout::LayoutError<'tcx>> {
-        depth_limit
-        desc { "computing layout (naive) of `{}`", key.value }
-    }
-
     /// Compute a `FnAbi` suitable for indirect calls, i.e. to `fn` pointers.
     ///
     /// NB: this doesn't handle virtual calls - those should use `fn_abi_of_instance`
@@ -1481,11 +1469,6 @@ rustc_queries! {
         desc { "getting a crate's configured panic-in-drop strategy" }
         separate_provide_extern
     }
-    query reference_niches_policy(_: CrateNum) -> abi::ReferenceNichePolicy {
-        fatal_cycle
-        desc { "getting a crate's policy for size and alignment niches of references" }
-        separate_provide_extern
-    }
     query is_no_builtins(_: CrateNum) -> bool {
         fatal_cycle
         desc { "getting whether a crate has `#![no_builtins]`" }
@@ -2081,9 +2064,9 @@ rustc_queries! {
         }
     }
 
-    query is_impossible_method(key: (DefId, DefId)) -> bool {
+    query is_impossible_associated_item(key: (DefId, DefId)) -> bool {
         desc { |tcx|
-            "checking if `{}` is impossible to call within `{}`",
+            "checking if `{}` is impossible to reference within `{}`",
             tcx.def_path_str(key.1),
             tcx.def_path_str(key.0),
         }
diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs
index b7ffed57a0b..a2b33bb2737 100644
--- a/compiler/rustc_middle/src/traits/mod.rs
+++ b/compiler/rustc_middle/src/traits/mod.rs
@@ -649,43 +649,31 @@ pub enum ImplSource<'tcx, N> {
     /// for some type parameter. The `Vec<N>` represents the
     /// obligations incurred from normalizing the where-clause (if
     /// any).
-    Param(Vec<N>, ty::BoundConstness),
+    Param(ty::BoundConstness, Vec<N>),
 
-    /// Virtual calls through an object.
-    Object(ImplSourceObjectData<N>),
-
-    /// Successful resolution for a builtin trait.
-    Builtin(Vec<N>),
-
-    /// ImplSource for trait upcasting coercion
-    TraitUpcasting(ImplSourceTraitUpcastingData<N>),
+    /// Successful resolution for a builtin impl.
+    Builtin(BuiltinImplSource, Vec<N>),
 }
 
 impl<'tcx, N> ImplSource<'tcx, N> {
     pub fn nested_obligations(self) -> Vec<N> {
         match self {
             ImplSource::UserDefined(i) => i.nested,
-            ImplSource::Param(n, _) | ImplSource::Builtin(n) => n,
-            ImplSource::Object(d) => d.nested,
-            ImplSource::TraitUpcasting(d) => d.nested,
+            ImplSource::Param(_, n) | ImplSource::Builtin(_, n) => n,
         }
     }
 
     pub fn borrow_nested_obligations(&self) -> &[N] {
         match self {
             ImplSource::UserDefined(i) => &i.nested,
-            ImplSource::Param(n, _) | ImplSource::Builtin(n) => &n,
-            ImplSource::Object(d) => &d.nested,
-            ImplSource::TraitUpcasting(d) => &d.nested,
+            ImplSource::Param(_, n) | ImplSource::Builtin(_, n) => &n,
         }
     }
 
     pub fn borrow_nested_obligations_mut(&mut self) -> &mut [N] {
         match self {
             ImplSource::UserDefined(i) => &mut i.nested,
-            ImplSource::Param(n, _) | ImplSource::Builtin(n) => n,
-            ImplSource::Object(d) => &mut d.nested,
-            ImplSource::TraitUpcasting(d) => &mut d.nested,
+            ImplSource::Param(_, n) | ImplSource::Builtin(_, n) => n,
         }
     }
 
@@ -699,17 +687,9 @@ impl<'tcx, N> ImplSource<'tcx, N> {
                 args: i.args,
                 nested: i.nested.into_iter().map(f).collect(),
             }),
-            ImplSource::Param(n, ct) => ImplSource::Param(n.into_iter().map(f).collect(), ct),
-            ImplSource::Builtin(n) => ImplSource::Builtin(n.into_iter().map(f).collect()),
-            ImplSource::Object(o) => ImplSource::Object(ImplSourceObjectData {
-                vtable_base: o.vtable_base,
-                nested: o.nested.into_iter().map(f).collect(),
-            }),
-            ImplSource::TraitUpcasting(d) => {
-                ImplSource::TraitUpcasting(ImplSourceTraitUpcastingData {
-                    vtable_vptr_slot: d.vtable_vptr_slot,
-                    nested: d.nested.into_iter().map(f).collect(),
-                })
+            ImplSource::Param(ct, n) => ImplSource::Param(ct, n.into_iter().map(f).collect()),
+            ImplSource::Builtin(source, n) => {
+                ImplSource::Builtin(source, n.into_iter().map(f).collect())
             }
         }
     }
@@ -733,29 +713,31 @@ pub struct ImplSourceUserDefinedData<'tcx, N> {
     pub nested: Vec<N>,
 }
 
-#[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, Lift)]
-#[derive(TypeFoldable, TypeVisitable)]
-pub struct ImplSourceTraitUpcastingData<N> {
+#[derive(Copy, Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, Debug)]
+pub enum BuiltinImplSource {
+    /// Some builtin impl we don't need to differentiate. This should be used
+    /// unless more specific information is necessary.
+    Misc,
+    /// A builtin impl for trait objects.
+    ///
+    /// The vtable is formed by concatenating together the method lists of
+    /// the base object trait and all supertraits, pointers to supertrait vtable will
+    /// be provided when necessary; this is the start of `upcast_trait_ref`'s methods
+    /// in that vtable.
+    Object { vtable_base: usize },
     /// The vtable is formed by concatenating together the method lists of
     /// the base object trait and all supertraits, pointers to supertrait vtable will
     /// be provided when necessary; this is the position of `upcast_trait_ref`'s vtable
     /// within that vtable.
-    pub vtable_vptr_slot: Option<usize>,
-
-    pub nested: Vec<N>,
+    TraitUpcasting { vtable_vptr_slot: Option<usize> },
+    /// Unsizing a tuple like `(A, B, ..., X)` to `(A, B, ..., Y)` if `X` unsizes to `Y`.
+    ///
+    /// This needs to be a separate variant as it is still unstable and we need to emit
+    /// a feature error when using it on stable.
+    TupleUnsizing,
 }
 
-#[derive(PartialEq, Eq, Clone, TyEncodable, TyDecodable, HashStable, Lift)]
-#[derive(TypeFoldable, TypeVisitable)]
-pub struct ImplSourceObjectData<N> {
-    /// The vtable is formed by concatenating together the method lists of
-    /// the base object trait and all supertraits, pointers to supertrait vtable will
-    /// be provided when necessary; this is the start of `upcast_trait_ref`'s methods
-    /// in that vtable.
-    pub vtable_base: usize,
-
-    pub nested: Vec<N>,
-}
+TrivialTypeTraversalAndLiftImpls! { BuiltinImplSource }
 
 #[derive(Clone, Debug, PartialEq, Eq, Hash, HashStable, PartialOrd, Ord)]
 pub enum ObjectSafetyViolation {
diff --git a/compiler/rustc_middle/src/traits/select.rs b/compiler/rustc_middle/src/traits/select.rs
index f2dda003b99..a90d58f5fc1 100644
--- a/compiler/rustc_middle/src/traits/select.rs
+++ b/compiler/rustc_middle/src/traits/select.rs
@@ -304,9 +304,7 @@ impl From<ErrorGuaranteed> for OverflowError {
     }
 }
 
-TrivialTypeTraversalAndLiftImpls! {
-    OverflowError,
-}
+TrivialTypeTraversalAndLiftImpls! { OverflowError }
 
 impl<'tcx> From<OverflowError> for SelectionError<'tcx> {
     fn from(overflow_error: OverflowError) -> SelectionError<'tcx> {
diff --git a/compiler/rustc_middle/src/traits/solve/inspect.rs b/compiler/rustc_middle/src/traits/solve/inspect.rs
index 8698cf86022..e793f481995 100644
--- a/compiler/rustc_middle/src/traits/solve/inspect.rs
+++ b/compiler/rustc_middle/src/traits/solve/inspect.rs
@@ -73,8 +73,12 @@ pub struct GoalCandidate<'tcx> {
 pub enum CandidateKind<'tcx> {
     /// Probe entered when normalizing the self ty during candidate assembly
     NormalizedSelfTyAssembly,
+    DynUpcastingAssembly,
     /// A normal candidate for proving a goal
-    Candidate { name: String, result: QueryResult<'tcx> },
+    Candidate {
+        name: String,
+        result: QueryResult<'tcx>,
+    },
 }
 impl Debug for GoalCandidate<'_> {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
diff --git a/compiler/rustc_middle/src/traits/solve/inspect/format.rs b/compiler/rustc_middle/src/traits/solve/inspect/format.rs
index f19f1189e44..39f84279259 100644
--- a/compiler/rustc_middle/src/traits/solve/inspect/format.rs
+++ b/compiler/rustc_middle/src/traits/solve/inspect/format.rs
@@ -15,11 +15,11 @@ struct Indentor<'a, 'b> {
 
 impl Write for Indentor<'_, '_> {
     fn write_str(&mut self, s: &str) -> std::fmt::Result {
-        for line in s.split_inclusive("\n") {
+        for line in s.split_inclusive('\n') {
             if self.on_newline {
                 self.f.write_str("    ")?;
             }
-            self.on_newline = line.ends_with("\n");
+            self.on_newline = line.ends_with('\n');
             self.f.write_str(line)?;
         }
 
@@ -100,6 +100,9 @@ impl<'a, 'b> ProofTreeFormatter<'a, 'b> {
             CandidateKind::NormalizedSelfTyAssembly => {
                 writeln!(self.f, "NORMALIZING SELF TY FOR ASSEMBLY:")
             }
+            CandidateKind::DynUpcastingAssembly => {
+                writeln!(self.f, "ASSEMBLING CANDIDATES FOR DYN UPCASTING:")
+            }
             CandidateKind::Candidate { name, result } => {
                 writeln!(self.f, "CANDIDATE {}: {:?}", name, result)
             }
diff --git a/compiler/rustc_middle/src/traits/structural_impls.rs b/compiler/rustc_middle/src/traits/structural_impls.rs
index e2cd118500b..530d1ec5d35 100644
--- a/compiler/rustc_middle/src/traits/structural_impls.rs
+++ b/compiler/rustc_middle/src/traits/structural_impls.rs
@@ -6,18 +6,16 @@ use std::fmt;
 
 impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSource<'tcx, N> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        match *self {
-            super::ImplSource::UserDefined(ref v) => write!(f, "{:?}", v),
+        match self {
+            super::ImplSource::UserDefined(v) => write!(f, "{:?}", v),
 
-            super::ImplSource::Builtin(ref d) => write!(f, "{:?}", d),
-
-            super::ImplSource::Object(ref d) => write!(f, "{:?}", d),
+            super::ImplSource::Builtin(source, d) => {
+                write!(f, "Builtin({source:?}, {d:?})")
+            }
 
-            super::ImplSource::Param(ref n, ct) => {
+            super::ImplSource::Param(ct, n) => {
                 write!(f, "ImplSourceParamData({:?}, {:?})", n, ct)
             }
-
-            super::ImplSource::TraitUpcasting(ref d) => write!(f, "{:?}", d),
         }
     }
 }
@@ -31,23 +29,3 @@ impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSourceUserDefinedData<'tcx,
         )
     }
 }
-
-impl<N: fmt::Debug> fmt::Debug for traits::ImplSourceTraitUpcastingData<N> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(
-            f,
-            "ImplSourceTraitUpcastingData(vtable_vptr_slot={:?}, nested={:?})",
-            self.vtable_vptr_slot, self.nested
-        )
-    }
-}
-
-impl<N: fmt::Debug> fmt::Debug for traits::ImplSourceObjectData<N> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(
-            f,
-            "ImplSourceObjectData(vtable_base={}, nested={:?})",
-            self.vtable_base, self.nested
-        )
-    }
-}
diff --git a/compiler/rustc_middle/src/ty/abstract_const.rs b/compiler/rustc_middle/src/ty/abstract_const.rs
index 0364a620810..cdd8351499b 100644
--- a/compiler/rustc_middle/src/ty/abstract_const.rs
+++ b/compiler/rustc_middle/src/ty/abstract_const.rs
@@ -27,9 +27,7 @@ impl From<ErrorGuaranteed> for NotConstEvaluatable {
     }
 }
 
-TrivialTypeTraversalAndLiftImpls! {
-    NotConstEvaluatable,
-}
+TrivialTypeTraversalAndLiftImpls! { NotConstEvaluatable }
 
 pub type BoundAbstractConst<'tcx> = Result<Option<EarlyBinder<ty::Const<'tcx>>>, ErrorGuaranteed>;
 
diff --git a/compiler/rustc_middle/src/ty/binding.rs b/compiler/rustc_middle/src/ty/binding.rs
index a5b05a4f9b5..2fec8ac9095 100644
--- a/compiler/rustc_middle/src/ty/binding.rs
+++ b/compiler/rustc_middle/src/ty/binding.rs
@@ -6,7 +6,7 @@ pub enum BindingMode {
     BindByValue(Mutability),
 }
 
-TrivialTypeTraversalAndLiftImpls! { BindingMode, }
+TrivialTypeTraversalAndLiftImpls! { BindingMode }
 
 impl BindingMode {
     pub fn convert(BindingAnnotation(by_ref, mutbl): BindingAnnotation) -> BindingMode {
diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs
index b4f4f9bef8e..7c05deae90a 100644
--- a/compiler/rustc_middle/src/ty/codec.rs
+++ b/compiler/rustc_middle/src/ty/codec.rs
@@ -168,7 +168,6 @@ impl<'tcx, E: TyEncoder<I = TyCtxt<'tcx>>> Encodable<E> for ty::ParamEnv<'tcx> {
     fn encode(&self, e: &mut E) {
         self.caller_bounds().encode(e);
         self.reveal().encode(e);
-        self.constness().encode(e);
     }
 }
 
@@ -306,8 +305,7 @@ impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for ty::ParamEnv<'tcx> {
     fn decode(d: &mut D) -> Self {
         let caller_bounds = Decodable::decode(d);
         let reveal = Decodable::decode(d);
-        let constness = Decodable::decode(d);
-        ty::ParamEnv::new(caller_bounds, reveal, constness)
+        ty::ParamEnv::new(caller_bounds, reveal)
     }
 }
 
diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs
index c794c3faded..3fdbaf5e947 100644
--- a/compiler/rustc_middle/src/ty/error.rs
+++ b/compiler/rustc_middle/src/ty/error.rs
@@ -339,12 +339,17 @@ impl<'tcx> TyCtxt<'tcx> {
     }
 
     pub fn short_ty_string(self, ty: Ty<'tcx>) -> (String, Option<PathBuf>) {
-        let width = self.sess.diagnostic_width();
-        let length_limit = width.saturating_sub(30);
         let regular = FmtPrinter::new(self, hir::def::Namespace::TypeNS)
             .pretty_print_type(ty)
             .expect("could not write to `String`")
             .into_buffer();
+
+        if !self.sess.opts.unstable_opts.write_long_types_to_disk {
+            return (regular, None);
+        }
+
+        let width = self.sess.diagnostic_width();
+        let length_limit = width.saturating_sub(30);
         if regular.len() <= width {
             return (regular, None);
         }
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs
index 26137e86fa0..81e7dc3728a 100644
--- a/compiler/rustc_middle/src/ty/layout.rs
+++ b/compiler/rustc_middle/src/ty/layout.rs
@@ -313,16 +313,7 @@ impl<'tcx> SizeSkeleton<'tcx> {
     ) -> Result<SizeSkeleton<'tcx>, &'tcx LayoutError<'tcx>> {
         debug_assert!(!ty.has_non_region_infer());
 
-        // First, try computing an exact naive layout (this covers simple types with generic
-        // references, where a full static layout would fail).
-        if let Ok(layout) = tcx.naive_layout_of(param_env.and(ty)) {
-            if layout.exact {
-                return Ok(SizeSkeleton::Known(layout.size));
-            }
-        }
-
-        // Second, try computing a full static layout (this covers cases when the naive layout
-        // wasn't smart enough, but cannot deal with generic references).
+        // First try computing a static layout.
         let err = match tcx.layout_of(param_env.and(ty)) {
             Ok(layout) => {
                 return Ok(SizeSkeleton::Known(layout.size));
@@ -336,7 +327,6 @@ impl<'tcx> SizeSkeleton<'tcx> {
             ) => return Err(e),
         };
 
-        // Third, fall back to ad-hoc cases.
         match *ty.kind() {
             ty::Ref(_, pointee, _) | ty::RawPtr(ty::TypeAndMut { ty: pointee, .. }) => {
                 let non_zero = !ty.is_unsafe_ptr();
@@ -631,219 +621,6 @@ impl<T, E> MaybeResult<T> for Result<T, E> {
 
 pub type TyAndLayout<'tcx> = rustc_target::abi::TyAndLayout<'tcx, Ty<'tcx>>;
 
-#[derive(Copy, Clone, Debug, HashStable)]
-pub struct TyAndNaiveLayout<'tcx> {
-    pub ty: Ty<'tcx>,
-    pub layout: NaiveLayout,
-}
-
-impl std::ops::Deref for TyAndNaiveLayout<'_> {
-    type Target = NaiveLayout;
-    fn deref(&self) -> &Self::Target {
-        &self.layout
-    }
-}
-
-impl std::ops::DerefMut for TyAndNaiveLayout<'_> {
-    fn deref_mut(&mut self) -> &mut Self::Target {
-        &mut self.layout
-    }
-}
-
-/// Extremely simplified approximation of a type's layout returned by the
-/// `naive_layout_of` query.
-#[derive(Copy, Clone, Debug, HashStable)]
-pub struct NaiveLayout {
-    pub abi: NaiveAbi,
-    /// Niche information, required for tracking non-null enum optimizations.
-    pub niches: NaiveNiches,
-    /// An underestimate of the layout's size.
-    pub size: Size,
-    /// An underestimate of the layout's required alignment.
-    pub align: Align,
-    /// If `true`, `size` and `align` must be exact values.
-    pub exact: bool,
-}
-
-#[derive(Copy, Clone, Debug, Eq, PartialEq, HashStable)]
-pub enum NaiveNiches {
-    None,
-    Some,
-    Maybe,
-}
-
-#[derive(Copy, Clone, Debug, Eq, PartialEq, HashStable)]
-pub enum NaiveAbi {
-    /// A scalar layout, always implies `exact` and a non-zero `size`.
-    Scalar(Primitive),
-    /// An uninhabited layout. (needed to properly track `Scalar` and niches)
-    Uninhabited,
-    /// An unsized aggregate. (needed to properly track `Scalar` and niches)
-    Unsized,
-    /// Any other sized layout.
-    Sized,
-}
-
-impl NaiveAbi {
-    #[inline]
-    pub fn as_aggregate(self) -> Self {
-        match self {
-            NaiveAbi::Scalar(_) => NaiveAbi::Sized,
-            _ => self,
-        }
-    }
-}
-
-impl NaiveLayout {
-    /// The layout of an empty aggregate, e.g. `()`.
-    pub const EMPTY: Self = Self {
-        size: Size::ZERO,
-        align: Align::ONE,
-        exact: true,
-        abi: NaiveAbi::Sized,
-        niches: NaiveNiches::None,
-    };
-
-    /// Returns whether `self` is a valid approximation of the given full `layout`.
-    ///
-    /// This should always return `true` when both layouts are computed from the same type.
-    pub fn is_refined_by(&self, layout: Layout<'_>) -> bool {
-        if self.size > layout.size() || self.align > layout.align().abi {
-            return false;
-        }
-
-        if let NaiveAbi::Scalar(prim) = self.abi {
-            if !self.exact
-                || self.size == Size::ZERO
-                || !matches!(layout.abi(), Abi::Scalar(s) if s.primitive() == prim)
-            {
-                return false;
-            }
-        }
-
-        match (self.niches, layout.largest_niche()) {
-            (NaiveNiches::None, Some(_)) => return false,
-            (NaiveNiches::Some, None) => return false,
-            _ => (),
-        }
-
-        !self.exact || (self.size, self.align) == (layout.size(), layout.align().abi)
-    }
-
-    /// Returns if this layout is known to be pointer-like (`None` if uncertain)
-    ///
-    /// See the corresponding `Layout::is_pointer_like` method.
-    pub fn is_pointer_like(&self, dl: &TargetDataLayout) -> Option<bool> {
-        match self.abi {
-            NaiveAbi::Scalar(_) => {
-                assert!(self.exact);
-                Some(self.size == dl.pointer_size && self.align == dl.pointer_align.abi)
-            }
-            NaiveAbi::Uninhabited | NaiveAbi::Unsized => Some(false),
-            NaiveAbi::Sized if self.exact => Some(false),
-            NaiveAbi::Sized => None,
-        }
-    }
-
-    /// Artificially lowers the alignment of this layout.
-    #[must_use]
-    #[inline]
-    pub fn packed(mut self, align: Align) -> Self {
-        if self.align > align {
-            self.align = align;
-            self.abi = self.abi.as_aggregate();
-        }
-        self
-    }
-
-    /// Artificially raises the alignment of this layout.
-    #[must_use]
-    #[inline]
-    pub fn align_to(mut self, align: Align) -> Self {
-        if align > self.align {
-            self.align = align;
-            self.abi = self.abi.as_aggregate();
-        }
-        self
-    }
-
-    /// Artificially makes this layout inexact.
-    #[must_use]
-    #[inline]
-    pub fn inexact(mut self) -> Self {
-        self.abi = self.abi.as_aggregate();
-        self.exact = false;
-        self
-    }
-
-    /// Pads this layout so that its size is a multiple of `align`.
-    #[must_use]
-    #[inline]
-    pub fn pad_to_align(mut self, align: Align) -> Self {
-        let new_size = self.size.align_to(align);
-        if new_size > self.size {
-            self.abi = self.abi.as_aggregate();
-            self.size = new_size;
-        }
-        self
-    }
-
-    /// Returns the layout of `self` immediately followed by `other`, without any
-    /// padding between them, as in a packed `struct` or tuple.
-    #[must_use]
-    #[inline]
-    pub fn concat(&self, other: &Self, dl: &TargetDataLayout) -> Option<Self> {
-        use NaiveAbi::*;
-
-        let size = self.size.checked_add(other.size, dl)?;
-        let align = cmp::max(self.align, other.align);
-        let exact = self.exact && other.exact;
-        let abi = match (self.abi, other.abi) {
-            // The uninhabited and unsized ABIs override everything.
-            (Uninhabited, _) | (_, Uninhabited) => Uninhabited,
-            (Unsized, _) | (_, Unsized) => Unsized,
-            // A scalar struct must have a single non ZST-field.
-            (_, s @ Scalar(_)) if exact && self.size == Size::ZERO => s,
-            (s @ Scalar(_), _) if exact && other.size == Size::ZERO => s,
-            // Default case.
-            (_, _) => Sized,
-        };
-        let niches = match (self.niches, other.niches) {
-            (NaiveNiches::Some, _) | (_, NaiveNiches::Some) => NaiveNiches::Some,
-            (NaiveNiches::None, NaiveNiches::None) => NaiveNiches::None,
-            (_, _) => NaiveNiches::Maybe,
-        };
-        Some(Self { abi, size, align, exact, niches })
-    }
-
-    /// Returns the layout of `self` superposed with `other`, as in an `enum`
-    /// or an `union`.
-    ///
-    /// Note: This always ignore niche information from `other`.
-    #[must_use]
-    #[inline]
-    pub fn union(&self, other: &Self) -> Self {
-        use NaiveAbi::*;
-
-        let size = cmp::max(self.size, other.size);
-        let align = cmp::max(self.align, other.align);
-        let exact = self.exact && other.exact;
-        let abi = match (self.abi, other.abi) {
-            // The unsized ABI overrides everything.
-            (Unsized, _) | (_, Unsized) => Unsized,
-            // A scalar union must have a single non ZST-field...
-            (_, s @ Scalar(_)) if exact && self.size == Size::ZERO => s,
-            (s @ Scalar(_), _) if exact && other.size == Size::ZERO => s,
-            // ...or identical scalar fields.
-            (Scalar(s1), Scalar(s2)) if s1 == s2 => Scalar(s1),
-            // Default cases.
-            (Uninhabited, Uninhabited) => Uninhabited,
-            (_, _) => Sized,
-        };
-        Self { abi, size, align, exact, niches: self.niches }
-    }
-}
-
 /// Trait for contexts that want to be able to compute layouts of types.
 /// This automatically gives access to `LayoutOf`, through a blanket `impl`.
 pub trait LayoutOfHelpers<'tcx>: HasDataLayout + HasTyCtxt<'tcx> + HasParamEnv<'tcx> {
@@ -896,19 +673,6 @@ pub trait LayoutOf<'tcx>: LayoutOfHelpers<'tcx> {
                 .map_err(|err| self.handle_layout_err(*err, span, ty)),
         )
     }
-
-    /// Computes the naive layout estimate of a type. Note that this implicitly
-    /// executes in "reveal all" mode, and will normalize the input type.
-    ///
-    /// Unlike `layout_of`, this doesn't look past references (beyond the `Pointee::Metadata`
-    /// projection), and as such can be called on generic types like `Option<&T>`.
-    #[inline]
-    fn naive_layout_of(
-        &self,
-        ty: Ty<'tcx>,
-    ) -> Result<TyAndNaiveLayout<'tcx>, &'tcx LayoutError<'tcx>> {
-        self.tcx().naive_layout_of(self.param_env().and(ty))
-    }
 }
 
 impl<'tcx, C: LayoutOfHelpers<'tcx>> LayoutOf<'tcx> for C {}
@@ -977,9 +741,9 @@ where
 
                 let fields = match this.ty.kind() {
                     ty::Adt(def, _) if def.variants().is_empty() =>
-                        bug!("for_variant called on zero-variant enum"),
+                        bug!("for_variant called on zero-variant enum {}", this.ty),
                     ty::Adt(def, _) => def.variant(variant_index).fields.len(),
-                    _ => bug!(),
+                    _ => bug!("`ty_and_layout_for_variant` on unexpected type {}", this.ty),
                 };
                 tcx.mk_layout(LayoutS {
                     variants: Variants::Single { index: variant_index },
@@ -1205,9 +969,6 @@ where
         this: TyAndLayout<'tcx>,
         cx: &C,
         offset: Size,
-        // If true, assume that pointers are either null or valid (according to their type),
-        // enabling extra optimizations.
-        mut assume_valid_ptr: bool,
     ) -> Option<PointeeInfo> {
         let tcx = cx.tcx();
         let param_env = cx.param_env();
@@ -1230,19 +991,19 @@ where
                 // Freeze/Unpin queries, and can save time in the codegen backend (noalias
                 // attributes in LLVM have compile-time cost even in unoptimized builds).
                 let optimize = tcx.sess.opts.optimize != OptLevel::No;
-                let safe = match (assume_valid_ptr, mt) {
-                    (true, hir::Mutability::Not) => Some(PointerKind::SharedRef {
+                let kind = match mt {
+                    hir::Mutability::Not => PointerKind::SharedRef {
                         frozen: optimize && ty.is_freeze(tcx, cx.param_env()),
-                    }),
-                    (true, hir::Mutability::Mut) => Some(PointerKind::MutableRef {
+                    },
+                    hir::Mutability::Mut => PointerKind::MutableRef {
                         unpin: optimize && ty.is_unpin(tcx, cx.param_env()),
-                    }),
-                    (false, _) => None,
+                    },
                 };
+
                 tcx.layout_of(param_env.and(ty)).ok().map(|layout| PointeeInfo {
                     size: layout.size,
                     align: layout.align.abi,
-                    safe,
+                    safe: Some(kind),
                 })
             }
 
@@ -1251,21 +1012,19 @@ where
                     // Within the discriminant field, only the niche itself is
                     // always initialized, so we only check for a pointer at its
                     // offset.
+                    //
+                    // If the niche is a pointer, it's either valid (according
+                    // to its type), or null (which the niche field's scalar
+                    // validity range encodes). This allows using
+                    // `dereferenceable_or_null` for e.g., `Option<&T>`, and
+                    // this will continue to work as long as we don't start
+                    // using more niches than just null (e.g., the first page of
+                    // the address space, or unaligned pointers).
                     Variants::Multiple {
-                        tag_encoding:
-                            TagEncoding::Niche {
-                                untagged_variant,
-                                niche_variants: ref variants,
-                                niche_start,
-                            },
+                        tag_encoding: TagEncoding::Niche { untagged_variant, .. },
                         tag_field,
                         ..
                     } if this.fields.offset(tag_field) == offset => {
-                        // We can only continue assuming pointer validity if the only possible
-                        // discriminant value is null. The null special-case is permitted by LLVM's
-                        // `dereferenceable_or_null`, and allow types like `Option<&T>` to benefit
-                        // from optimizations.
-                        assume_valid_ptr &= niche_start == 0 && variants.start() == variants.end();
                         Some(this.for_variant(cx, untagged_variant))
                     }
                     _ => Some(this),
@@ -1291,12 +1050,9 @@ where
                             result = field.to_result().ok().and_then(|field| {
                                 if ptr_end <= field_start + field.size {
                                     // We found the right field, look inside it.
-                                    Self::ty_and_layout_pointee_info_at(
-                                        field,
-                                        cx,
-                                        offset - field_start,
-                                        assume_valid_ptr,
-                                    )
+                                    let field_info =
+                                        field.pointee_info_at(cx, offset - field_start);
+                                    field_info
                                 } else {
                                     None
                                 }
@@ -1311,7 +1067,7 @@ where
                 // FIXME(eddyb) This should be for `ptr::Unique<T>`, not `Box<T>`.
                 if let Some(ref mut pointee) = result {
                     if let ty::Adt(def, _) = this.ty.kind() {
-                        if assume_valid_ptr && def.is_box() && offset.bytes() == 0 {
+                        if def.is_box() && offset.bytes() == 0 {
                             let optimize = tcx.sess.opts.optimize != OptLevel::No;
                             pointee.safe = Some(PointerKind::Box {
                                 unpin: optimize && this.ty.boxed_ty().is_unpin(tcx, cx.param_env()),
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 0411890ab51..f9c0fbb23c3 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -867,20 +867,6 @@ pub struct TraitPredicate<'tcx> {
 pub type PolyTraitPredicate<'tcx> = ty::Binder<'tcx, TraitPredicate<'tcx>>;
 
 impl<'tcx> TraitPredicate<'tcx> {
-    pub fn remap_constness(&mut self, param_env: &mut ParamEnv<'tcx>) {
-        *param_env = param_env.with_constness(self.constness.and(param_env.constness()))
-    }
-
-    /// Remap the constness of this predicate before emitting it for diagnostics.
-    pub fn remap_constness_diag(&mut self, param_env: ParamEnv<'tcx>) {
-        // this is different to `remap_constness` that callees want to print this predicate
-        // in case of selection errors. `T: ~const Drop` bounds cannot end up here when the
-        // param_env is not const because it is always satisfied in non-const contexts.
-        if let hir::Constness::NotConst = param_env.constness() {
-            self.constness = ty::BoundConstness::NotConst;
-        }
-    }
-
     pub fn with_self_ty(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> Self {
         Self { trait_ref: self.trait_ref.with_self_ty(tcx, self_ty), ..self }
     }
@@ -922,14 +908,6 @@ impl<'tcx> PolyTraitPredicate<'tcx> {
         self.map_bound(|trait_ref| trait_ref.self_ty())
     }
 
-    /// Remap the constness of this predicate before emitting it for diagnostics.
-    pub fn remap_constness_diag(&mut self, param_env: ParamEnv<'tcx>) {
-        *self = self.map_bound(|mut p| {
-            p.remap_constness_diag(param_env);
-            p
-        });
-    }
-
     #[inline]
     pub fn is_const_if_const(self) -> bool {
         self.skip_binder().is_const_if_const()
@@ -1700,15 +1678,12 @@ pub struct ParamEnv<'tcx> {
 #[derive(Copy, Clone)]
 struct ParamTag {
     reveal: traits::Reveal,
-    constness: hir::Constness,
 }
 
 impl_tag! {
     impl Tag for ParamTag;
-    ParamTag { reveal: traits::Reveal::UserFacing, constness: hir::Constness::NotConst },
-    ParamTag { reveal: traits::Reveal::All,        constness: hir::Constness::NotConst },
-    ParamTag { reveal: traits::Reveal::UserFacing, constness: hir::Constness::Const    },
-    ParamTag { reveal: traits::Reveal::All,        constness: hir::Constness::Const    },
+    ParamTag { reveal: traits::Reveal::UserFacing },
+    ParamTag { reveal: traits::Reveal::All },
 }
 
 impl<'tcx> fmt::Debug for ParamEnv<'tcx> {
@@ -1716,7 +1691,6 @@ impl<'tcx> fmt::Debug for ParamEnv<'tcx> {
         f.debug_struct("ParamEnv")
             .field("caller_bounds", &self.caller_bounds())
             .field("reveal", &self.reveal())
-            .field("constness", &self.constness())
             .finish()
     }
 }
@@ -1725,7 +1699,6 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for ParamEnv<'tcx> {
     fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
         self.caller_bounds().hash_stable(hcx, hasher);
         self.reveal().hash_stable(hcx, hasher);
-        self.constness().hash_stable(hcx, hasher);
     }
 }
 
@@ -1737,7 +1710,6 @@ impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for ParamEnv<'tcx> {
         Ok(ParamEnv::new(
             self.caller_bounds().try_fold_with(folder)?,
             self.reveal().try_fold_with(folder)?,
-            self.constness(),
         ))
     }
 }
@@ -1756,7 +1728,7 @@ impl<'tcx> ParamEnv<'tcx> {
     /// type-checking.
     #[inline]
     pub fn empty() -> Self {
-        Self::new(List::empty(), Reveal::UserFacing, hir::Constness::NotConst)
+        Self::new(List::empty(), Reveal::UserFacing)
     }
 
     #[inline]
@@ -1769,16 +1741,6 @@ impl<'tcx> ParamEnv<'tcx> {
         self.packed.tag().reveal
     }
 
-    #[inline]
-    pub fn constness(self) -> hir::Constness {
-        self.packed.tag().constness
-    }
-
-    #[inline]
-    pub fn is_const(self) -> bool {
-        self.packed.tag().constness == hir::Constness::Const
-    }
-
     /// Construct a trait environment with no where-clauses in scope
     /// where the values of all `impl Trait` and other hidden types
     /// are revealed. This is suitable for monomorphized, post-typeck
@@ -1788,17 +1750,13 @@ impl<'tcx> ParamEnv<'tcx> {
     /// or invoke `param_env.with_reveal_all()`.
     #[inline]
     pub fn reveal_all() -> Self {
-        Self::new(List::empty(), Reveal::All, hir::Constness::NotConst)
+        Self::new(List::empty(), Reveal::All)
     }
 
     /// Construct a trait environment with the given set of predicates.
     #[inline]
-    pub fn new(
-        caller_bounds: &'tcx List<Clause<'tcx>>,
-        reveal: Reveal,
-        constness: hir::Constness,
-    ) -> Self {
-        ty::ParamEnv { packed: CopyTaggedPtr::new(caller_bounds, ParamTag { reveal, constness }) }
+    pub fn new(caller_bounds: &'tcx List<Clause<'tcx>>, reveal: Reveal) -> Self {
+        ty::ParamEnv { packed: CopyTaggedPtr::new(caller_bounds, ParamTag { reveal }) }
     }
 
     pub fn with_user_facing(mut self) -> Self {
@@ -1806,29 +1764,6 @@ impl<'tcx> ParamEnv<'tcx> {
         self
     }
 
-    #[inline]
-    pub fn with_constness(mut self, constness: hir::Constness) -> Self {
-        self.packed.set_tag(ParamTag { constness, ..self.packed.tag() });
-        self
-    }
-
-    #[inline]
-    pub fn with_const(mut self) -> Self {
-        self.packed.set_tag(ParamTag { constness: hir::Constness::Const, ..self.packed.tag() });
-        self
-    }
-
-    #[inline]
-    pub fn without_const(mut self) -> Self {
-        self.packed.set_tag(ParamTag { constness: hir::Constness::NotConst, ..self.packed.tag() });
-        self
-    }
-
-    #[inline]
-    pub fn remap_constness_with(&mut self, mut constness: ty::BoundConstness) {
-        *self = self.with_constness(constness.and(self.constness()))
-    }
-
     /// Returns a new parameter environment with the same clauses, but
     /// which "reveals" the true results of projections in all cases
     /// (even for associated types that are specializable). This is
@@ -1843,17 +1778,13 @@ impl<'tcx> ParamEnv<'tcx> {
             return self;
         }
 
-        ParamEnv::new(
-            tcx.reveal_opaque_types_in_bounds(self.caller_bounds()),
-            Reveal::All,
-            self.constness(),
-        )
+        ParamEnv::new(tcx.reveal_opaque_types_in_bounds(self.caller_bounds()), Reveal::All)
     }
 
     /// Returns this same environment but with no caller bounds.
     #[inline]
     pub fn without_caller_bounds(self) -> Self {
-        Self::new(List::empty(), self.reveal(), self.constness())
+        Self::new(List::empty(), self.reveal())
     }
 
     /// Creates a suitable environment in which to perform trait
diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs
index 9d380a58d9f..50bf9afa531 100644
--- a/compiler/rustc_middle/src/ty/structural_impls.rs
+++ b/compiler/rustc_middle/src/ty/structural_impls.rs
@@ -602,7 +602,7 @@ impl<'a, 'tcx> Lift<'tcx> for ty::ParamEnv<'a> {
     type Lifted = ty::ParamEnv<'tcx>;
     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
         tcx.lift(self.caller_bounds())
-            .map(|caller_bounds| ty::ParamEnv::new(caller_bounds, self.reveal(), self.constness()))
+            .map(|caller_bounds| ty::ParamEnv::new(caller_bounds, self.reveal()))
     }
 }
 
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index f9c1ca9a8b1..3e023ccdead 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -2670,11 +2670,6 @@ impl<'tcx> Ty<'tcx> {
         variant_index: VariantIdx,
     ) -> Option<Discr<'tcx>> {
         match self.kind() {
-            TyKind::Adt(adt, _) if adt.variants().is_empty() => {
-                // This can actually happen during CTFE, see
-                // https://github.com/rust-lang/rust/issues/89765.
-                None
-            }
             TyKind::Adt(adt, _) if adt.is_enum() => {
                 Some(adt.discriminant_for_variant(tcx, variant_index))
             }