about summary refs log tree commit diff
path: root/compiler/rustc_infer
diff options
context:
space:
mode:
authorlcnr <rust@lcnr.de>2025-09-08 11:41:43 +0200
committerlcnr <rust@lcnr.de>2025-09-08 14:17:56 +0200
commitb51a3a565a056235f3864e2cefdb9449f6b0dcb1 (patch)
tree525669b67e94ecdfe97995123eb4f79886831f2d /compiler/rustc_infer
parentf51458640840cb94c32f1e55431b1c855ca22e88 (diff)
downloadrust-b51a3a565a056235f3864e2cefdb9449f6b0dcb1.tar.gz
rust-b51a3a565a056235f3864e2cefdb9449f6b0dcb1.zip
review
Diffstat (limited to 'compiler/rustc_infer')
-rw-r--r--compiler/rustc_infer/src/infer/canonical/canonicalizer.rs8
-rw-r--r--compiler/rustc_infer/src/infer/canonical/mod.rs5
-rw-r--r--compiler/rustc_infer/src/infer/context.rs8
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs10
-rw-r--r--compiler/rustc_infer/src/infer/relate/generalize.rs2
-rw-r--r--compiler/rustc_infer/src/infer/type_variable.rs41
6 files changed, 42 insertions, 32 deletions
diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
index be68609502a..3c5e4a91c98 100644
--- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
+++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
@@ -294,6 +294,12 @@ struct Canonicalizer<'cx, 'tcx> {
     // Note that indices is only used once `var_values` is big enough to be
     // heap-allocated.
     indices: FxHashMap<GenericArg<'tcx>, BoundVar>,
+    /// Maps each `sub_unification_table_root_var` to the index of the first
+    /// variable which used it.
+    ///
+    /// This means in case two type variables have the same sub relations root,
+    /// we set the `sub_root` of the second variable to the position of the first.
+    /// Otherwise the `sub_root` of each type variable is just its own position.
     sub_root_lookup_table: SsoHashMap<ty::TyVid, usize>,
     canonicalize_mode: &'cx dyn CanonicalizeMode,
     needs_canonical_flags: TypeFlags,
@@ -662,7 +668,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
     }
 
     fn get_or_insert_sub_root(&mut self, vid: ty::TyVid) -> ty::BoundVar {
-        let root_vid = self.infcx.unwrap().sub_root_var(vid);
+        let root_vid = self.infcx.unwrap().sub_unification_table_root_var(vid);
         let idx =
             *self.sub_root_lookup_table.entry(root_vid).or_insert_with(|| self.variables.len());
         ty::BoundVar::from(idx)
diff --git a/compiler/rustc_infer/src/infer/canonical/mod.rs b/compiler/rustc_infer/src/infer/canonical/mod.rs
index 517331c3245..f99f228e19d 100644
--- a/compiler/rustc_infer/src/infer/canonical/mod.rs
+++ b/compiler/rustc_infer/src/infer/canonical/mod.rs
@@ -93,10 +93,11 @@ impl<'tcx> InferCtxt<'tcx> {
         match kind {
             CanonicalVarKind::Ty { ui, sub_root } => {
                 let vid = self.next_ty_vid_in_universe(span, universe_map(ui));
-                // Fetch the `sub_root` in case it exists.
+                // If this inference variable is related to an earlier variable
+                // via subtyping, we need to add that info to the inference context.
                 if let Some(prev) = previous_var_values.get(sub_root.as_usize()) {
                     if let &ty::Infer(ty::TyVar(sub_root)) = prev.expect_ty().kind() {
-                        self.inner.borrow_mut().type_variables().sub(vid, sub_root);
+                        self.sub_unify_ty_vids_raw(vid, sub_root);
                     } else {
                         unreachable!()
                     }
diff --git a/compiler/rustc_infer/src/infer/context.rs b/compiler/rustc_infer/src/infer/context.rs
index b76931caaa5..14cc590720a 100644
--- a/compiler/rustc_infer/src/infer/context.rs
+++ b/compiler/rustc_infer/src/infer/context.rs
@@ -59,8 +59,8 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> {
         self.root_var(var)
     }
 
-    fn sub_root_ty_var(&self, var: ty::TyVid) -> ty::TyVid {
-        self.sub_root_var(var)
+    fn sub_unification_table_root_var(&self, var: ty::TyVid) -> ty::TyVid {
+        self.sub_unification_table_root_var(var)
     }
 
     fn root_const_var(&self, var: ty::ConstVid) -> ty::ConstVid {
@@ -183,8 +183,8 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> {
         self.inner.borrow_mut().type_variables().equate(a, b);
     }
 
-    fn sub_ty_vids_raw(&self, a: ty::TyVid, b: ty::TyVid) {
-        self.sub_ty_vids_raw(a, b);
+    fn sub_unify_ty_vids_raw(&self, a: ty::TyVid, b: ty::TyVid) {
+        self.sub_unify_ty_vids_raw(a, b);
     }
 
     fn equate_int_vids_raw(&self, a: ty::IntVid, b: ty::IntVid) {
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index 48dd699cd50..9d3886aff1c 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -764,7 +764,7 @@ impl<'tcx> InferCtxt<'tcx> {
         let r_b = self.shallow_resolve(predicate.skip_binder().b);
         match (r_a.kind(), r_b.kind()) {
             (&ty::Infer(ty::TyVar(a_vid)), &ty::Infer(ty::TyVar(b_vid))) => {
-                self.sub_ty_vids_raw(a_vid, b_vid);
+                self.sub_unify_ty_vids_raw(a_vid, b_vid);
                 return Err((a_vid, b_vid));
             }
             _ => {}
@@ -1129,12 +1129,12 @@ impl<'tcx> InferCtxt<'tcx> {
         self.inner.borrow_mut().type_variables().root_var(var)
     }
 
-    pub fn sub_ty_vids_raw(&self, a: ty::TyVid, b: ty::TyVid) {
-        self.inner.borrow_mut().type_variables().sub(a, b);
+    pub fn sub_unify_ty_vids_raw(&self, a: ty::TyVid, b: ty::TyVid) {
+        self.inner.borrow_mut().type_variables().sub_unify(a, b);
     }
 
-    pub fn sub_root_var(&self, var: ty::TyVid) -> ty::TyVid {
-        self.inner.borrow_mut().type_variables().sub_root_var(var)
+    pub fn sub_unification_table_root_var(&self, var: ty::TyVid) -> ty::TyVid {
+        self.inner.borrow_mut().type_variables().sub_unification_table_root_var(var)
     }
 
     pub fn root_const_var(&self, var: ty::ConstVid) -> ty::ConstVid {
diff --git a/compiler/rustc_infer/src/infer/relate/generalize.rs b/compiler/rustc_infer/src/infer/relate/generalize.rs
index 2323add0b32..f0b5b164a0b 100644
--- a/compiler/rustc_infer/src/infer/relate/generalize.rs
+++ b/compiler/rustc_infer/src/infer/relate/generalize.rs
@@ -522,7 +522,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Generalizer<'_, 'tcx> {
                             // Record that `vid` and `new_var_id` have to be subtypes
                             // of each other. This is currently only used for diagnostics.
                             // To see why, see the docs in the `type_variables` module.
-                            inner.type_variables().sub(vid, new_var_id);
+                            inner.type_variables().sub_unify(vid, new_var_id);
                             // If we're in the new solver and create a new inference
                             // variable inside of an alias we eagerly constrain that
                             // inference variable to prevent unexpected ambiguity errors.
diff --git a/compiler/rustc_infer/src/infer/type_variable.rs b/compiler/rustc_infer/src/infer/type_variable.rs
index 613e5a5883a..65f77fe8e25 100644
--- a/compiler/rustc_infer/src/infer/type_variable.rs
+++ b/compiler/rustc_infer/src/infer/type_variable.rs
@@ -42,7 +42,7 @@ impl<'tcx> Rollback<sv::UndoLog<ut::Delegate<TyVidEqKey<'tcx>>>> for TypeVariabl
 
 impl<'tcx> Rollback<sv::UndoLog<ut::Delegate<TyVidSubKey>>> for TypeVariableStorage<'tcx> {
     fn reverse(&mut self, undo: sv::UndoLog<ut::Delegate<TyVidSubKey>>) {
-        self.sub_relations.reverse(undo)
+        self.sub_unification_table.reverse(undo)
     }
 }
 
@@ -50,7 +50,7 @@ impl<'tcx> Rollback<UndoLog<'tcx>> for TypeVariableStorage<'tcx> {
     fn reverse(&mut self, undo: UndoLog<'tcx>) {
         match undo {
             UndoLog::EqRelation(undo) => self.eq_relations.reverse(undo),
-            UndoLog::SubRelation(undo) => self.sub_relations.reverse(undo),
+            UndoLog::SubRelation(undo) => self.sub_unification_table.reverse(undo),
         }
     }
 }
@@ -63,7 +63,9 @@ pub(crate) struct TypeVariableStorage<'tcx> {
     /// constraint `?X == ?Y`. This table also stores, for each key,
     /// the known value.
     eq_relations: ut::UnificationTableStorage<TyVidEqKey<'tcx>>,
-    /// Only used by `-Znext-solver` and for diagnostics.
+    /// Only used by `-Znext-solver` and for diagnostics. Tracks whether
+    /// type variables are related via subtyping at all, ignoring which of
+    /// the two is the subtype.
     ///
     /// When reporting ambiguity errors, we sometimes want to
     /// treat all inference vars which are subtypes of each
@@ -79,7 +81,7 @@ pub(crate) struct TypeVariableStorage<'tcx> {
     /// Even for something like `let x = returns_arg(); x.method();` the
     /// type of `x` is only a supertype of the argument of `returns_arg`. We
     /// still want to suggest specifying the type of the argument.
-    sub_relations: ut::UnificationTableStorage<TyVidSubKey>,
+    sub_unification_table: ut::UnificationTableStorage<TyVidSubKey>,
 }
 
 pub(crate) struct TypeVariableTable<'a, 'tcx> {
@@ -155,23 +157,24 @@ impl<'tcx> TypeVariableTable<'_, 'tcx> {
         self.storage.values[vid].origin
     }
 
-    /// Records that `a == b`, depending on `dir`.
+    /// Records that `a == b`.
     ///
     /// Precondition: neither `a` nor `b` are known.
     pub(crate) fn equate(&mut self, a: ty::TyVid, b: ty::TyVid) {
         debug_assert!(self.probe(a).is_unknown());
         debug_assert!(self.probe(b).is_unknown());
         self.eq_relations().union(a, b);
-        self.sub_relations().union(a, b);
+        self.sub_unification_table().union(a, b);
     }
 
-    /// Records that `a <: b`, depending on `dir`.
+    /// Records that `a` and `b` are related via subtyping. We don't track
+    /// which of the two is the subtype.
     ///
     /// Precondition: neither `a` nor `b` are known.
-    pub(crate) fn sub(&mut self, a: ty::TyVid, b: ty::TyVid) {
+    pub(crate) fn sub_unify(&mut self, a: ty::TyVid, b: ty::TyVid) {
         debug_assert!(self.probe(a).is_unknown());
         debug_assert!(self.probe(b).is_unknown());
-        self.sub_relations().union(a, b);
+        self.sub_unification_table().union(a, b);
     }
 
     /// Instantiates `vid` with the type `ty`.
@@ -206,7 +209,7 @@ impl<'tcx> TypeVariableTable<'_, 'tcx> {
     ) -> ty::TyVid {
         let eq_key = self.eq_relations().new_key(TypeVariableValue::Unknown { universe });
 
-        let sub_key = self.sub_relations().new_key(());
+        let sub_key = self.sub_unification_table().new_key(());
         debug_assert_eq!(eq_key.vid, sub_key.vid);
 
         let index = self.storage.values.push(TypeVariableData { origin });
@@ -231,16 +234,16 @@ impl<'tcx> TypeVariableTable<'_, 'tcx> {
         self.eq_relations().find(vid).vid
     }
 
-    /// Returns the "root" variable of `vid` in the `sub_relations`
-    /// equivalence table. All type variables that have been are
-    /// related via equality or subtyping will yield the same root
-    /// variable (per the union-find algorithm), so `sub_root_var(a)
-    /// == sub_root_var(b)` implies that:
+    /// Returns the "root" variable of `vid` in the `sub_unification_table`
+    /// equivalence table. All type variables that have been are related via
+    /// equality or subtyping will yield the same root variable (per the
+    /// union-find algorithm), so `sub_unification_table_root_var(a)
+    /// == sub_unification_table_root_var(b)` implies that:
     /// ```text
     /// exists X. (a <: X || X <: a) && (b <: X || X <: b)
     /// ```
-    pub(crate) fn sub_root_var(&mut self, vid: ty::TyVid) -> ty::TyVid {
-        self.sub_relations().find(vid).vid
+    pub(crate) fn sub_unification_table_root_var(&mut self, vid: ty::TyVid) -> ty::TyVid {
+        self.sub_unification_table().find(vid).vid
     }
 
     /// Retrieves the type to which `vid` has been instantiated, if
@@ -261,8 +264,8 @@ impl<'tcx> TypeVariableTable<'_, 'tcx> {
     }
 
     #[inline]
-    fn sub_relations(&mut self) -> super::UnificationTable<'_, 'tcx, TyVidSubKey> {
-        self.storage.sub_relations.with_log(self.undo_log)
+    fn sub_unification_table(&mut self) -> super::UnificationTable<'_, 'tcx, TyVidSubKey> {
+        self.storage.sub_unification_table.with_log(self.undo_log)
     }
 
     /// Returns a range of the type variables created during the snapshot.