about summary refs log tree commit diff
path: root/compiler/rustc_middle/src
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_middle/src')
-rw-r--r--compiler/rustc_middle/src/mir/basic_blocks.rs2
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs44
-rw-r--r--compiler/rustc_middle/src/mir/pretty.rs5
-rw-r--r--compiler/rustc_middle/src/mir/syntax.rs100
-rw-r--r--compiler/rustc_middle/src/mir/terminator.rs2
-rw-r--r--compiler/rustc_middle/src/mir/traversal.rs47
-rw-r--r--compiler/rustc_middle/src/traits/mod.rs38
-rw-r--r--compiler/rustc_middle/src/traits/query.rs6
8 files changed, 101 insertions, 143 deletions
diff --git a/compiler/rustc_middle/src/mir/basic_blocks.rs b/compiler/rustc_middle/src/mir/basic_blocks.rs
index 107c3198525..171542d1279 100644
--- a/compiler/rustc_middle/src/mir/basic_blocks.rs
+++ b/compiler/rustc_middle/src/mir/basic_blocks.rs
@@ -79,7 +79,7 @@ impl<'tcx> BasicBlocks<'tcx> {
     #[inline]
     pub fn reverse_postorder(&self) -> &[BasicBlock] {
         self.cache.reverse_postorder.get_or_init(|| {
-            let mut rpo: Vec<_> = Postorder::new(&self.basic_blocks, START_BLOCK, ()).collect();
+            let mut rpo: Vec<_> = Postorder::new(&self.basic_blocks, START_BLOCK, None).collect();
             rpo.reverse();
             rpo
         })
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index 71fed4b3e1e..227cb97c76b 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -30,7 +30,6 @@ use rustc_span::{DUMMY_SP, Span, Symbol};
 use tracing::{debug, trace};
 
 pub use self::query::*;
-use self::visit::TyContext;
 use crate::mir::interpret::{AllocRange, Scalar};
 use crate::ty::codec::{TyDecoder, TyEncoder};
 use crate::ty::print::{FmtPrinter, Printer, pretty_print_const, with_no_trimmed_paths};
@@ -98,24 +97,17 @@ impl<'tcx> HasLocalDecls<'tcx> for Body<'tcx> {
 }
 
 impl MirPhase {
-    /// Gets the index of the current MirPhase within the set of all `MirPhase`s.
-    ///
-    /// FIXME(JakobDegen): Return a `(usize, usize)` instead.
-    pub fn phase_index(&self) -> usize {
-        const BUILT_PHASE_COUNT: usize = 1;
-        const ANALYSIS_PHASE_COUNT: usize = 2;
-        match self {
-            MirPhase::Built => 1,
-            MirPhase::Analysis(analysis_phase) => {
-                1 + BUILT_PHASE_COUNT + (*analysis_phase as usize)
-            }
-            MirPhase::Runtime(runtime_phase) => {
-                1 + BUILT_PHASE_COUNT + ANALYSIS_PHASE_COUNT + (*runtime_phase as usize)
-            }
+    /// Gets the (dialect, phase) index of the current `MirPhase`. Both numbers
+    /// are 1-indexed.
+    pub fn index(&self) -> (usize, usize) {
+        match *self {
+            MirPhase::Built => (1, 1),
+            MirPhase::Analysis(analysis_phase) => (2, 1 + analysis_phase as usize),
+            MirPhase::Runtime(runtime_phase) => (3, 1 + runtime_phase as usize),
         }
     }
 
-    /// Parses an `MirPhase` from a pair of strings. Panics if this isn't possible for any reason.
+    /// Parses a `MirPhase` from a pair of strings. Panics if this isn't possible for any reason.
     pub fn parse(dialect: String, phase: Option<String>) -> Self {
         match &*dialect.to_ascii_lowercase() {
             "built" => {
@@ -539,17 +531,6 @@ impl<'tcx> Body<'tcx> {
         }
     }
 
-    pub fn span_for_ty_context(&self, ty_context: TyContext) -> Span {
-        match ty_context {
-            TyContext::UserTy(span) => span,
-            TyContext::ReturnTy(source_info)
-            | TyContext::LocalDecl { source_info, .. }
-            | TyContext::YieldTy(source_info)
-            | TyContext::ResumeTy(source_info) => source_info.span,
-            TyContext::Location(loc) => self.source_info(loc).span,
-        }
-    }
-
     /// Returns the return type; it always return first element from `local_decls` array.
     #[inline]
     pub fn return_ty(&self) -> Ty<'tcx> {
@@ -791,7 +772,7 @@ impl<T> ClearCrossCrate<T> {
         }
     }
 
-    pub fn assert_crate_local(self) -> T {
+    pub fn unwrap_crate_local(self) -> T {
         match self {
             ClearCrossCrate::Clear => bug!("unwrapping cross-crate data"),
             ClearCrossCrate::Set(v) => v,
@@ -948,7 +929,7 @@ mod binding_form_impl {
 /// involved in borrow_check errors, e.g., explanations of where the
 /// temporaries come from, when their destructors are run, and/or how
 /// one might revise the code to satisfy the borrow checker's rules.
-#[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable)]
+#[derive(Clone, Copy, Debug, PartialEq, Eq, TyEncodable, TyDecodable, HashStable)]
 pub struct BlockTailInfo {
     /// If `true`, then the value resulting from evaluating this tail
     /// expression is ignored by the block's expression context.
@@ -972,7 +953,6 @@ pub struct LocalDecl<'tcx> {
     /// Temporaries and the return place are always mutable.
     pub mutability: Mutability,
 
-    // FIXME(matthewjasper) Don't store in this in `Body`
     pub local_info: ClearCrossCrate<Box<LocalInfo<'tcx>>>,
 
     /// The type of this local.
@@ -982,7 +962,6 @@ pub struct LocalDecl<'tcx> {
     /// e.g., via `let x: T`, then we carry that type here. The MIR
     /// borrow checker needs this information since it can affect
     /// region inference.
-    // FIXME(matthewjasper) Don't store in this in `Body`
     pub user_ty: Option<Box<UserTypeProjections>>,
 
     /// The *syntactic* (i.e., not visibility) source scope the local is defined
@@ -1090,7 +1069,6 @@ pub enum LocalInfo<'tcx> {
     AggregateTemp,
     /// A temporary created for evaluation of some subexpression of some block's tail expression
     /// (with no intervening statement context).
-    // FIXME(matthewjasper) Don't store in this in `Body`
     BlockTailTemp(BlockTailInfo),
     /// A temporary created during evaluating `if` predicate, possibly for pattern matching for `let`s,
     /// and subject to Edition 2024 temporary lifetime rules
@@ -1105,7 +1083,7 @@ pub enum LocalInfo<'tcx> {
 
 impl<'tcx> LocalDecl<'tcx> {
     pub fn local_info(&self) -> &LocalInfo<'tcx> {
-        self.local_info.as_ref().assert_crate_local()
+        self.local_info.as_ref().unwrap_crate_local()
     }
 
     /// Returns `true` only if local is a binding that can itself be
diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs
index 1e3b8d029e1..788306a2885 100644
--- a/compiler/rustc_middle/src/mir/pretty.rs
+++ b/compiler/rustc_middle/src/mir/pretty.rs
@@ -22,7 +22,7 @@ pub(crate) const ALIGN: usize = 40;
 
 /// An indication of where we are in the control flow graph. Used for printing
 /// extra information in `dump_mir`
-#[derive(Clone)]
+#[derive(Clone, Copy)]
 pub enum PassWhere {
     /// We have not started dumping the control flow graph, but we are about to.
     BeforeCFG,
@@ -231,7 +231,8 @@ fn dump_path<'tcx>(
     let pass_num = if tcx.sess.opts.unstable_opts.dump_mir_exclude_pass_number {
         String::new()
     } else if pass_num {
-        format!(".{:03}-{:03}", body.phase.phase_index(), body.pass_count)
+        let (dialect_index, phase_index) = body.phase.index();
+        format!(".{}-{}-{:03}", dialect_index, phase_index, body.pass_count)
     } else {
         ".-------".to_string()
     };
diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs
index 389792a04f8..af6f0e4c551 100644
--- a/compiler/rustc_middle/src/mir/syntax.rs
+++ b/compiler/rustc_middle/src/mir/syntax.rs
@@ -23,68 +23,77 @@ use crate::ty::{self, GenericArgsRef, List, Region, Ty, UserTypeAnnotationIndex}
 
 /// Represents the "flavors" of MIR.
 ///
-/// All flavors of MIR use the same data structure, but there are some important differences. These
-/// differences come in two forms: Dialects and phases.
+/// The MIR pipeline is structured into a few major dialects, with one or more phases within each
+/// dialect. A MIR flavor is identified by a dialect-phase pair. A single `MirPhase` value
+/// specifies such a pair. All flavors of MIR use the same data structure to represent the program.
 ///
-/// Dialects represent a stronger distinction than phases. This is because the transitions between
-/// dialects are semantic changes, and therefore technically *lowerings* between distinct IRs. In
-/// other words, the same [`Body`](crate::mir::Body) might be well-formed for multiple dialects, but
-/// have different semantic meaning and different behavior at runtime.
+/// Different MIR dialects have different semantics. (The differences between dialects are small,
+/// but they do exist.) The progression from one MIR dialect to the next is technically a lowering
+/// from one IR to another. In other words, a single well-formed [`Body`](crate::mir::Body) might
+/// have different semantic meaning and different behavior at runtime in the different dialects.
+/// The specific differences between dialects are described on the variants below.
 ///
-/// Each dialect additionally has a number of phases. However, phase changes never involve semantic
-/// changes. If some MIR is well-formed both before and after a phase change, it is also guaranteed
-/// that it has the same semantic meaning. In this sense, phase changes can only add additional
-/// restrictions on what MIR is well-formed.
+/// Phases exist only to place restrictions on what language constructs are permitted in
+/// well-formed MIR, and subsequent phases mostly increase those restrictions. I.e. to convert MIR
+/// from one phase to the next might require removing/replacing certain MIR constructs.
 ///
-/// When adding phases, remember to update [`MirPhase::phase_index`].
+/// When adding dialects or phases, remember to update [`MirPhase::index`].
 #[derive(Copy, Clone, TyEncodable, TyDecodable, Debug, PartialEq, Eq, PartialOrd, Ord)]
 #[derive(HashStable)]
 pub enum MirPhase {
-    /// The MIR that is generated by MIR building.
+    /// The "built MIR" dialect, as generated by MIR building.
     ///
     /// The only things that operate on this dialect are unsafeck, the various MIR lints, and const
     /// qualifs.
     ///
-    /// This has no distinct phases.
+    /// This dialect has just the one (implicit) phase, which places few restrictions on what MIR
+    /// constructs are allowed.
     Built,
-    /// The MIR used for most analysis.
+
+    /// The "analysis MIR" dialect, used for borrowck and friends.
     ///
-    /// The only semantic change between analysis and built MIR is constant promotion. In built MIR,
-    /// sequences of statements that would generally be subject to constant promotion are
-    /// semantically constants, while in analysis MIR all constants are explicit.
+    /// The only semantic difference between built MIR and analysis MIR relates to constant
+    /// promotion. In built MIR, sequences of statements that would generally be subject to
+    /// constant promotion are semantically constants, while in analysis MIR all constants are
+    /// explicit.
     ///
-    /// The result of const promotion is available from the `mir_promoted` and `promoted_mir` queries.
+    /// The result of const promotion is available from the `mir_promoted` and `promoted_mir`
+    /// queries.
     ///
-    /// This is the version of MIR used by borrowck and friends.
+    /// The phases of this dialect are described in `AnalysisPhase`.
     Analysis(AnalysisPhase),
-    /// The MIR used for CTFE, optimizations, and codegen.
-    ///
-    /// The semantic changes that occur in the lowering from analysis to runtime MIR are as follows:
-    ///
-    ///  - Drops: In analysis MIR, `Drop` terminators represent *conditional* drops; roughly speaking,
-    ///    if dataflow analysis determines that the place being dropped is uninitialized, the drop will
-    ///    not be executed. The exact semantics of this aren't written down anywhere, which means they
-    ///    are essentially "what drop elaboration does." In runtime MIR, the drops are unconditional;
-    ///    when a `Drop` terminator is reached, if the type has drop glue that drop glue is always
-    ///    executed. This may be UB if the underlying place is not initialized.
-    ///  - Packed drops: Places might in general be misaligned - in most cases this is UB, the exception
-    ///    is fields of packed structs. In analysis MIR, `Drop(P)` for a `P` that might be misaligned
-    ///    for this reason implicitly moves `P` to a temporary before dropping. Runtime MIR has no such
-    ///    rules, and dropping a misaligned place is simply UB.
-    ///  - Unwinding: in analysis MIR, unwinding from a function which may not unwind aborts. In runtime
-    ///    MIR, this is UB.
-    ///  - Retags: If `-Zmir-emit-retag` is enabled, analysis MIR has "implicit" retags in the same way
-    ///    that Rust itself has them. Where exactly these are is generally subject to change, and so we
-    ///    don't document this here. Runtime MIR has most retags explicit (though implicit retags
-    ///    can still occur at `Rvalue::{Ref,AddrOf}`).
-    ///  - Coroutine bodies: In analysis MIR, locals may actually be behind a pointer that user code has
-    ///    access to. This occurs in coroutine bodies. Such locals do not behave like other locals,
-    ///    because they eg may be aliased in surprising ways. Runtime MIR has no such special locals -
-    ///    all coroutine bodies are lowered and so all places that look like locals really are locals.
+
+    /// The "runtime MIR" dialect, used for CTFE, optimizations, and codegen.
+    ///
+    /// The semantic differences between analysis MIR and runtime MIR are as follows.
+    ///
+    /// - Drops: In analysis MIR, `Drop` terminators represent *conditional* drops; roughly
+    ///   speaking, if dataflow analysis determines that the place being dropped is uninitialized,
+    ///   the drop will not be executed. The exact semantics of this aren't written down anywhere,
+    ///   which means they are essentially "what drop elaboration does." In runtime MIR, the drops
+    ///   are unconditional; when a `Drop` terminator is reached, if the type has drop glue that
+    ///   drop glue is always executed. This may be UB if the underlying place is not initialized.
+    /// - Packed drops: Places might in general be misaligned - in most cases this is UB, the
+    ///   exception is fields of packed structs. In analysis MIR, `Drop(P)` for a `P` that might be
+    ///   misaligned for this reason implicitly moves `P` to a temporary before dropping. Runtime
+    ///   MIR has no such rules, and dropping a misaligned place is simply UB.
+    /// - Unwinding: in analysis MIR, unwinding from a function which may not unwind aborts. In
+    ///   runtime MIR, this is UB.
+    /// - Retags: If `-Zmir-emit-retag` is enabled, analysis MIR has "implicit" retags in the same
+    ///   way that Rust itself has them. Where exactly these are is generally subject to change,
+    ///   and so we don't document this here. Runtime MIR has most retags explicit (though implicit
+    ///   retags can still occur at `Rvalue::{Ref,AddrOf}`).
+    /// - Coroutine bodies: In analysis MIR, locals may actually be behind a pointer that user code
+    ///   has access to. This occurs in coroutine bodies. Such locals do not behave like other
+    ///   locals, because they e.g. may be aliased in surprising ways. Runtime MIR has no such
+    ///   special locals. All coroutine bodies are lowered and so all places that look like locals
+    ///   really are locals.
     ///
     /// Also note that the lint pass which reports eg `200_u8 + 200_u8` as an error is run as a part
     /// of analysis to runtime MIR lowering. To ensure lints are reported reliably, this means that
-    /// transformations which may suppress such errors should not run on analysis MIR.
+    /// transformations that can suppress such errors should not run on analysis MIR.
+    ///
+    /// The phases of this dialect are described in `RuntimePhase`.
     Runtime(RuntimePhase),
 }
 
@@ -111,7 +120,8 @@ pub enum AnalysisPhase {
     /// * [`TerminatorKind::FalseEdge`]
     /// * [`StatementKind::FakeRead`]
     /// * [`StatementKind::AscribeUserType`]
-    /// * [`StatementKind::Coverage`] with [`CoverageKind::BlockMarker`] or [`CoverageKind::SpanMarker`]
+    /// * [`StatementKind::Coverage`] with [`CoverageKind::BlockMarker`] or
+    ///   [`CoverageKind::SpanMarker`]
     /// * [`Rvalue::Ref`] with `BorrowKind::Fake`
     /// * [`CastKind::PointerCoercion`] with any of the following:
     ///   * [`PointerCoercion::ArrayToPointer`]
diff --git a/compiler/rustc_middle/src/mir/terminator.rs b/compiler/rustc_middle/src/mir/terminator.rs
index 9357e19f7c5..49e0f619b1e 100644
--- a/compiler/rustc_middle/src/mir/terminator.rs
+++ b/compiler/rustc_middle/src/mir/terminator.rs
@@ -86,7 +86,7 @@ impl SwitchTargets {
         self.iter().find_map(|(v, t)| (v == value).then_some(t)).unwrap_or_else(|| self.otherwise())
     }
 
-    /// Adds a new target to the switch. But You cannot add an already present value.
+    /// Adds a new target to the switch. Panics if you add an already present value.
     #[inline]
     pub fn add_target(&mut self, value: u128, bb: BasicBlock) {
         let value = Pu128(value);
diff --git a/compiler/rustc_middle/src/mir/traversal.rs b/compiler/rustc_middle/src/mir/traversal.rs
index 0e7dcc24daf..5950ac295af 100644
--- a/compiler/rustc_middle/src/mir/traversal.rs
+++ b/compiler/rustc_middle/src/mir/traversal.rs
@@ -104,23 +104,21 @@ impl<'a, 'tcx> Iterator for Preorder<'a, 'tcx> {
 /// ```
 ///
 /// A Postorder traversal of this graph is `D B C A` or `D C B A`
-pub struct Postorder<'a, 'tcx, C> {
+pub struct Postorder<'a, 'tcx> {
     basic_blocks: &'a IndexSlice<BasicBlock, BasicBlockData<'tcx>>,
     visited: DenseBitSet<BasicBlock>,
     visit_stack: Vec<(BasicBlock, Successors<'a>)>,
     root_is_start_block: bool,
-    extra: C,
+    /// A non-empty `extra` allows for a precise calculation of the successors.
+    extra: Option<(TyCtxt<'tcx>, Instance<'tcx>)>,
 }
 
-impl<'a, 'tcx, C> Postorder<'a, 'tcx, C>
-where
-    C: Customization<'tcx>,
-{
+impl<'a, 'tcx> Postorder<'a, 'tcx> {
     pub fn new(
         basic_blocks: &'a IndexSlice<BasicBlock, BasicBlockData<'tcx>>,
         root: BasicBlock,
-        extra: C,
-    ) -> Postorder<'a, 'tcx, C> {
+        extra: Option<(TyCtxt<'tcx>, Instance<'tcx>)>,
+    ) -> Postorder<'a, 'tcx> {
         let mut po = Postorder {
             basic_blocks,
             visited: DenseBitSet::new_empty(basic_blocks.len()),
@@ -140,7 +138,11 @@ where
             return;
         }
         let data = &self.basic_blocks[bb];
-        let successors = C::successors(data, self.extra);
+        let successors = if let Some(extra) = self.extra {
+            data.mono_successors(extra.0, extra.1)
+        } else {
+            data.terminator().successors()
+        };
         self.visit_stack.push((bb, successors));
     }
 
@@ -198,10 +200,7 @@ where
     }
 }
 
-impl<'tcx, C> Iterator for Postorder<'_, 'tcx, C>
-where
-    C: Customization<'tcx>,
-{
+impl<'tcx> Iterator for Postorder<'_, 'tcx> {
     type Item = BasicBlock;
 
     fn next(&mut self) -> Option<BasicBlock> {
@@ -241,32 +240,12 @@ pub fn postorder<'a, 'tcx>(
     reverse_postorder(body).rev()
 }
 
-/// Lets us plug in some additional logic and data into a Postorder traversal. Or not.
-pub trait Customization<'tcx>: Copy {
-    fn successors<'a>(_: &'a BasicBlockData<'tcx>, _: Self) -> Successors<'a>;
-}
-
-impl<'tcx> Customization<'tcx> for () {
-    fn successors<'a>(data: &'a BasicBlockData<'tcx>, _: ()) -> Successors<'a> {
-        data.terminator().successors()
-    }
-}
-
-impl<'tcx> Customization<'tcx> for (TyCtxt<'tcx>, Instance<'tcx>) {
-    fn successors<'a>(
-        data: &'a BasicBlockData<'tcx>,
-        (tcx, instance): (TyCtxt<'tcx>, Instance<'tcx>),
-    ) -> Successors<'a> {
-        data.mono_successors(tcx, instance)
-    }
-}
-
 pub fn mono_reachable_reverse_postorder<'a, 'tcx>(
     body: &'a Body<'tcx>,
     tcx: TyCtxt<'tcx>,
     instance: Instance<'tcx>,
 ) -> Vec<BasicBlock> {
-    let mut iter = Postorder::new(&body.basic_blocks, START_BLOCK, (tcx, instance));
+    let mut iter = Postorder::new(&body.basic_blocks, START_BLOCK, Some((tcx, instance)));
     let mut items = Vec::with_capacity(body.basic_blocks.len());
     while let Some(block) = iter.next() {
         items.push(block);
diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs
index f039da772fd..53bc9eb7e46 100644
--- a/compiler/rustc_middle/src/traits/mod.rs
+++ b/compiler/rustc_middle/src/traits/mod.rs
@@ -51,7 +51,7 @@ pub struct ObligationCause<'tcx> {
     /// information.
     pub body_id: LocalDefId,
 
-    code: InternedObligationCauseCode<'tcx>,
+    code: ObligationCauseCodeHandle<'tcx>,
 }
 
 // This custom hash function speeds up hashing for `Obligation` deduplication
@@ -97,7 +97,7 @@ impl<'tcx> ObligationCause<'tcx> {
 
     pub fn map_code(
         &mut self,
-        f: impl FnOnce(InternedObligationCauseCode<'tcx>) -> ObligationCauseCode<'tcx>,
+        f: impl FnOnce(ObligationCauseCodeHandle<'tcx>) -> ObligationCauseCode<'tcx>,
     ) {
         self.code = f(std::mem::take(&mut self.code)).into();
     }
@@ -152,15 +152,16 @@ pub struct UnifyReceiverContext<'tcx> {
     pub args: GenericArgsRef<'tcx>,
 }
 
+/// A compact form of `ObligationCauseCode`.
 #[derive(Clone, PartialEq, Eq, Default, HashStable)]
 #[derive(TypeVisitable, TypeFoldable, TyEncodable, TyDecodable)]
-pub struct InternedObligationCauseCode<'tcx> {
+pub struct ObligationCauseCodeHandle<'tcx> {
     /// `None` for `ObligationCauseCode::Misc` (a common case, occurs ~60% of
     /// the time). `Some` otherwise.
     code: Option<Arc<ObligationCauseCode<'tcx>>>,
 }
 
-impl<'tcx> std::fmt::Debug for InternedObligationCauseCode<'tcx> {
+impl<'tcx> std::fmt::Debug for ObligationCauseCodeHandle<'tcx> {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         let cause: &ObligationCauseCode<'_> = self;
         cause.fmt(f)
@@ -169,14 +170,14 @@ impl<'tcx> std::fmt::Debug for InternedObligationCauseCode<'tcx> {
 
 impl<'tcx> ObligationCauseCode<'tcx> {
     #[inline(always)]
-    fn into(self) -> InternedObligationCauseCode<'tcx> {
-        InternedObligationCauseCode {
+    fn into(self) -> ObligationCauseCodeHandle<'tcx> {
+        ObligationCauseCodeHandle {
             code: if let ObligationCauseCode::Misc = self { None } else { Some(Arc::new(self)) },
         }
     }
 }
 
-impl<'tcx> std::ops::Deref for InternedObligationCauseCode<'tcx> {
+impl<'tcx> std::ops::Deref for ObligationCauseCodeHandle<'tcx> {
     type Target = ObligationCauseCode<'tcx>;
 
     fn deref(&self) -> &Self::Target {
@@ -305,7 +306,7 @@ pub enum ObligationCauseCode<'tcx> {
         /// The node of the function call.
         call_hir_id: HirId,
         /// The obligation introduced by this argument.
-        parent_code: InternedObligationCauseCode<'tcx>,
+        parent_code: ObligationCauseCodeHandle<'tcx>,
     },
 
     /// Error derived when checking an impl item is compatible with
@@ -390,7 +391,8 @@ pub enum ObligationCauseCode<'tcx> {
     /// `WellFormed(None)`.
     WellFormed(Option<WellFormedLoc>),
 
-    /// From `match_impl`. The cause for us having to match an impl, and the DefId we are matching against.
+    /// From `match_impl`. The cause for us having to match an impl, and the DefId we are matching
+    /// against.
     MatchImpl(ObligationCause<'tcx>, DefId),
 
     BinOp {
@@ -413,7 +415,7 @@ pub enum ObligationCauseCode<'tcx> {
     ConstParam(Ty<'tcx>),
 
     /// Obligations emitted during the normalization of a weak type alias.
-    TypeAlias(InternedObligationCauseCode<'tcx>, Span, DefId),
+    TypeAlias(ObligationCauseCodeHandle<'tcx>, Span, DefId),
 }
 
 /// Whether a value can be extracted into a const.
@@ -514,12 +516,6 @@ impl<'tcx> ObligationCauseCode<'tcx> {
 #[cfg(target_pointer_width = "64")]
 rustc_data_structures::static_assert_size!(ObligationCauseCode<'_>, 48);
 
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
-pub enum StatementAsExpression {
-    CorrectType,
-    NeedsBoxing,
-}
-
 #[derive(Clone, Debug, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
 #[derive(TypeVisitable, TypeFoldable)]
 pub struct MatchExpressionArmCause<'tcx> {
@@ -584,7 +580,7 @@ pub struct DerivedCause<'tcx> {
     pub parent_trait_pred: ty::PolyTraitPredicate<'tcx>,
 
     /// The parent trait had this cause.
-    pub parent_code: InternedObligationCauseCode<'tcx>,
+    pub parent_code: ObligationCauseCodeHandle<'tcx>,
 }
 
 #[derive(Clone, Debug, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
@@ -592,9 +588,9 @@ pub struct DerivedCause<'tcx> {
 pub struct ImplDerivedCause<'tcx> {
     pub derived: DerivedCause<'tcx>,
     /// The `DefId` of the `impl` that gave rise to the `derived` obligation.
-    /// If the `derived` obligation arose from a trait alias, which conceptually has a synthetic impl,
-    /// then this will be the `DefId` of that trait alias. Care should therefore be taken to handle
-    /// that exceptional case where appropriate.
+    /// If the `derived` obligation arose from a trait alias, which conceptually has a synthetic
+    /// impl, then this will be the `DefId` of that trait alias. Care should therefore be taken to
+    /// handle that exceptional case where appropriate.
     pub impl_or_alias_def_id: DefId,
     /// The index of the derived predicate in the parent impl's predicates.
     pub impl_def_predicate_index: Option<usize>,
@@ -611,7 +607,7 @@ pub struct DerivedHostCause<'tcx> {
     pub parent_host_pred: ty::Binder<'tcx, ty::HostEffectPredicate<'tcx>>,
 
     /// The parent trait had this cause.
-    pub parent_code: InternedObligationCauseCode<'tcx>,
+    pub parent_code: ObligationCauseCodeHandle<'tcx>,
 }
 
 #[derive(Clone, Debug, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
diff --git a/compiler/rustc_middle/src/traits/query.rs b/compiler/rustc_middle/src/traits/query.rs
index 4203c8fd861..76f3d2bab9c 100644
--- a/compiler/rustc_middle/src/traits/query.rs
+++ b/compiler/rustc_middle/src/traits/query.rs
@@ -75,12 +75,6 @@ pub type CanonicalPredicateGoal<'tcx> =
 pub type CanonicalTypeOpAscribeUserTypeGoal<'tcx> =
     CanonicalQueryInput<'tcx, ty::ParamEnvAnd<'tcx, type_op::AscribeUserType<'tcx>>>;
 
-pub type CanonicalTypeOpEqGoal<'tcx> =
-    CanonicalQueryInput<'tcx, ty::ParamEnvAnd<'tcx, type_op::Eq<'tcx>>>;
-
-pub type CanonicalTypeOpSubtypeGoal<'tcx> =
-    CanonicalQueryInput<'tcx, ty::ParamEnvAnd<'tcx, type_op::Subtype<'tcx>>>;
-
 pub type CanonicalTypeOpProvePredicateGoal<'tcx> =
     CanonicalQueryInput<'tcx, ty::ParamEnvAnd<'tcx, type_op::ProvePredicate<'tcx>>>;