about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock1
-rw-r--r--compiler/rustc_next_trait_solver/Cargo.toml2
-rw-r--r--compiler/rustc_next_trait_solver/src/lib.rs2
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs62
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs41
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/search_graph.rs17
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/trait_goals.rs4
-rw-r--r--compiler/rustc_type_ir/Cargo.toml3
-rw-r--r--compiler/rustc_type_ir/src/binder.rs6
-rw-r--r--compiler/rustc_type_ir/src/data_structures.rs29
-rw-r--r--compiler/rustc_type_ir/src/error.rs2
-rw-r--r--compiler/rustc_type_ir/src/fold.rs3
-rw-r--r--compiler/rustc_type_ir/src/generic_arg.rs1
-rw-r--r--compiler/rustc_type_ir/src/inherent.rs4
-rw-r--r--compiler/rustc_type_ir/src/lib.rs10
-rw-r--r--compiler/rustc_type_ir/src/opaque_ty.rs1
-rw-r--r--compiler/rustc_type_ir/src/relate.rs9
-rw-r--r--compiler/rustc_type_ir/src/visit.rs3
18 files changed, 124 insertions, 76 deletions
diff --git a/Cargo.lock b/Cargo.lock
index da99ac9b8af..74754e98993 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -4905,6 +4905,7 @@ version = "0.0.0"
 dependencies = [
  "bitflags 2.5.0",
  "derivative",
+ "indexmap",
  "rustc_ast_ir",
  "rustc_data_structures",
  "rustc_index",
diff --git a/compiler/rustc_next_trait_solver/Cargo.toml b/compiler/rustc_next_trait_solver/Cargo.toml
index 3a5f438b432..07cd4ae68d9 100644
--- a/compiler/rustc_next_trait_solver/Cargo.toml
+++ b/compiler/rustc_next_trait_solver/Cargo.toml
@@ -7,7 +7,7 @@ edition = "2021"
 # tidy-alphabetical-start
 bitflags = "2.4.1"
 derivative = "2.2.0"
-rustc_ast_ir = { path = "../rustc_ast_ir" }
+rustc_ast_ir = { path = "../rustc_ast_ir", default-features = false }
 rustc_data_structures = { path = "../rustc_data_structures", optional = true }
 rustc_index = { path = "../rustc_index", default-features = false }
 rustc_macros = { path = "../rustc_macros", optional = true }
diff --git a/compiler/rustc_next_trait_solver/src/lib.rs b/compiler/rustc_next_trait_solver/src/lib.rs
index 79c6925221e..ea3e18872fa 100644
--- a/compiler/rustc_next_trait_solver/src/lib.rs
+++ b/compiler/rustc_next_trait_solver/src/lib.rs
@@ -4,8 +4,6 @@
 //! but were uplifted in the process of making the new trait solver generic.
 //! So if you got to this crate from the old solver, it's totally normal.
 
-#![feature(let_chains)]
-
 pub mod canonicalizer;
 pub mod infcx;
 pub mod resolve;
diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs
index 202af76565a..dbe3dfd4a1b 100644
--- a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs
@@ -2,7 +2,7 @@
 //! traits, `Copy`/`Clone`.
 
 use rustc_ast_ir::{Movability, Mutability};
-use rustc_data_structures::fx::FxHashMap;
+use rustc_type_ir::data_structures::HashMap;
 use rustc_type_ir::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
 use rustc_type_ir::inherent::*;
 use rustc_type_ir::lang_items::TraitSolverLangItem;
@@ -304,9 +304,10 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_callable<I: Intern
             let kind_ty = args.kind_ty();
             let sig = args.coroutine_closure_sig().skip_binder();
 
-            let coroutine_ty = if let Some(closure_kind) = kind_ty.to_opt_closure_kind()
-                && !args.tupled_upvars_ty().is_ty_var()
-            {
+            // FIXME: let_chains
+            let kind = kind_ty.to_opt_closure_kind();
+            let coroutine_ty = if kind.is_some() && !args.tupled_upvars_ty().is_ty_var() {
+                let closure_kind = kind.unwrap();
                 if !closure_kind.extends(goal_kind) {
                     return Err(NoSolution);
                 }
@@ -411,10 +412,11 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<I:
             let kind_ty = args.kind_ty();
             let sig = args.coroutine_closure_sig().skip_binder();
             let mut nested = vec![];
-            let coroutine_ty = if let Some(closure_kind) = kind_ty.to_opt_closure_kind()
-                && !args.tupled_upvars_ty().is_ty_var()
-            {
-                if !closure_kind.extends(goal_kind) {
+
+            // FIXME: let_chains
+            let kind = kind_ty.to_opt_closure_kind();
+            let coroutine_ty = if kind.is_some() && !args.tupled_upvars_ty().is_ty_var() {
+                if !kind.unwrap().extends(goal_kind) {
                     return Err(NoSolution);
                 }
 
@@ -683,7 +685,7 @@ where
         );
     }
 
-    let mut replace_projection_with = FxHashMap::default();
+    let mut replace_projection_with = HashMap::default();
     for bound in object_bounds {
         if let ty::ExistentialPredicate::Projection(proj) = bound.skip_binder() {
             let proj = proj.with_self_ty(tcx, trait_ref.self_ty());
@@ -713,7 +715,7 @@ where
 struct ReplaceProjectionWith<'a, Infcx: SolverDelegate<Interner = I>, I: Interner> {
     ecx: &'a EvalCtxt<'a, Infcx>,
     param_env: I::ParamEnv,
-    mapping: FxHashMap<I::DefId, ty::Binder<I, ty::ProjectionPredicate<I>>>,
+    mapping: HashMap<I::DefId, ty::Binder<I, ty::ProjectionPredicate<I>>>,
     nested: Vec<Goal<I, I::Predicate>>,
 }
 
@@ -725,24 +727,28 @@ impl<Infcx: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I>
     }
 
     fn fold_ty(&mut self, ty: I::Ty) -> I::Ty {
-        if let ty::Alias(ty::Projection, alias_ty) = ty.kind()
-            && let Some(replacement) = self.mapping.get(&alias_ty.def_id)
-        {
-            // We may have a case where our object type's projection bound is higher-ranked,
-            // but the where clauses we instantiated are not. We can solve this by instantiating
-            // the binder at the usage site.
-            let proj = self.ecx.instantiate_binder_with_infer(*replacement);
-            // FIXME: Technically this equate could be fallible...
-            self.nested.extend(
-                self.ecx
-                    .eq_and_get_goals(
-                        self.param_env,
-                        alias_ty,
-                        proj.projection_term.expect_ty(self.ecx.interner()),
-                    )
-                    .expect("expected to be able to unify goal projection with dyn's projection"),
-            );
-            proj.term.expect_ty()
+        if let ty::Alias(ty::Projection, alias_ty) = ty.kind() {
+            if let Some(replacement) = self.mapping.get(&alias_ty.def_id) {
+                // We may have a case where our object type's projection bound is higher-ranked,
+                // but the where clauses we instantiated are not. We can solve this by instantiating
+                // the binder at the usage site.
+                let proj = self.ecx.instantiate_binder_with_infer(*replacement);
+                // FIXME: Technically this equate could be fallible...
+                self.nested.extend(
+                    self.ecx
+                        .eq_and_get_goals(
+                            self.param_env,
+                            alias_ty,
+                            proj.projection_term.expect_ty(self.ecx.interner()),
+                        )
+                        .expect(
+                            "expected to be able to unify goal projection with dyn's projection",
+                        ),
+                );
+                proj.term.expect_ty()
+            } else {
+                ty.super_fold_with(self)
+            }
         } else {
             ty.super_fold_with(self)
         }
diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
index 485758b91a2..8548c647b6b 100644
--- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
@@ -1,7 +1,8 @@
 use std::ops::ControlFlow;
 
-use rustc_data_structures::stack::ensure_sufficient_stack;
+#[cfg(feature = "nightly")]
 use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable};
+use rustc_type_ir::data_structures::ensure_sufficient_stack;
 use rustc_type_ir::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
 use rustc_type_ir::inherent::*;
 use rustc_type_ir::relate::Relate;
@@ -88,7 +89,7 @@ where
 #[derive(derivative::Derivative)]
 #[derivative(Clone(bound = ""), Debug(bound = ""), Default(bound = ""))]
 #[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
-#[derive(TyDecodable, TyEncodable, HashStable_NoContext)]
+#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))]
 // FIXME: This can be made crate-private once `EvalCtxt` also lives in this crate.
 pub struct NestedGoals<I: Interner> {
     /// These normalizes-to goals are treated specially during the evaluation
@@ -116,7 +117,8 @@ impl<I: Interner> NestedGoals<I> {
     }
 }
 
-#[derive(PartialEq, Eq, Debug, Hash, HashStable_NoContext, Clone, Copy)]
+#[derive(PartialEq, Eq, Debug, Hash, Clone, Copy)]
+#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))]
 pub enum GenerateProofTree {
     Yes,
     No,
@@ -689,14 +691,15 @@ where
             fn visit_ty(&mut self, t: I::Ty) -> Self::Result {
                 match t.kind() {
                     ty::Infer(ty::TyVar(vid)) => {
-                        if let ty::TermKind::Ty(term) = self.term.kind()
-                            && let ty::Infer(ty::TyVar(term_vid)) = term.kind()
-                            && self.infcx.root_ty_var(vid) == self.infcx.root_ty_var(term_vid)
-                        {
-                            ControlFlow::Break(())
-                        } else {
-                            self.check_nameable(self.infcx.universe_of_ty(vid).unwrap())
+                        if let ty::TermKind::Ty(term) = self.term.kind() {
+                            if let ty::Infer(ty::TyVar(term_vid)) = term.kind() {
+                                if self.infcx.root_ty_var(vid) == self.infcx.root_ty_var(term_vid) {
+                                    return ControlFlow::Break(());
+                                }
+                            }
                         }
+
+                        self.check_nameable(self.infcx.universe_of_ty(vid).unwrap())
                     }
                     ty::Placeholder(p) => self.check_nameable(p.universe()),
                     _ => {
@@ -712,14 +715,18 @@ where
             fn visit_const(&mut self, c: I::Const) -> Self::Result {
                 match c.kind() {
                     ty::ConstKind::Infer(ty::InferConst::Var(vid)) => {
-                        if let ty::TermKind::Const(term) = self.term.kind()
-                            && let ty::ConstKind::Infer(ty::InferConst::Var(term_vid)) = term.kind()
-                            && self.infcx.root_const_var(vid) == self.infcx.root_const_var(term_vid)
-                        {
-                            ControlFlow::Break(())
-                        } else {
-                            self.check_nameable(self.infcx.universe_of_ct(vid).unwrap())
+                        if let ty::TermKind::Const(term) = self.term.kind() {
+                            if let ty::ConstKind::Infer(ty::InferConst::Var(term_vid)) = term.kind()
+                            {
+                                if self.infcx.root_const_var(vid)
+                                    == self.infcx.root_const_var(term_vid)
+                                {
+                                    return ControlFlow::Break(());
+                                }
+                            }
                         }
+
+                        self.check_nameable(self.infcx.universe_of_ct(vid).unwrap())
                     }
                     ty::ConstKind::Placeholder(p) => self.check_nameable(p.universe()),
                     _ => {
diff --git a/compiler/rustc_next_trait_solver/src/solve/search_graph.rs b/compiler/rustc_next_trait_solver/src/solve/search_graph.rs
index b923a121d81..fc78a864f81 100644
--- a/compiler/rustc_next_trait_solver/src/solve/search_graph.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/search_graph.rs
@@ -1,7 +1,7 @@
 use std::mem;
 
-use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_index::{Idx, IndexVec};
+use rustc_type_ir::data_structures::{HashMap, HashSet};
 use rustc_type_ir::inherent::*;
 use rustc_type_ir::Interner;
 use tracing::debug;
@@ -17,6 +17,7 @@ pub struct SolverLimit(usize);
 
 rustc_index::newtype_index! {
     #[orderable]
+    #[gate_rustc_only]
     pub struct StackDepth {}
 }
 
@@ -70,7 +71,7 @@ struct StackEntry<I: Interner> {
     /// C :- D
     /// D :- C
     /// ```
-    cycle_participants: FxHashSet<CanonicalInput<I>>,
+    cycle_participants: HashSet<CanonicalInput<I>>,
     /// Starts out as `None` and gets set when rerunning this
     /// goal in case we encounter a cycle.
     provisional_result: Option<QueryResult<I>>,
@@ -126,7 +127,7 @@ pub(super) struct SearchGraph<I: Interner> {
     ///
     /// An element is *deeper* in the stack if its index is *lower*.
     stack: IndexVec<StackDepth, StackEntry<I>>,
-    provisional_cache: FxHashMap<CanonicalInput<I>, ProvisionalCacheEntry<I>>,
+    provisional_cache: HashMap<CanonicalInput<I>, ProvisionalCacheEntry<I>>,
 }
 
 impl<I: Interner> SearchGraph<I> {
@@ -227,13 +228,17 @@ impl<I: Interner> SearchGraph<I> {
     }
 
     fn clear_dependent_provisional_results(
-        provisional_cache: &mut FxHashMap<CanonicalInput<I>, ProvisionalCacheEntry<I>>,
+        provisional_cache: &mut HashMap<CanonicalInput<I>, ProvisionalCacheEntry<I>>,
         head: StackDepth,
     ) {
         #[allow(rustc::potential_query_instability)]
         provisional_cache.retain(|_, entry| {
-            entry.with_coinductive_stack.take_if(|p| p.head == head);
-            entry.with_inductive_stack.take_if(|p| p.head == head);
+            if entry.with_coinductive_stack.as_ref().is_some_and(|p| p.head == head) {
+                entry.with_coinductive_stack.take();
+            }
+            if entry.with_inductive_stack.as_ref().is_some_and(|p| p.head == head) {
+                entry.with_inductive_stack.take();
+            }
             !entry.is_empty()
         });
     }
diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
index d1419bf5db9..c0353f92bf8 100644
--- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
@@ -1,7 +1,7 @@
 //! Dealing with trait goals, i.e. `T: Trait<'a, U>`.
 
 use rustc_ast_ir::Movability;
-use rustc_data_structures::fx::FxIndexSet;
+use rustc_type_ir::data_structures::IndexSet;
 use rustc_type_ir::inherent::*;
 use rustc_type_ir::lang_items::TraitSolverLangItem;
 use rustc_type_ir::visit::TypeVisitableExt as _;
@@ -821,7 +821,7 @@ where
         // We may upcast to auto traits that are either explicitly listed in
         // the object type's bounds, or implied by the principal trait ref's
         // supertraits.
-        let a_auto_traits: FxIndexSet<I::DefId> = a_data
+        let a_auto_traits: IndexSet<I::DefId> = a_data
             .auto_traits()
             .into_iter()
             .chain(a_data.principal_def_id().into_iter().flat_map(|principal_def_id| {
diff --git a/compiler/rustc_type_ir/Cargo.toml b/compiler/rustc_type_ir/Cargo.toml
index 18a09067a2c..e4bf6069caf 100644
--- a/compiler/rustc_type_ir/Cargo.toml
+++ b/compiler/rustc_type_ir/Cargo.toml
@@ -7,7 +7,8 @@ edition = "2021"
 # tidy-alphabetical-start
 bitflags = "2.4.1"
 derivative = "2.2.0"
-rustc_ast_ir = { path = "../rustc_ast_ir" }
+indexmap = "2.0.0"
+rustc_ast_ir = { path = "../rustc_ast_ir", default-features = false }
 rustc_data_structures = { path = "../rustc_data_structures", optional = true }
 rustc_index = { path = "../rustc_index", default-features = false }
 rustc_macros = { path = "../rustc_macros", optional = true }
diff --git a/compiler/rustc_type_ir/src/binder.rs b/compiler/rustc_type_ir/src/binder.rs
index 5042a38fdb8..59de7c552af 100644
--- a/compiler/rustc_type_ir/src/binder.rs
+++ b/compiler/rustc_type_ir/src/binder.rs
@@ -5,14 +5,16 @@ use std::ops::{ControlFlow, Deref};
 
 #[cfg(feature = "nightly")]
 use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable};
+#[cfg(feature = "nightly")]
 use rustc_serialize::Decodable;
 use tracing::debug;
 
+use crate::data_structures::SsoHashSet;
 use crate::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder, TypeSuperFoldable};
 use crate::inherent::*;
 use crate::lift::Lift;
 use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor};
-use crate::{self as ty, Interner, SsoHashSet};
+use crate::{self as ty, Interner};
 
 /// Binder is a binder for higher-ranked lifetimes or types. It is part of the
 /// compiler's representation for things like `for<'a> Fn(&'a isize)`
@@ -55,6 +57,7 @@ where
     }
 }
 
+#[cfg(feature = "nightly")]
 macro_rules! impl_binder_encode_decode {
     ($($t:ty),+ $(,)?) => {
         $(
@@ -82,6 +85,7 @@ macro_rules! impl_binder_encode_decode {
     }
 }
 
+#[cfg(feature = "nightly")]
 impl_binder_encode_decode! {
     ty::FnSig<I>,
     ty::TraitPredicate<I>,
diff --git a/compiler/rustc_type_ir/src/data_structures.rs b/compiler/rustc_type_ir/src/data_structures.rs
new file mode 100644
index 00000000000..6d8ab61b722
--- /dev/null
+++ b/compiler/rustc_type_ir/src/data_structures.rs
@@ -0,0 +1,29 @@
+#[cfg(feature = "nightly")]
+mod impl_ {
+    pub use rustc_data_structures::fx::FxHashMap as HashMap;
+    pub use rustc_data_structures::fx::FxHashSet as HashSet;
+    pub use rustc_data_structures::fx::FxIndexMap as IndexMap;
+    pub use rustc_data_structures::fx::FxIndexSet as IndexSet;
+    pub use rustc_data_structures::sso::SsoHashMap;
+    pub use rustc_data_structures::sso::SsoHashSet;
+    pub use rustc_data_structures::stack::ensure_sufficient_stack;
+    pub use rustc_data_structures::sync::Lrc;
+}
+
+#[cfg(not(feature = "nightly"))]
+mod impl_ {
+    pub use indexmap::IndexMap;
+    pub use indexmap::IndexSet;
+    pub use std::collections::HashMap;
+    pub use std::collections::HashMap as SsoHashMap;
+    pub use std::collections::HashSet;
+    pub use std::collections::HashSet as SsoHashSet;
+    pub use std::sync::Arc as Lrc;
+
+    #[inline]
+    pub fn ensure_sufficient_stack<R>(f: impl FnOnce() -> R) -> R {
+        f()
+    }
+}
+
+pub use impl_::*;
diff --git a/compiler/rustc_type_ir/src/error.rs b/compiler/rustc_type_ir/src/error.rs
index 27623ea9cac..8b59e9a6f48 100644
--- a/compiler/rustc_type_ir/src/error.rs
+++ b/compiler/rustc_type_ir/src/error.rs
@@ -30,7 +30,7 @@ impl<T> ExpectedFound<T> {
     Debug(bound = "")
 )]
 #[derive(TypeVisitable_Generic)]
-#[rustc_pass_by_value]
+#[cfg_attr(feature = "nightly", rustc_pass_by_value)]
 pub enum TypeError<I: Interner> {
     Mismatch,
     ConstnessMismatch(ExpectedFound<ty::BoundConstness>),
diff --git a/compiler/rustc_type_ir/src/fold.rs b/compiler/rustc_type_ir/src/fold.rs
index ee3e5ce66d0..26e365f64fa 100644
--- a/compiler/rustc_type_ir/src/fold.rs
+++ b/compiler/rustc_type_ir/src/fold.rs
@@ -49,9 +49,10 @@ use rustc_index::{Idx, IndexVec};
 use std::mem;
 use tracing::debug;
 
+use crate::data_structures::Lrc;
 use crate::inherent::*;
 use crate::visit::{TypeVisitable, TypeVisitableExt as _};
-use crate::{self as ty, Interner, Lrc};
+use crate::{self as ty, Interner};
 
 #[cfg(feature = "nightly")]
 type Never = !;
diff --git a/compiler/rustc_type_ir/src/generic_arg.rs b/compiler/rustc_type_ir/src/generic_arg.rs
index cc8c4444657..b158f0f5eee 100644
--- a/compiler/rustc_type_ir/src/generic_arg.rs
+++ b/compiler/rustc_type_ir/src/generic_arg.rs
@@ -1,3 +1,4 @@
+#[cfg(feature = "nightly")]
 use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable};
 
 use crate::Interner;
diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs
index 64d3400976a..be6deee011b 100644
--- a/compiler/rustc_type_ir/src/inherent.rs
+++ b/compiler/rustc_type_ir/src/inherent.rs
@@ -8,8 +8,8 @@ use std::hash::Hash;
 use std::ops::Deref;
 
 use rustc_ast_ir::Mutability;
-use rustc_data_structures::fx::FxHashSet;
 
+use crate::data_structures::HashSet;
 use crate::fold::{TypeFoldable, TypeSuperFoldable};
 use crate::relate::Relate;
 use crate::solve::{CacheData, CanonicalInput, QueryResult, Reveal};
@@ -530,7 +530,7 @@ pub trait EvaluationCache<I: Interner> {
         proof_tree: Option<I::CanonicalGoalEvaluationStepRef>,
         additional_depth: usize,
         encountered_overflow: bool,
-        cycle_participants: FxHashSet<CanonicalInput<I>>,
+        cycle_participants: HashSet<CanonicalInput<I>>,
         dep_node: I::DepNodeIndex,
         result: QueryResult<I>,
     );
diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs
index 130ea231bf7..9b8ca5efdda 100644
--- a/compiler/rustc_type_ir/src/lib.rs
+++ b/compiler/rustc_type_ir/src/lib.rs
@@ -7,27 +7,19 @@
 #![cfg_attr(feature = "nightly", allow(internal_features))]
 // tidy-alphabetical-end
 
-#[cfg(feature = "nightly")]
 extern crate self as rustc_type_ir;
 
 #[cfg(feature = "nightly")]
-use rustc_data_structures::sso::SsoHashSet;
-#[cfg(feature = "nightly")]
-use rustc_data_structures::sync::Lrc;
-#[cfg(feature = "nightly")]
 use rustc_macros::{Decodable, Encodable, HashStable_NoContext};
-#[cfg(not(feature = "nightly"))]
-use std::collections::HashSet as SsoHashSet;
 use std::fmt;
 use std::hash::Hash;
-#[cfg(not(feature = "nightly"))]
-use std::sync::Arc as Lrc;
 
 // These modules are `pub` since they are not glob-imported.
 #[macro_use]
 pub mod visit;
 #[cfg(feature = "nightly")]
 pub mod codec;
+pub mod data_structures;
 pub mod error;
 pub mod fold;
 pub mod inherent;
diff --git a/compiler/rustc_type_ir/src/opaque_ty.rs b/compiler/rustc_type_ir/src/opaque_ty.rs
index 60737066597..738350f1b34 100644
--- a/compiler/rustc_type_ir/src/opaque_ty.rs
+++ b/compiler/rustc_type_ir/src/opaque_ty.rs
@@ -1,3 +1,4 @@
+#[cfg(feature = "nightly")]
 use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable};
 use rustc_type_ir_macros::{TypeFoldable_Generic, TypeVisitable_Generic};
 
diff --git a/compiler/rustc_type_ir/src/relate.rs b/compiler/rustc_type_ir/src/relate.rs
index 8a6ba87b60e..429bc3197d4 100644
--- a/compiler/rustc_type_ir/src/relate.rs
+++ b/compiler/rustc_type_ir/src/relate.rs
@@ -1,12 +1,13 @@
 use std::iter;
 
 use rustc_ast_ir::Mutability;
-use rustc_type_ir::error::{ExpectedFound, TypeError};
-use rustc_type_ir::fold::TypeFoldable;
-use rustc_type_ir::inherent::*;
-use rustc_type_ir::{self as ty, Interner};
 use tracing::{debug, instrument};
 
+use crate::error::{ExpectedFound, TypeError};
+use crate::fold::TypeFoldable;
+use crate::inherent::*;
+use crate::{self as ty, Interner};
+
 pub type RelateResult<I, T> = Result<T, TypeError<I>>;
 
 /// Extra information about why we ended up with a particular variance.
diff --git a/compiler/rustc_type_ir/src/visit.rs b/compiler/rustc_type_ir/src/visit.rs
index 6880c7b8cef..473a0aa250f 100644
--- a/compiler/rustc_type_ir/src/visit.rs
+++ b/compiler/rustc_type_ir/src/visit.rs
@@ -47,8 +47,9 @@ use rustc_index::{Idx, IndexVec};
 use std::fmt;
 use std::ops::ControlFlow;
 
+use crate::data_structures::Lrc;
 use crate::inherent::*;
-use crate::{self as ty, Interner, Lrc, TypeFlags};
+use crate::{self as ty, Interner, TypeFlags};
 
 /// This trait is implemented for every type that can be visited,
 /// providing the skeleton of the traversal.