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/messages.ftl4
-rw-r--r--compiler/rustc_middle/src/mir/coverage.rs11
-rw-r--r--compiler/rustc_middle/src/mir/interpret/mod.rs86
-rw-r--r--compiler/rustc_middle/src/mir/pretty.rs4
-rw-r--r--compiler/rustc_middle/src/mir/query.rs5
-rw-r--r--compiler/rustc_middle/src/query/mod.rs23
-rw-r--r--compiler/rustc_middle/src/query/plumbing.rs2
-rw-r--r--compiler/rustc_middle/src/traits/mod.rs5
-rw-r--r--compiler/rustc_middle/src/ty/assoc.rs12
-rw-r--r--compiler/rustc_middle/src/ty/closure.rs17
-rw-r--r--compiler/rustc_middle/src/ty/context.rs9
-rw-r--r--compiler/rustc_middle/src/ty/fold.rs2
-rw-r--r--compiler/rustc_middle/src/ty/generics.rs4
-rw-r--r--compiler/rustc_middle/src/ty/instance.rs4
-rw-r--r--compiler/rustc_middle/src/ty/intrinsic.rs2
-rw-r--r--compiler/rustc_middle/src/ty/layout.rs38
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs23
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs19
-rw-r--r--compiler/rustc_middle/src/ty/region.rs28
-rw-r--r--compiler/rustc_middle/src/ty/structural_impls.rs6
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs1
-rw-r--r--compiler/rustc_middle/src/ty/util.rs15
-rw-r--r--compiler/rustc_middle/src/util/call_kind.rs4
23 files changed, 224 insertions, 100 deletions
diff --git a/compiler/rustc_middle/messages.ftl b/compiler/rustc_middle/messages.ftl
index 39485a324f2..52c3212ab80 100644
--- a/compiler/rustc_middle/messages.ftl
+++ b/compiler/rustc_middle/messages.ftl
@@ -68,8 +68,8 @@ middle_deprecated_in_version = use of {$kind} `{$path}` that will be deprecated
 middle_deprecated_suggestion = replace the use of the deprecated {$kind}
 
 middle_drop_check_overflow =
-    overflow while adding drop-check rules for {$ty}
-    .note = overflowed on {$overflow_ty}
+    overflow while adding drop-check rules for `{$ty}`
+    .note = overflowed on `{$overflow_ty}`
 
 middle_erroneous_constant = erroneous constant encountered
 
diff --git a/compiler/rustc_middle/src/mir/coverage.rs b/compiler/rustc_middle/src/mir/coverage.rs
index 4a876dc1228..11a4e7f89a7 100644
--- a/compiler/rustc_middle/src/mir/coverage.rs
+++ b/compiler/rustc_middle/src/mir/coverage.rs
@@ -4,7 +4,7 @@ use std::fmt::{self, Debug, Formatter};
 
 use rustc_index::IndexVec;
 use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
-use rustc_span::{Span, Symbol};
+use rustc_span::Span;
 
 rustc_index::newtype_index! {
     /// Used by [`CoverageKind::BlockMarker`] to mark blocks during THIR-to-MIR
@@ -158,7 +158,6 @@ impl Debug for CoverageKind {
 #[derive(Clone, TyEncodable, TyDecodable, Hash, HashStable, PartialEq, Eq, PartialOrd, Ord)]
 #[derive(TypeFoldable, TypeVisitable)]
 pub struct SourceRegion {
-    pub file_name: Symbol,
     pub start_line: u32,
     pub start_col: u32,
     pub end_line: u32,
@@ -167,11 +166,8 @@ pub struct SourceRegion {
 
 impl Debug for SourceRegion {
     fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
-        write!(
-            fmt,
-            "{}:{}:{} - {}:{}",
-            self.file_name, self.start_line, self.start_col, self.end_line, self.end_col
-        )
+        let &Self { start_line, start_col, end_line, end_col } = self;
+        write!(fmt, "{start_line}:{start_col} - {end_line}:{end_col}")
     }
 }
 
@@ -246,6 +242,7 @@ pub struct Mapping {
 #[derive(TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable, TypeVisitable)]
 pub struct FunctionCoverageInfo {
     pub function_source_hash: u64,
+    pub body_span: Span,
     pub num_counters: usize,
     pub mcdc_bitmap_bits: usize,
     pub expressions: IndexVec<ExpressionId, Expression>,
diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs
index b0c0e1be500..f225ad94aa7 100644
--- a/compiler/rustc_middle/src/mir/interpret/mod.rs
+++ b/compiler/rustc_middle/src/mir/interpret/mod.rs
@@ -12,11 +12,12 @@ use std::io::{Read, Write};
 use std::num::NonZero;
 use std::{fmt, io};
 
-use rustc_abi::{AddressSpace, Endian, HasDataLayout};
-use rustc_ast::LitKind;
+use rustc_abi::{AddressSpace, Align, Endian, HasDataLayout, Size};
+use rustc_ast::{LitKind, Mutability};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::sync::Lock;
 use rustc_errors::ErrorGuaranteed;
+use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
 use rustc_middle::ty::print::with_no_trimmed_paths;
@@ -45,7 +46,7 @@ pub use self::pointer::{CtfeProvenance, Pointer, PointerArithmetic, Provenance};
 pub use self::value::Scalar;
 use crate::mir;
 use crate::ty::codec::{TyDecoder, TyEncoder};
-use crate::ty::{self, Instance, Ty, TyCtxt};
+use crate::ty::{self, Instance, ParamEnv, Ty, TyCtxt};
 
 /// Uniquely identifies one of the following:
 /// - A constant
@@ -310,6 +311,85 @@ impl<'tcx> GlobalAlloc<'tcx> {
             }
         }
     }
+
+    pub fn mutability(&self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Mutability {
+        // Let's see what kind of memory we are.
+        match self {
+            GlobalAlloc::Static(did) => {
+                let DefKind::Static { safety: _, mutability, nested } = tcx.def_kind(did) else {
+                    bug!()
+                };
+                if nested {
+                    // Nested statics in a `static` are never interior mutable,
+                    // so just use the declared mutability.
+                    if cfg!(debug_assertions) {
+                        let alloc = tcx.eval_static_initializer(did).unwrap();
+                        assert_eq!(alloc.0.mutability, mutability);
+                    }
+                    mutability
+                } else {
+                    let mutability = match mutability {
+                        Mutability::Not
+                            if !tcx
+                                .type_of(did)
+                                .no_bound_vars()
+                                .expect("statics should not have generic parameters")
+                                .is_freeze(tcx, param_env) =>
+                        {
+                            Mutability::Mut
+                        }
+                        _ => mutability,
+                    };
+                    mutability
+                }
+            }
+            GlobalAlloc::Memory(alloc) => alloc.inner().mutability,
+            GlobalAlloc::Function { .. } | GlobalAlloc::VTable(..) => {
+                // These are immutable.
+                Mutability::Not
+            }
+        }
+    }
+
+    pub fn size_and_align(&self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> (Size, Align) {
+        match self {
+            GlobalAlloc::Static(def_id) => {
+                let DefKind::Static { nested, .. } = tcx.def_kind(def_id) else {
+                    bug!("GlobalAlloc::Static is not a static")
+                };
+
+                if nested {
+                    // Nested anonymous statics are untyped, so let's get their
+                    // size and alignment from the allocation itself. This always
+                    // succeeds, as the query is fed at DefId creation time, so no
+                    // evaluation actually occurs.
+                    let alloc = tcx.eval_static_initializer(def_id).unwrap();
+                    (alloc.0.size(), alloc.0.align)
+                } else {
+                    // Use size and align of the type for everything else. We need
+                    // to do that to
+                    // * avoid cycle errors in case of self-referential statics,
+                    // * be able to get information on extern statics.
+                    let ty = tcx
+                        .type_of(def_id)
+                        .no_bound_vars()
+                        .expect("statics should not have generic parameters");
+                    let layout = tcx.layout_of(param_env.and(ty)).unwrap();
+                    assert!(layout.is_sized());
+                    (layout.size, layout.align.abi)
+                }
+            }
+            GlobalAlloc::Memory(alloc) => {
+                let alloc = alloc.inner();
+                (alloc.size(), alloc.align)
+            }
+            GlobalAlloc::Function { .. } => (Size::ZERO, Align::ONE),
+            GlobalAlloc::VTable(..) => {
+                // No data to be accessed here. But vtables are pointer-aligned.
+                return (Size::ZERO, tcx.data_layout.pointer_align.abi);
+            }
+        }
+    }
 }
 
 pub const CTFE_ALLOC_SALT: usize = 0;
diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs
index d0f93c19e44..f0e2b7a376c 100644
--- a/compiler/rustc_middle/src/mir/pretty.rs
+++ b/compiler/rustc_middle/src/mir/pretty.rs
@@ -596,8 +596,10 @@ fn write_function_coverage_info(
     function_coverage_info: &coverage::FunctionCoverageInfo,
     w: &mut dyn io::Write,
 ) -> io::Result<()> {
-    let coverage::FunctionCoverageInfo { expressions, mappings, .. } = function_coverage_info;
+    let coverage::FunctionCoverageInfo { body_span, expressions, mappings, .. } =
+        function_coverage_info;
 
+    writeln!(w, "{INDENT}coverage body span: {body_span:?}")?;
     for (id, expression) in expressions.iter_enumerated() {
         writeln!(w, "{INDENT}coverage {id:?} => {expression:?};")?;
     }
diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs
index c34bdf041af..86abeb50382 100644
--- a/compiler/rustc_middle/src/mir/query.rs
+++ b/compiler/rustc_middle/src/mir/query.rs
@@ -317,7 +317,10 @@ impl<'tcx> ClosureOutlivesSubjectTy<'tcx> {
     pub fn bind(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Self {
         let inner = tcx.fold_regions(ty, |r, depth| match r.kind() {
             ty::ReVar(vid) => {
-                let br = ty::BoundRegion { var: ty::BoundVar::new(vid.index()), kind: ty::BrAnon };
+                let br = ty::BoundRegion {
+                    var: ty::BoundVar::new(vid.index()),
+                    kind: ty::BoundRegionKind::Anon,
+                };
                 ty::Region::new_bound(tcx, depth, br)
             }
             _ => bug!("unexpected region in ClosureOutlivesSubjectTy: {r:?}"),
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 30a2e839fb4..b25ed1c44e1 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -1844,6 +1844,16 @@ rustc_queries! {
         desc { |tcx| "computing crate imported by `{}`", tcx.def_path_str(def_id) }
     }
 
+    /// Gets the number of definitions in a foreign crate.
+    ///
+    /// This allows external tools to iterate over all definitions in a foreign crate.
+    ///
+    /// This should never be used for the local crate, instead use `iter_local_def_id`.
+    query num_extern_def_ids(_: CrateNum) -> usize {
+        desc { "fetching the number of definitions in a crate" }
+        separate_provide_extern
+    }
+
     query lib_features(_: CrateNum) -> &'tcx LibFeatures {
         desc { "calculating the lib features defined in a crate" }
         separate_provide_extern
@@ -2200,10 +2210,11 @@ rustc_queries! {
         desc { "computing autoderef types for `{}`", goal.canonical.value.value }
     }
 
-    query supported_target_features(_: CrateNum) -> &'tcx UnordMap<String, Option<Symbol>> {
+    /// Returns the Rust target features for the current target. These are not always the same as LLVM target features!
+    query rust_target_features(_: CrateNum) -> &'tcx UnordMap<String, rustc_target::target_features::Stability> {
         arena_cache
         eval_always
-        desc { "looking up supported target features" }
+        desc { "looking up Rust target features" }
     }
 
     query implied_target_features(feature: Symbol) -> &'tcx Vec<Symbol> {
@@ -2314,6 +2325,14 @@ rustc_queries! {
         desc { "whether the item should be made inlinable across crates" }
         separate_provide_extern
     }
+
+    /// Check the signature of this function as well as all the call expressions inside of it
+    /// to ensure that any target features required by the ABI are enabled.
+    /// Should be called on a fully monomorphized instance.
+    query check_feature_dependent_abi(key: ty::Instance<'tcx>) {
+        desc { "check for feature-dependent ABI" }
+        cache_on_disk_if { true }
+    }
 }
 
 rustc_query_append! { define_callbacks! }
diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs
index 57da5b39ba7..20ba1b27c0e 100644
--- a/compiler/rustc_middle/src/query/plumbing.rs
+++ b/compiler/rustc_middle/src/query/plumbing.rs
@@ -319,7 +319,7 @@ macro_rules! define_callbacks {
 
                 pub type Storage<'tcx> = <$($K)* as keys::Key>::Cache<Erase<$V>>;
 
-                // Ensure that keys grow no larger than 72 bytes by accident.
+                // Ensure that keys grow no larger than 80 bytes by accident.
                 // Increase this limit if necessary, but do try to keep the size low if possible
                 #[cfg(target_pointer_width = "64")]
                 const _: () = {
diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs
index 40e5ec45959..09731d565b6 100644
--- a/compiler/rustc_middle/src/traits/mod.rs
+++ b/compiler/rustc_middle/src/traits/mod.rs
@@ -193,6 +193,11 @@ pub enum ObligationCauseCode<'tcx> {
     /// The span corresponds to the clause.
     WhereClause(DefId, Span),
 
+    /// Represents a bound for an opaque we are checking the well-formedness of.
+    /// The def-id corresponds to a specific definition site that we found the
+    /// hidden type from, if any.
+    OpaqueTypeBound(Span, Option<LocalDefId>),
+
     /// Like `WhereClause`, but also identifies the expression
     /// which requires the `where` clause to be proven, and also
     /// identifies the index of the predicate in the `predicates_of`
diff --git a/compiler/rustc_middle/src/ty/assoc.rs b/compiler/rustc_middle/src/ty/assoc.rs
index 3137fe9bd1d..62157d9bfe2 100644
--- a/compiler/rustc_middle/src/ty/assoc.rs
+++ b/compiler/rustc_middle/src/ty/assoc.rs
@@ -10,8 +10,8 @@ use crate::ty;
 
 #[derive(Clone, Copy, PartialEq, Eq, Debug, HashStable, Hash, Encodable, Decodable)]
 pub enum AssocItemContainer {
-    TraitContainer,
-    ImplContainer,
+    Trait,
+    Impl,
 }
 
 /// Information about an associated item
@@ -63,16 +63,16 @@ impl AssocItem {
     #[inline]
     pub fn trait_container(&self, tcx: TyCtxt<'_>) -> Option<DefId> {
         match self.container {
-            AssocItemContainer::ImplContainer => None,
-            AssocItemContainer::TraitContainer => Some(tcx.parent(self.def_id)),
+            AssocItemContainer::Impl => None,
+            AssocItemContainer::Trait => Some(tcx.parent(self.def_id)),
         }
     }
 
     #[inline]
     pub fn impl_container(&self, tcx: TyCtxt<'_>) -> Option<DefId> {
         match self.container {
-            AssocItemContainer::ImplContainer => Some(tcx.parent(self.def_id)),
-            AssocItemContainer::TraitContainer => None,
+            AssocItemContainer::Impl => Some(tcx.parent(self.def_id)),
+            AssocItemContainer::Trait => None,
         }
     }
 
diff --git a/compiler/rustc_middle/src/ty/closure.rs b/compiler/rustc_middle/src/ty/closure.rs
index 9ee82942911..6ab4d76e545 100644
--- a/compiler/rustc_middle/src/ty/closure.rs
+++ b/compiler/rustc_middle/src/ty/closure.rs
@@ -10,7 +10,6 @@ use rustc_span::def_id::LocalDefIdMap;
 use rustc_span::symbol::Ident;
 use rustc_span::{Span, Symbol};
 
-use self::BorrowKind::*;
 use super::TyCtxt;
 use crate::hir::place::{
     Place as HirPlace, PlaceBase as HirPlaceBase, ProjectionKind as HirProjectionKind,
@@ -334,7 +333,7 @@ pub fn place_to_string_for_capture<'tcx>(tcx: TyCtxt<'tcx>, place: &HirPlace<'tc
 #[derive(TypeFoldable, TypeVisitable)]
 pub enum BorrowKind {
     /// Data must be immutable and is aliasable.
-    ImmBorrow,
+    Immutable,
 
     /// Data must be immutable but not aliasable. This kind of borrow
     /// cannot currently be expressed by the user and is used only in
@@ -382,17 +381,17 @@ pub enum BorrowKind {
     /// borrow, it's just used when translating closures.
     ///
     /// FIXME: Rename this to indicate the borrow is actually not immutable.
-    UniqueImmBorrow,
+    UniqueImmutable,
 
     /// Data is mutable and not aliasable.
-    MutBorrow,
+    Mutable,
 }
 
 impl BorrowKind {
     pub fn from_mutbl(m: hir::Mutability) -> BorrowKind {
         match m {
-            hir::Mutability::Mut => MutBorrow,
-            hir::Mutability::Not => ImmBorrow,
+            hir::Mutability::Mut => BorrowKind::Mutable,
+            hir::Mutability::Not => BorrowKind::Immutable,
         }
     }
 
@@ -402,13 +401,13 @@ impl BorrowKind {
     /// question.
     pub fn to_mutbl_lossy(self) -> hir::Mutability {
         match self {
-            MutBorrow => hir::Mutability::Mut,
-            ImmBorrow => hir::Mutability::Not,
+            BorrowKind::Mutable => hir::Mutability::Mut,
+            BorrowKind::Immutable => hir::Mutability::Not,
 
             // We have no type corresponding to a unique imm borrow, so
             // use `&mut`. It gives all the capabilities of a `&uniq`
             // and hence is a safe "over approximation".
-            UniqueImmBorrow => hir::Mutability::Mut,
+            BorrowKind::UniqueImmutable => hir::Mutability::Mut,
         }
     }
 }
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 59c7b51ae68..c55733da7b3 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -1059,7 +1059,7 @@ impl<'tcx> CommonLifetimes<'tcx> {
                     .map(|v| {
                         mk(ty::ReBound(ty::DebruijnIndex::from(i), ty::BoundRegion {
                             var: ty::BoundVar::from(v),
-                            kind: ty::BrAnon,
+                            kind: ty::BoundRegionKind::Anon,
                         }))
                     })
                     .collect()
@@ -1982,7 +1982,10 @@ impl<'tcx> TyCtxt<'tcx> {
                 region = self.map_opaque_lifetime_to_parent_lifetime(def_id);
                 continue;
             }
-            break (scope, ty::BrNamed(def_id.into(), self.item_name(def_id.into())));
+            break (
+                scope,
+                ty::BoundRegionKind::Named(def_id.into(), self.item_name(def_id.into())),
+            );
         };
 
         let is_impl_item = match self.hir_node_by_def_id(suitable_region_binding_scope) {
@@ -3091,7 +3094,7 @@ impl<'tcx> TyCtxt<'tcx> {
                     return ty::Region::new_late_param(
                         self,
                         new_parent.to_def_id(),
-                        ty::BoundRegionKind::BrNamed(
+                        ty::BoundRegionKind::Named(
                             lbv.to_def_id(),
                             self.item_name(lbv.to_def_id()),
                         ),
diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs
index b5a77b3c942..7adbd556141 100644
--- a/compiler/rustc_middle/src/ty/fold.rs
+++ b/compiler/rustc_middle/src/ty/fold.rs
@@ -399,7 +399,7 @@ impl<'tcx> TyCtxt<'tcx> {
                 let index = entry.index();
                 let var = ty::BoundVar::from_usize(index);
                 let kind = entry
-                    .or_insert_with(|| ty::BoundVariableKind::Region(ty::BrAnon))
+                    .or_insert_with(|| ty::BoundVariableKind::Region(ty::BoundRegionKind::Anon))
                     .expect_region();
                 let br = ty::BoundRegion { var, kind };
                 ty::Region::new_bound(self.tcx, ty::INNERMOST, br)
diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs
index 19779740227..ce40ab18261 100644
--- a/compiler/rustc_middle/src/ty/generics.rs
+++ b/compiler/rustc_middle/src/ty/generics.rs
@@ -86,10 +86,10 @@ impl GenericParamDef {
         tcx: TyCtxt<'tcx>,
     ) -> Option<EarlyBinder<'tcx, ty::GenericArg<'tcx>>> {
         match self.kind {
-            GenericParamDefKind::Type { has_default, .. } if has_default => {
+            GenericParamDefKind::Type { has_default: true, .. } => {
                 Some(tcx.type_of(self.def_id).map_bound(|t| t.into()))
             }
-            GenericParamDefKind::Const { has_default, .. } if has_default => {
+            GenericParamDefKind::Const { has_default: true, .. } => {
                 Some(tcx.const_param_default(self.def_id).map_bound(|c| c.into()))
             }
             _ => None,
diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs
index e237d382900..0d1c56f0d38 100644
--- a/compiler/rustc_middle/src/ty/instance.rs
+++ b/compiler/rustc_middle/src/ty/instance.rs
@@ -71,7 +71,7 @@ pub enum InstanceKind<'tcx> {
     /// - coroutines
     Item(DefId),
 
-    /// An intrinsic `fn` item (with `"rust-intrinsic"` or `"platform-intrinsic"` ABI).
+    /// An intrinsic `fn` item (with `"rust-intrinsic"` ABI).
     ///
     /// Alongside `Virtual`, this is the only `InstanceKind` that does not have its own callable MIR.
     /// Instead, codegen and const eval "magically" evaluate calls to intrinsics purely in the
@@ -690,7 +690,7 @@ impl<'tcx> Instance<'tcx> {
                         && !matches!(
                             tcx.opt_associated_item(def),
                             Some(ty::AssocItem {
-                                container: ty::AssocItemContainer::TraitContainer,
+                                container: ty::AssocItemContainer::Trait,
                                 ..
                             })
                         )
diff --git a/compiler/rustc_middle/src/ty/intrinsic.rs b/compiler/rustc_middle/src/ty/intrinsic.rs
index ed0fb37d3b8..6a3ddacb424 100644
--- a/compiler/rustc_middle/src/ty/intrinsic.rs
+++ b/compiler/rustc_middle/src/ty/intrinsic.rs
@@ -9,6 +9,8 @@ pub struct IntrinsicDef {
     pub name: Symbol,
     /// Whether the intrinsic has no meaningful body and all backends need to shim all calls to it.
     pub must_be_overridden: bool,
+    /// Whether the intrinsic can be invoked from stable const fn
+    pub const_stable: bool,
 }
 
 impl TyCtxt<'_> {
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs
index 76e3183fcbb..a0eb9029319 100644
--- a/compiler/rustc_middle/src/ty/layout.rs
+++ b/compiler/rustc_middle/src/ty/layout.rs
@@ -1011,25 +1011,41 @@ where
             }
 
             _ => {
-                let mut data_variant = match this.variants {
+                let mut data_variant = match &this.variants {
                     // 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).
+                    // Our goal here is to check whether this represents a
+                    // "dereferenceable or null" pointer, so we need to ensure
+                    // that there is only one other variant, and it must be null.
+                    // Below, we will then check whether the pointer is indeed
+                    // dereferenceable.
                     Variants::Multiple {
-                        tag_encoding: TagEncoding::Niche { untagged_variant, .. },
+                        tag_encoding:
+                            TagEncoding::Niche { untagged_variant, niche_variants, niche_start },
                         tag_field,
+                        variants,
                         ..
-                    } if this.fields.offset(tag_field) == offset => {
-                        Some(this.for_variant(cx, untagged_variant))
+                    } if variants.len() == 2 && this.fields.offset(*tag_field) == offset => {
+                        let tagged_variant = if untagged_variant.as_u32() == 0 {
+                            VariantIdx::from_u32(1)
+                        } else {
+                            VariantIdx::from_u32(0)
+                        };
+                        assert_eq!(tagged_variant, *niche_variants.start());
+                        if *niche_start == 0 {
+                            // The other variant is encoded as "null", so we can recurse searching for
+                            // a pointer here. This relies on the fact that the codegen backend
+                            // only adds "dereferenceable" if there's also a "nonnull" proof,
+                            // and that null is aligned for all alignments so it's okay to forward
+                            // the pointer's alignment.
+                            Some(this.for_variant(cx, *untagged_variant))
+                        } else {
+                            None
+                        }
                     }
+                    Variants::Multiple { .. } => None,
                     _ => Some(this),
                 };
 
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 8a324be32e7..1a3128ed936 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -49,19 +49,12 @@ pub use rustc_session::lint::RegisteredTools;
 use rustc_span::hygiene::MacroKind;
 use rustc_span::symbol::{Ident, Symbol, kw, sym};
 use rustc_span::{ExpnId, ExpnKind, Span};
-pub use rustc_type_ir::ConstKind::{
-    Bound as BoundCt, Error as ErrorCt, Expr as ExprCt, Infer as InferCt, Param as ParamCt,
-    Placeholder as PlaceholderCt, Unevaluated, Value,
-};
 pub use rustc_type_ir::relate::VarianceDiagInfo;
 pub use rustc_type_ir::*;
 use tracing::{debug, instrument};
 pub use vtable::*;
 use {rustc_ast as ast, rustc_attr as attr, rustc_hir as hir};
 
-pub use self::AssocItemContainer::*;
-pub use self::BorrowKind::*;
-pub use self::IntVarValue::*;
 pub use self::closure::{
     BorrowKind, CAPTURE_STRUCT_LOCAL, CaptureInfo, CapturedPlace, ClosureTypeInfo,
     MinCaptureInformationMap, MinCaptureList, RootVariableMinCaptureList, UpvarCapture, UpvarId,
@@ -91,7 +84,6 @@ pub use self::predicate::{
     RegionOutlivesPredicate, SubtypePredicate, ToPolyTraitRef, TraitPredicate, TraitRef,
     TypeOutlivesPredicate,
 };
-pub use self::region::BoundRegionKind::*;
 pub use self::region::{
     BoundRegion, BoundRegionKind, EarlyParamRegion, LateParamRegion, Region, RegionKind, RegionVid,
 };
@@ -902,7 +894,7 @@ impl rustc_type_ir::inherent::PlaceholderLike for PlaceholderRegion {
     }
 
     fn new(ui: UniverseIndex, var: BoundVar) -> Self {
-        Placeholder { universe: ui, bound: BoundRegion { var, kind: BoundRegionKind::BrAnon } }
+        Placeholder { universe: ui, bound: BoundRegion { var, kind: BoundRegionKind::Anon } }
     }
 }
 
@@ -1084,11 +1076,6 @@ impl<'tcx> ParamEnv<'tcx> {
         ty::ParamEnv { packed: CopyTaggedPtr::new(caller_bounds, ParamTag { reveal }) }
     }
 
-    pub fn with_user_facing(mut self) -> Self {
-        self.packed.set_tag(ParamTag { reveal: Reveal::UserFacing, ..self.packed.tag() });
-        self
-    }
-
     /// 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
@@ -1103,6 +1090,12 @@ impl<'tcx> ParamEnv<'tcx> {
             return self;
         }
 
+        // No need to reveal opaques with the new solver enabled,
+        // since we have lazy norm.
+        if tcx.next_trait_solver_globally() {
+            return ParamEnv::new(self.caller_bounds(), Reveal::All);
+        }
+
         ParamEnv::new(tcx.reveal_opaque_types_in_bounds(self.caller_bounds()), Reveal::All)
     }
 
@@ -2078,7 +2071,7 @@ impl<'tcx> TyCtxt<'tcx> {
         let Some(item) = self.opt_associated_item(def_id) else {
             return false;
         };
-        if item.container != ty::AssocItemContainer::ImplContainer {
+        if item.container != ty::AssocItemContainer::Impl {
             return false;
         }
 
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index d8725cb6ba0..039c988f5c9 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -2483,7 +2483,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
             | ty::RePlaceholder(ty::Placeholder {
                 bound: ty::BoundRegion { kind: br, .. }, ..
             }) => {
-                if let ty::BrNamed(_, name) = br
+                if let ty::BoundRegionKind::Named(_, name) = br
                     && br.is_named()
                 {
                     p!(write("{}", name));
@@ -2569,7 +2569,7 @@ impl<'a, 'tcx> ty::TypeFolder<TyCtxt<'tcx>> for RegionFolder<'a, 'tcx> {
                 // If this is an anonymous placeholder, don't rename. Otherwise, in some
                 // async fns, we get a `for<'r> Send` bound
                 match kind {
-                    ty::BrAnon | ty::BrEnv => r,
+                    ty::BoundRegionKind::Anon | ty::BoundRegionKind::ClosureEnv => r,
                     _ => {
                         // Index doesn't matter, since this is just for naming and these never get bound
                         let br = ty::BoundRegion { var: ty::BoundVar::ZERO, kind };
@@ -2688,12 +2688,13 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
                             binder_level_idx: ty::DebruijnIndex,
                             br: ty::BoundRegion| {
                 let (name, kind) = match br.kind {
-                    ty::BrAnon | ty::BrEnv => {
+                    ty::BoundRegionKind::Anon | ty::BoundRegionKind::ClosureEnv => {
                         let name = next_name(self);
 
                         if let Some(lt_idx) = lifetime_idx {
                             if lt_idx > binder_level_idx {
-                                let kind = ty::BrNamed(CRATE_DEF_ID.to_def_id(), name);
+                                let kind =
+                                    ty::BoundRegionKind::Named(CRATE_DEF_ID.to_def_id(), name);
                                 return ty::Region::new_bound(
                                     tcx,
                                     ty::INNERMOST,
@@ -2702,14 +2703,14 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
                             }
                         }
 
-                        (name, ty::BrNamed(CRATE_DEF_ID.to_def_id(), name))
+                        (name, ty::BoundRegionKind::Named(CRATE_DEF_ID.to_def_id(), name))
                     }
-                    ty::BrNamed(def_id, kw::UnderscoreLifetime | kw::Empty) => {
+                    ty::BoundRegionKind::Named(def_id, kw::UnderscoreLifetime | kw::Empty) => {
                         let name = next_name(self);
 
                         if let Some(lt_idx) = lifetime_idx {
                             if lt_idx > binder_level_idx {
-                                let kind = ty::BrNamed(def_id, name);
+                                let kind = ty::BoundRegionKind::Named(def_id, name);
                                 return ty::Region::new_bound(
                                     tcx,
                                     ty::INNERMOST,
@@ -2718,9 +2719,9 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
                             }
                         }
 
-                        (name, ty::BrNamed(def_id, name))
+                        (name, ty::BoundRegionKind::Named(def_id, name))
                     }
-                    ty::BrNamed(_, name) => {
+                    ty::BoundRegionKind::Named(_, name) => {
                         if let Some(lt_idx) = lifetime_idx {
                             if lt_idx > binder_level_idx {
                                 let kind = br.kind;
diff --git a/compiler/rustc_middle/src/ty/region.rs b/compiler/rustc_middle/src/ty/region.rs
index be4772e888f..60c2c322d4f 100644
--- a/compiler/rustc_middle/src/ty/region.rs
+++ b/compiler/rustc_middle/src/ty/region.rs
@@ -56,7 +56,7 @@ impl<'tcx> Region<'tcx> {
         bound_region: ty::BoundRegion,
     ) -> Region<'tcx> {
         // Use a pre-interned one when possible.
-        if let ty::BoundRegion { var, kind: ty::BrAnon } = bound_region
+        if let ty::BoundRegion { var, kind: ty::BoundRegionKind::Anon } = bound_region
             && let Some(inner) = tcx.lifetimes.re_late_bounds.get(debruijn.as_usize())
             && let Some(re) = inner.get(var.as_usize()).copied()
         {
@@ -147,7 +147,7 @@ impl<'tcx> rustc_type_ir::inherent::Region<TyCtxt<'tcx>> for Region<'tcx> {
     }
 
     fn new_anon_bound(tcx: TyCtxt<'tcx>, debruijn: ty::DebruijnIndex, var: ty::BoundVar) -> Self {
-        Region::new_bound(tcx, debruijn, ty::BoundRegion { var, kind: ty::BoundRegionKind::BrAnon })
+        Region::new_bound(tcx, debruijn, ty::BoundRegion { var, kind: ty::BoundRegionKind::Anon })
     }
 
     fn new_static(tcx: TyCtxt<'tcx>) -> Self {
@@ -311,7 +311,7 @@ impl<'tcx> Region<'tcx> {
                 Some(tcx.generics_of(binding_item).region_param(ebr, tcx).def_id)
             }
             ty::ReLateParam(ty::LateParamRegion {
-                bound_region: ty::BoundRegionKind::BrNamed(def_id, _),
+                bound_region: ty::BoundRegionKind::Named(def_id, _),
                 ..
             }) => Some(def_id),
             _ => None,
@@ -355,7 +355,7 @@ impl std::fmt::Debug for EarlyParamRegion {
 /// Similar to a placeholder region as we create `LateParam` regions when entering a binder
 /// except they are always in the root universe and instead of using a boundvar to distinguish
 /// between others we use the `DefId` of the parameter. For this reason the `bound_region` field
-/// should basically always be `BoundRegionKind::BrNamed` as otherwise there is no way of telling
+/// should basically always be `BoundRegionKind::Named` as otherwise there is no way of telling
 /// different parameters apart.
 pub struct LateParamRegion {
     pub scope: DefId,
@@ -366,17 +366,17 @@ pub struct LateParamRegion {
 #[derive(HashStable)]
 pub enum BoundRegionKind {
     /// An anonymous region parameter for a given fn (&T)
-    BrAnon,
+    Anon,
 
     /// Named region parameters for functions (a in &'a T)
     ///
     /// The `DefId` is needed to distinguish free regions in
     /// the event of shadowing.
-    BrNamed(DefId, Symbol),
+    Named(DefId, Symbol),
 
     /// Anonymous region for the implicit env pointer parameter
     /// to a closure
-    BrEnv,
+    ClosureEnv,
 }
 
 #[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
@@ -399,9 +399,9 @@ impl<'tcx> rustc_type_ir::inherent::BoundVarLike<TyCtxt<'tcx>> for BoundRegion {
 impl core::fmt::Debug for BoundRegion {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         match self.kind {
-            BoundRegionKind::BrAnon => write!(f, "{:?}", self.var),
-            BoundRegionKind::BrEnv => write!(f, "{:?}.Env", self.var),
-            BoundRegionKind::BrNamed(def, symbol) => {
+            BoundRegionKind::Anon => write!(f, "{:?}", self.var),
+            BoundRegionKind::ClosureEnv => write!(f, "{:?}.Env", self.var),
+            BoundRegionKind::Named(def, symbol) => {
                 write!(f, "{:?}.Named({:?}, {:?})", self.var, def, symbol)
             }
         }
@@ -411,9 +411,7 @@ impl core::fmt::Debug for BoundRegion {
 impl BoundRegionKind {
     pub fn is_named(&self) -> bool {
         match *self {
-            BoundRegionKind::BrNamed(_, name) => {
-                name != kw::UnderscoreLifetime && name != kw::Empty
-            }
+            BoundRegionKind::Named(_, name) => name != kw::UnderscoreLifetime && name != kw::Empty,
             _ => false,
         }
     }
@@ -421,7 +419,7 @@ impl BoundRegionKind {
     pub fn get_name(&self) -> Option<Symbol> {
         if self.is_named() {
             match *self {
-                BoundRegionKind::BrNamed(_, name) => return Some(name),
+                BoundRegionKind::Named(_, name) => return Some(name),
                 _ => unreachable!(),
             }
         }
@@ -431,7 +429,7 @@ impl BoundRegionKind {
 
     pub fn get_id(&self) -> Option<DefId> {
         match *self {
-            BoundRegionKind::BrNamed(id, _) => Some(id),
+            BoundRegionKind::Named(id, _) => Some(id),
             _ => None,
         }
     }
diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs
index 3268dabd165..e48fac6c7e8 100644
--- a/compiler/rustc_middle/src/ty/structural_impls.rs
+++ b/compiler/rustc_middle/src/ty/structural_impls.rs
@@ -62,15 +62,15 @@ impl<'tcx> fmt::Debug for ty::adjustment::Adjustment<'tcx> {
 impl fmt::Debug for ty::BoundRegionKind {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match *self {
-            ty::BrAnon => write!(f, "BrAnon"),
-            ty::BrNamed(did, name) => {
+            ty::BoundRegionKind::Anon => write!(f, "BrAnon"),
+            ty::BoundRegionKind::Named(did, name) => {
                 if did.is_crate_root() {
                     write!(f, "BrNamed({name})")
                 } else {
                     write!(f, "BrNamed({did:?}, {name})")
                 }
             }
-            ty::BrEnv => write!(f, "BrEnv"),
+            ty::BoundRegionKind::ClosureEnv => write!(f, "BrEnv"),
         }
     }
 }
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index e27bb2fd135..142db8a17f0 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -1933,6 +1933,7 @@ impl<'tcx> Ty<'tcx> {
                 ty::UintTy::U64 => Some(sym::u64),
                 ty::UintTy::U128 => Some(sym::u128),
             },
+            ty::Str => Some(sym::str),
             _ => None,
         }
     }
diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs
index 83276808a28..3c6e34160f4 100644
--- a/compiler/rustc_middle/src/ty/util.rs
+++ b/compiler/rustc_middle/src/ty/util.rs
@@ -735,8 +735,11 @@ impl<'tcx> TyCtxt<'tcx> {
                 let ty = self.fold_regions(decl.ty, |re, debruijn| {
                     assert_eq!(re, self.lifetimes.re_erased);
                     let var = ty::BoundVar::from_usize(vars.len());
-                    vars.push(ty::BoundVariableKind::Region(ty::BrAnon));
-                    ty::Region::new_bound(self, debruijn, ty::BoundRegion { var, kind: ty::BrAnon })
+                    vars.push(ty::BoundVariableKind::Region(ty::BoundRegionKind::Anon));
+                    ty::Region::new_bound(self, debruijn, ty::BoundRegion {
+                        var,
+                        kind: ty::BoundRegionKind::Anon,
+                    })
                 });
                 ty::EarlyBinder::bind(ty::Binder::bind_with_vars(
                     ty,
@@ -1748,6 +1751,7 @@ pub fn reveal_opaque_types_in_bounds<'tcx>(
     tcx: TyCtxt<'tcx>,
     val: ty::Clauses<'tcx>,
 ) -> ty::Clauses<'tcx> {
+    assert!(!tcx.next_trait_solver_globally());
     let mut visitor = OpaqueTypeExpander {
         seen_opaque_tys: FxHashSet::default(),
         expanded_cache: FxHashMap::default(),
@@ -1782,13 +1786,14 @@ pub fn is_doc_notable_trait(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
 /// the compiler to make some assumptions about its shape; if the user doesn't use a feature gate, they may
 /// cause an ICE that we otherwise may want to prevent.
 pub fn intrinsic_raw(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<ty::IntrinsicDef> {
-    if (matches!(tcx.fn_sig(def_id).skip_binder().abi(), ExternAbi::RustIntrinsic)
-        && tcx.features().intrinsics())
-        || (tcx.has_attr(def_id, sym::rustc_intrinsic) && tcx.features().rustc_attrs())
+    if tcx.features().intrinsics()
+        && (matches!(tcx.fn_sig(def_id).skip_binder().abi(), ExternAbi::RustIntrinsic)
+            || tcx.has_attr(def_id, sym::rustc_intrinsic))
     {
         Some(ty::IntrinsicDef {
             name: tcx.item_name(def_id.into()),
             must_be_overridden: tcx.has_attr(def_id, sym::rustc_intrinsic_must_be_overridden),
+            const_stable: tcx.has_attr(def_id, sym::rustc_const_stable_intrinsic),
         })
     } else {
         None
diff --git a/compiler/rustc_middle/src/util/call_kind.rs b/compiler/rustc_middle/src/util/call_kind.rs
index fe30cbfae4e..ed27a880562 100644
--- a/compiler/rustc_middle/src/util/call_kind.rs
+++ b/compiler/rustc_middle/src/util/call_kind.rs
@@ -72,8 +72,8 @@ pub fn call_kind<'tcx>(
     let parent = tcx.opt_associated_item(method_did).and_then(|assoc| {
         let container_id = assoc.container_id(tcx);
         match assoc.container {
-            AssocItemContainer::ImplContainer => tcx.trait_id_of_impl(container_id),
-            AssocItemContainer::TraitContainer => Some(container_id),
+            AssocItemContainer::Impl => tcx.trait_id_of_impl(container_id),
+            AssocItemContainer::Trait => Some(container_id),
         }
     });