about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-06-04 17:07:13 +0000
committerbors <bors@rust-lang.org>2024-06-04 17:07:13 +0000
commit44701e070c8453df10df1984944258018ac21610 (patch)
tree91d6284aa03752400b85c5e6d50b952ae2c314e6
parent30ea1a2693bb1ba4b119ac6257985b9e11e45b83 (diff)
parent208c316a61d3f21f834845ea35aca41369673f59 (diff)
downloadrust-44701e070c8453df10df1984944258018ac21610.tar.gz
rust-44701e070c8453df10df1984944258018ac21610.zip
Auto merge of #123536 - compiler-errors:simplify-int-float, r=lcnr
Simplify `IntVarValue`/`FloatVarValue`

r? `@ghost`
-rw-r--r--compiler/rustc_infer/src/infer/freshen.rs26
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs130
-rw-r--r--compiler/rustc_infer/src/infer/relate/combine.rs81
-rw-r--r--compiler/rustc_infer/src/infer/relate/lattice.rs4
-rw-r--r--compiler/rustc_infer/src/infer/relate/type_relating.rs4
-rw-r--r--compiler/rustc_middle/src/infer/unify_key.rs16
-rw-r--r--compiler/rustc_middle/src/ty/error.rs22
-rw-r--r--compiler/rustc_type_ir/src/ty_kind.rs93
-rw-r--r--tests/ui/parser/recover/recover-range-pats.stderr9
9 files changed, 186 insertions, 199 deletions
diff --git a/compiler/rustc_infer/src/infer/freshen.rs b/compiler/rustc_infer/src/infer/freshen.rs
index b2d89523ea8..a3c8d5f4251 100644
--- a/compiler/rustc_infer/src/infer/freshen.rs
+++ b/compiler/rustc_infer/src/infer/freshen.rs
@@ -33,7 +33,6 @@
 use super::InferCtxt;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_middle::bug;
-use rustc_middle::infer::unify_key::ToType;
 use rustc_middle::ty::fold::TypeFolder;
 use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable, TypeVisitableExt};
 use std::collections::hash_map::Entry;
@@ -204,22 +203,27 @@ impl<'a, 'tcx> TypeFreshener<'a, 'tcx> {
 
             ty::IntVar(v) => {
                 let mut inner = self.infcx.inner.borrow_mut();
-                let input = inner
-                    .int_unification_table()
-                    .probe_value(v)
-                    .map(|v| v.to_type(self.infcx.tcx))
-                    .ok_or_else(|| ty::IntVar(inner.int_unification_table().find(v)));
+                let value = inner.int_unification_table().probe_value(v);
+                let input = match value {
+                    ty::IntVarValue::IntType(ty) => Ok(Ty::new_int(self.infcx.tcx, ty)),
+                    ty::IntVarValue::UintType(ty) => Ok(Ty::new_uint(self.infcx.tcx, ty)),
+                    ty::IntVarValue::Unknown => {
+                        Err(ty::IntVar(inner.int_unification_table().find(v)))
+                    }
+                };
                 drop(inner);
                 Some(self.freshen_ty(input, |n| Ty::new_fresh_int(self.infcx.tcx, n)))
             }
 
             ty::FloatVar(v) => {
                 let mut inner = self.infcx.inner.borrow_mut();
-                let input = inner
-                    .float_unification_table()
-                    .probe_value(v)
-                    .map(|v| v.to_type(self.infcx.tcx))
-                    .ok_or_else(|| ty::FloatVar(inner.float_unification_table().find(v)));
+                let value = inner.float_unification_table().probe_value(v);
+                let input = match value {
+                    ty::FloatVarValue::Known(ty) => Ok(Ty::new_float(self.infcx.tcx, ty)),
+                    ty::FloatVarValue::Unknown => {
+                        Err(ty::FloatVar(inner.float_unification_table().find(v)))
+                    }
+                };
                 drop(inner);
                 Some(self.freshen_ty(input, |n| Ty::new_fresh_float(self.infcx.tcx, n)))
             }
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index 2cfa447833c..e9a4cc3e04b 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -29,9 +29,9 @@ use rustc_errors::{Diag, DiagCtxt, ErrorGuaranteed};
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_macros::extension;
 use rustc_middle::infer::canonical::{Canonical, CanonicalVarValues};
+use rustc_middle::infer::unify_key::ConstVariableOrigin;
 use rustc_middle::infer::unify_key::ConstVariableValue;
 use rustc_middle::infer::unify_key::EffectVarValue;
-use rustc_middle::infer::unify_key::{ConstVariableOrigin, ToType};
 use rustc_middle::infer::unify_key::{ConstVidKey, EffectVidKey};
 use rustc_middle::mir::interpret::{ErrorHandled, EvalToValTreeResult};
 use rustc_middle::mir::ConstraintCategory;
@@ -41,7 +41,7 @@ use rustc_middle::ty::fold::BoundVarReplacerDelegate;
 use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
 use rustc_middle::ty::relate::RelateResult;
 use rustc_middle::ty::visit::TypeVisitableExt;
-use rustc_middle::ty::{self, GenericParamDefKind, InferConst, InferTy, Ty, TyCtxt};
+use rustc_middle::ty::{self, GenericParamDefKind, InferConst, Ty, TyCtxt};
 use rustc_middle::ty::{ConstVid, EffectVid, FloatVid, IntVid, TyVid};
 use rustc_middle::ty::{GenericArg, GenericArgKind, GenericArgs, GenericArgsRef};
 use rustc_middle::{bug, span_bug};
@@ -813,13 +813,13 @@ impl<'tcx> InferCtxt<'tcx> {
         vars.extend(
             (0..inner.int_unification_table().len())
                 .map(|i| ty::IntVid::from_u32(i as u32))
-                .filter(|&vid| inner.int_unification_table().probe_value(vid).is_none())
+                .filter(|&vid| inner.int_unification_table().probe_value(vid).is_unknown())
                 .map(|v| Ty::new_int_var(self.tcx, v)),
         );
         vars.extend(
             (0..inner.float_unification_table().len())
                 .map(|i| ty::FloatVid::from_u32(i as u32))
-                .filter(|&vid| inner.float_unification_table().probe_value(vid).is_none())
+                .filter(|&vid| inner.float_unification_table().probe_value(vid).is_unknown())
                 .map(|v| Ty::new_float_var(self.tcx, v)),
         );
         vars
@@ -1027,14 +1027,28 @@ impl<'tcx> InferCtxt<'tcx> {
         ty::Const::new_var(self.tcx, vid, ty)
     }
 
+    pub fn next_const_var_id(&self, origin: ConstVariableOrigin) -> ConstVid {
+        self.inner
+            .borrow_mut()
+            .const_unification_table()
+            .new_key(ConstVariableValue::Unknown { origin, universe: self.universe() })
+            .vid
+    }
+
+    fn next_int_var_id(&self) -> IntVid {
+        self.inner.borrow_mut().int_unification_table().new_key(ty::IntVarValue::Unknown)
+    }
+
     pub fn next_int_var(&self) -> Ty<'tcx> {
-        let vid = self.inner.borrow_mut().int_unification_table().new_key(None);
-        Ty::new_int_var(self.tcx, vid)
+        Ty::new_int_var(self.tcx, self.next_int_var_id())
+    }
+
+    fn next_float_var_id(&self) -> FloatVid {
+        self.inner.borrow_mut().float_unification_table().new_key(ty::FloatVarValue::Unknown)
     }
 
     pub fn next_float_var(&self) -> Ty<'tcx> {
-        let vid = self.inner.borrow_mut().float_unification_table().new_key(None);
-        Ty::new_float_var(self.tcx, vid)
+        Ty::new_float_var(self.tcx, self.next_float_var_id())
     }
 
     /// Creates a fresh region variable with the next available index.
@@ -1236,45 +1250,44 @@ impl<'tcx> InferCtxt<'tcx> {
     }
 
     pub fn shallow_resolve(&self, ty: Ty<'tcx>) -> Ty<'tcx> {
-        if let ty::Infer(v) = ty.kind() { self.fold_infer_ty(*v).unwrap_or(ty) } else { ty }
-    }
-
-    // This is separate from `shallow_resolve` to keep that method small and inlinable.
-    #[inline(never)]
-    fn fold_infer_ty(&self, v: InferTy) -> Option<Ty<'tcx>> {
-        match v {
-            ty::TyVar(v) => {
-                // Not entirely obvious: if `typ` is a type variable,
-                // it can be resolved to an int/float variable, which
-                // can then be recursively resolved, hence the
-                // recursion. Note though that we prevent type
-                // variables from unifying to other type variables
-                // directly (though they may be embedded
-                // structurally), and we prevent cycles in any case,
-                // so this recursion should always be of very limited
-                // depth.
-                //
-                // Note: if these two lines are combined into one we get
-                // dynamic borrow errors on `self.inner`.
-                let known = self.inner.borrow_mut().type_variables().probe(v).known();
-                known.map(|t| self.shallow_resolve(t))
-            }
+        if let ty::Infer(v) = *ty.kind() {
+            match v {
+                ty::TyVar(v) => {
+                    // Not entirely obvious: if `typ` is a type variable,
+                    // it can be resolved to an int/float variable, which
+                    // can then be recursively resolved, hence the
+                    // recursion. Note though that we prevent type
+                    // variables from unifying to other type variables
+                    // directly (though they may be embedded
+                    // structurally), and we prevent cycles in any case,
+                    // so this recursion should always be of very limited
+                    // depth.
+                    //
+                    // Note: if these two lines are combined into one we get
+                    // dynamic borrow errors on `self.inner`.
+                    let known = self.inner.borrow_mut().type_variables().probe(v).known();
+                    known.map_or(ty, |t| self.shallow_resolve(t))
+                }
+
+                ty::IntVar(v) => {
+                    match self.inner.borrow_mut().int_unification_table().probe_value(v) {
+                        ty::IntVarValue::IntType(ty) => Ty::new_int(self.tcx, ty),
+                        ty::IntVarValue::UintType(ty) => Ty::new_uint(self.tcx, ty),
+                        ty::IntVarValue::Unknown => ty,
+                    }
+                }
 
-            ty::IntVar(v) => self
-                .inner
-                .borrow_mut()
-                .int_unification_table()
-                .probe_value(v)
-                .map(|v| v.to_type(self.tcx)),
-
-            ty::FloatVar(v) => self
-                .inner
-                .borrow_mut()
-                .float_unification_table()
-                .probe_value(v)
-                .map(|v| v.to_type(self.tcx)),
-
-            ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_) => None,
+                ty::FloatVar(v) => {
+                    match self.inner.borrow_mut().float_unification_table().probe_value(v) {
+                        ty::FloatVarValue::Known(ty) => Ty::new_float(self.tcx, ty),
+                        ty::FloatVarValue::Unknown => ty,
+                    }
+                }
+
+                ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_) => ty,
+            }
+        } else {
+            ty
         }
     }
 
@@ -1323,10 +1336,13 @@ impl<'tcx> InferCtxt<'tcx> {
     /// or else the root int var in the unification table.
     pub fn opportunistic_resolve_int_var(&self, vid: ty::IntVid) -> Ty<'tcx> {
         let mut inner = self.inner.borrow_mut();
-        if let Some(value) = inner.int_unification_table().probe_value(vid) {
-            value.to_type(self.tcx)
-        } else {
-            Ty::new_int_var(self.tcx, inner.int_unification_table().find(vid))
+        let value = inner.int_unification_table().probe_value(vid);
+        match value {
+            ty::IntVarValue::IntType(ty) => Ty::new_int(self.tcx, ty),
+            ty::IntVarValue::UintType(ty) => Ty::new_uint(self.tcx, ty),
+            ty::IntVarValue::Unknown => {
+                Ty::new_int_var(self.tcx, inner.int_unification_table().find(vid))
+            }
         }
     }
 
@@ -1334,10 +1350,12 @@ impl<'tcx> InferCtxt<'tcx> {
     /// or else the root float var in the unification table.
     pub fn opportunistic_resolve_float_var(&self, vid: ty::FloatVid) -> Ty<'tcx> {
         let mut inner = self.inner.borrow_mut();
-        if let Some(value) = inner.float_unification_table().probe_value(vid) {
-            value.to_type(self.tcx)
-        } else {
-            Ty::new_float_var(self.tcx, inner.float_unification_table().find(vid))
+        let value = inner.float_unification_table().probe_value(vid);
+        match value {
+            ty::FloatVarValue::Known(ty) => Ty::new_float(self.tcx, ty),
+            ty::FloatVarValue::Unknown => {
+                Ty::new_float_var(self.tcx, inner.float_unification_table().find(vid))
+            }
         }
     }
 
@@ -1628,7 +1646,7 @@ impl<'tcx> InferCtxt<'tcx> {
                 // If `inlined_probe_value` returns a value it's always a
                 // `ty::Int(_)` or `ty::UInt(_)`, which never matches a
                 // `ty::Infer(_)`.
-                self.inner.borrow_mut().int_unification_table().inlined_probe_value(v).is_some()
+                self.inner.borrow_mut().int_unification_table().inlined_probe_value(v).is_known()
             }
 
             TyOrConstInferVar::TyFloat(v) => {
@@ -1636,7 +1654,7 @@ impl<'tcx> InferCtxt<'tcx> {
                 // `ty::Float(_)`, which never matches a `ty::Infer(_)`.
                 //
                 // Not `inlined_probe_value(v)` because this call site is colder.
-                self.inner.borrow_mut().float_unification_table().probe_value(v).is_some()
+                self.inner.borrow_mut().float_unification_table().probe_value(v).is_known()
             }
 
             TyOrConstInferVar::Const(v) => {
diff --git a/compiler/rustc_infer/src/infer/relate/combine.rs b/compiler/rustc_infer/src/infer/relate/combine.rs
index 04ca043e6fe..b193f4bcede 100644
--- a/compiler/rustc_infer/src/infer/relate/combine.rs
+++ b/compiler/rustc_infer/src/infer/relate/combine.rs
@@ -26,7 +26,7 @@ use crate::infer::{DefineOpaqueTypes, InferCtxt, TypeTrace};
 use crate::traits::{Obligation, PredicateObligations};
 use rustc_middle::bug;
 use rustc_middle::infer::unify_key::EffectVarValue;
-use rustc_middle::ty::error::{ExpectedFound, TypeError};
+use rustc_middle::ty::error::TypeError;
 use rustc_middle::ty::relate::{RelateResult, TypeRelation};
 use rustc_middle::ty::{self, InferConst, Ty, TyCtxt, TypeVisitableExt, Upcast};
 use rustc_middle::ty::{IntType, UintType};
@@ -68,40 +68,38 @@ impl<'tcx> InferCtxt<'tcx> {
         match (a.kind(), b.kind()) {
             // Relate integral variables to other types
             (&ty::Infer(ty::IntVar(a_id)), &ty::Infer(ty::IntVar(b_id))) => {
-                self.inner
-                    .borrow_mut()
-                    .int_unification_table()
-                    .unify_var_var(a_id, b_id)
-                    .map_err(|e| int_unification_error(true, e))?;
+                self.inner.borrow_mut().int_unification_table().union(a_id, b_id);
                 Ok(a)
             }
             (&ty::Infer(ty::IntVar(v_id)), &ty::Int(v)) => {
-                self.unify_integral_variable(true, v_id, IntType(v))
+                self.unify_integral_variable(v_id, IntType(v));
+                Ok(b)
             }
             (&ty::Int(v), &ty::Infer(ty::IntVar(v_id))) => {
-                self.unify_integral_variable(false, v_id, IntType(v))
+                self.unify_integral_variable(v_id, IntType(v));
+                Ok(a)
             }
             (&ty::Infer(ty::IntVar(v_id)), &ty::Uint(v)) => {
-                self.unify_integral_variable(true, v_id, UintType(v))
+                self.unify_integral_variable(v_id, UintType(v));
+                Ok(b)
             }
             (&ty::Uint(v), &ty::Infer(ty::IntVar(v_id))) => {
-                self.unify_integral_variable(false, v_id, UintType(v))
+                self.unify_integral_variable(v_id, UintType(v));
+                Ok(a)
             }
 
             // Relate floating-point variables to other types
             (&ty::Infer(ty::FloatVar(a_id)), &ty::Infer(ty::FloatVar(b_id))) => {
-                self.inner
-                    .borrow_mut()
-                    .float_unification_table()
-                    .unify_var_var(a_id, b_id)
-                    .map_err(|e| float_unification_error(true, e))?;
+                self.inner.borrow_mut().float_unification_table().union(a_id, b_id);
                 Ok(a)
             }
             (&ty::Infer(ty::FloatVar(v_id)), &ty::Float(v)) => {
-                self.unify_float_variable(true, v_id, v)
+                self.unify_float_variable(v_id, ty::FloatVarValue::Known(v));
+                Ok(b)
             }
             (&ty::Float(v), &ty::Infer(ty::FloatVar(v_id))) => {
-                self.unify_float_variable(false, v_id, v)
+                self.unify_float_variable(v_id, ty::FloatVarValue::Known(v));
+                Ok(a)
             }
 
             // We don't expect `TyVar` or `Fresh*` vars at this point with lazy norm.
@@ -244,35 +242,14 @@ impl<'tcx> InferCtxt<'tcx> {
         }
     }
 
-    fn unify_integral_variable(
-        &self,
-        vid_is_expected: bool,
-        vid: ty::IntVid,
-        val: ty::IntVarValue,
-    ) -> RelateResult<'tcx, Ty<'tcx>> {
-        self.inner
-            .borrow_mut()
-            .int_unification_table()
-            .unify_var_value(vid, Some(val))
-            .map_err(|e| int_unification_error(vid_is_expected, e))?;
-        match val {
-            IntType(v) => Ok(Ty::new_int(self.tcx, v)),
-            UintType(v) => Ok(Ty::new_uint(self.tcx, v)),
-        }
+    #[inline(always)]
+    fn unify_integral_variable(&self, vid: ty::IntVid, val: ty::IntVarValue) {
+        self.inner.borrow_mut().int_unification_table().union_value(vid, val);
     }
 
-    fn unify_float_variable(
-        &self,
-        vid_is_expected: bool,
-        vid: ty::FloatVid,
-        val: ty::FloatTy,
-    ) -> RelateResult<'tcx, Ty<'tcx>> {
-        self.inner
-            .borrow_mut()
-            .float_unification_table()
-            .unify_var_value(vid, Some(ty::FloatVarValue(val)))
-            .map_err(|e| float_unification_error(vid_is_expected, e))?;
-        Ok(Ty::new_float(self.tcx, val))
+    #[inline(always)]
+    fn unify_float_variable(&self, vid: ty::FloatVid, val: ty::FloatVarValue) {
+        self.inner.borrow_mut().float_unification_table().union_value(vid, val);
     }
 
     fn unify_effect_variable(&self, vid: ty::EffectVid, val: ty::Const<'tcx>) -> ty::Const<'tcx> {
@@ -350,19 +327,3 @@ pub trait ObligationEmittingRelation<'tcx>: TypeRelation<'tcx> {
     /// Register `AliasRelate` obligation(s) that both types must be related to each other.
     fn register_type_relate_obligation(&mut self, a: Ty<'tcx>, b: Ty<'tcx>);
 }
-
-fn int_unification_error<'tcx>(
-    a_is_expected: bool,
-    v: (ty::IntVarValue, ty::IntVarValue),
-) -> TypeError<'tcx> {
-    let (a, b) = v;
-    TypeError::IntMismatch(ExpectedFound::new(a_is_expected, a, b))
-}
-
-fn float_unification_error<'tcx>(
-    a_is_expected: bool,
-    v: (ty::FloatVarValue, ty::FloatVarValue),
-) -> TypeError<'tcx> {
-    let (ty::FloatVarValue(a), ty::FloatVarValue(b)) = v;
-    TypeError::FloatMismatch(ExpectedFound::new(a_is_expected, a, b))
-}
diff --git a/compiler/rustc_infer/src/infer/relate/lattice.rs b/compiler/rustc_infer/src/infer/relate/lattice.rs
index 38e25b0d9b6..c0c51a2820b 100644
--- a/compiler/rustc_infer/src/infer/relate/lattice.rs
+++ b/compiler/rustc_infer/src/infer/relate/lattice.rs
@@ -64,8 +64,8 @@ where
 
     let infcx = this.infcx();
 
-    let a = infcx.inner.borrow_mut().type_variables().replace_if_possible(a);
-    let b = infcx.inner.borrow_mut().type_variables().replace_if_possible(b);
+    let a = infcx.shallow_resolve(a);
+    let b = infcx.shallow_resolve(b);
 
     match (a.kind(), b.kind()) {
         // If one side is known to be a variable and one is not,
diff --git a/compiler/rustc_infer/src/infer/relate/type_relating.rs b/compiler/rustc_infer/src/infer/relate/type_relating.rs
index 21064fff97f..e55a5878821 100644
--- a/compiler/rustc_infer/src/infer/relate/type_relating.rs
+++ b/compiler/rustc_infer/src/infer/relate/type_relating.rs
@@ -80,8 +80,8 @@ impl<'tcx> TypeRelation<'tcx> for TypeRelating<'_, '_, 'tcx> {
         }
 
         let infcx = self.fields.infcx;
-        let a = infcx.inner.borrow_mut().type_variables().replace_if_possible(a);
-        let b = infcx.inner.borrow_mut().type_variables().replace_if_possible(b);
+        let a = infcx.shallow_resolve(a);
+        let b = infcx.shallow_resolve(b);
 
         match (a.kind(), b.kind()) {
             (&ty::Infer(TyVar(a_id)), &ty::Infer(TyVar(b_id))) => {
diff --git a/compiler/rustc_middle/src/infer/unify_key.rs b/compiler/rustc_middle/src/infer/unify_key.rs
index 105be21f272..a5da7e7739e 100644
--- a/compiler/rustc_middle/src/infer/unify_key.rs
+++ b/compiler/rustc_middle/src/infer/unify_key.rs
@@ -86,21 +86,6 @@ impl<'tcx> UnifyValue for RegionVariableValue<'tcx> {
     }
 }
 
-impl ToType for ty::IntVarValue {
-    fn to_type<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
-        match *self {
-            ty::IntType(i) => Ty::new_int(tcx, i),
-            ty::UintType(i) => Ty::new_uint(tcx, i),
-        }
-    }
-}
-
-impl ToType for ty::FloatVarValue {
-    fn to_type<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
-        Ty::new_float(tcx, self.0)
-    }
-}
-
 // Generic consts.
 
 #[derive(Copy, Clone, Debug)]
@@ -211,6 +196,7 @@ impl<'tcx> EffectVarValue<'tcx> {
 
 impl<'tcx> UnifyValue for EffectVarValue<'tcx> {
     type Error = NoError;
+
     fn unify_values(value1: &Self, value2: &Self) -> Result<Self, Self::Error> {
         match (*value1, *value2) {
             (EffectVarValue::Unknown, EffectVarValue::Unknown) => Ok(EffectVarValue::Unknown),
diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs
index 99d703be873..9e2c626478a 100644
--- a/compiler/rustc_middle/src/ty/error.rs
+++ b/compiler/rustc_middle/src/ty/error.rs
@@ -49,8 +49,6 @@ pub enum TypeError<'tcx> {
 
     Sorts(ExpectedFound<Ty<'tcx>>),
     ArgumentSorts(ExpectedFound<Ty<'tcx>>, usize),
-    IntMismatch(ExpectedFound<ty::IntVarValue>),
-    FloatMismatch(ExpectedFound<ty::FloatTy>),
     Traits(ExpectedFound<DefId>),
     VariadicMismatch(ExpectedFound<bool>),
 
@@ -155,23 +153,6 @@ impl<'tcx> TypeError<'tcx> {
                 report_maybe_different(&format!("trait `{expected}`"), &format!("trait `{found}`"))
                     .into()
             }
-            IntMismatch(ref values) => {
-                let expected = match values.expected {
-                    ty::IntVarValue::IntType(ty) => ty.name_str(),
-                    ty::IntVarValue::UintType(ty) => ty.name_str(),
-                };
-                let found = match values.found {
-                    ty::IntVarValue::IntType(ty) => ty.name_str(),
-                    ty::IntVarValue::UintType(ty) => ty.name_str(),
-                };
-                format!("expected `{expected}`, found `{found}`").into()
-            }
-            FloatMismatch(ref values) => format!(
-                "expected `{}`, found `{}`",
-                values.expected.name_str(),
-                values.found.name_str()
-            )
-            .into(),
             VariadicMismatch(ref values) => format!(
                 "expected {} fn, found {} function",
                 if values.expected { "variadic" } else { "non-variadic" },
@@ -206,8 +187,7 @@ impl<'tcx> TypeError<'tcx> {
         match self {
             CyclicTy(_) | CyclicConst(_) | SafetyMismatch(_) | ConstnessMismatch(_)
             | PolarityMismatch(_) | Mismatch | AbiMismatch(_) | FixedArraySize(_)
-            | ArgumentSorts(..) | Sorts(_) | IntMismatch(_) | FloatMismatch(_)
-            | VariadicMismatch(_) | TargetFeatureCast(_) => false,
+            | ArgumentSorts(..) | Sorts(_) | VariadicMismatch(_) | TargetFeatureCast(_) => false,
 
             Mutability
             | ArgumentMutability(_)
diff --git a/compiler/rustc_type_ir/src/ty_kind.rs b/compiler/rustc_type_ir/src/ty_kind.rs
index 6569f3123aa..71f3862226d 100644
--- a/compiler/rustc_type_ir/src/ty_kind.rs
+++ b/compiler/rustc_type_ir/src/ty_kind.rs
@@ -1,7 +1,7 @@
 #[cfg(feature = "nightly")]
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 #[cfg(feature = "nightly")]
-use rustc_data_structures::unify::{EqUnifyValue, UnifyKey};
+use rustc_data_structures::unify::{NoError, UnifyKey, UnifyValue};
 #[cfg(feature = "nightly")]
 use rustc_macros::{Decodable, Encodable, HashStable_NoContext, TyDecodable, TyEncodable};
 use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic};
@@ -717,14 +717,44 @@ impl FloatTy {
     }
 }
 
-#[derive(Clone, Copy, PartialEq, Eq)]
+#[derive(Clone, Copy, PartialEq, Eq, Debug)]
 pub enum IntVarValue {
+    Unknown,
     IntType(IntTy),
     UintType(UintTy),
 }
 
-#[derive(Clone, Copy, PartialEq, Eq)]
-pub struct FloatVarValue(pub FloatTy);
+impl IntVarValue {
+    pub fn is_known(self) -> bool {
+        match self {
+            IntVarValue::IntType(_) | IntVarValue::UintType(_) => true,
+            IntVarValue::Unknown => false,
+        }
+    }
+
+    pub fn is_unknown(self) -> bool {
+        !self.is_known()
+    }
+}
+
+#[derive(Clone, Copy, PartialEq, Eq, Debug)]
+pub enum FloatVarValue {
+    Unknown,
+    Known(FloatTy),
+}
+
+impl FloatVarValue {
+    pub fn is_known(self) -> bool {
+        match self {
+            FloatVarValue::Known(_) => true,
+            FloatVarValue::Unknown => false,
+        }
+    }
+
+    pub fn is_unknown(self) -> bool {
+        !self.is_known()
+    }
+}
 
 rustc_index::newtype_index! {
     /// A **ty**pe **v**ariable **ID**.
@@ -809,11 +839,28 @@ impl UnifyKey for TyVid {
 }
 
 #[cfg(feature = "nightly")]
-impl EqUnifyValue for IntVarValue {}
+impl UnifyValue for IntVarValue {
+    type Error = NoError;
+
+    fn unify_values(value1: &Self, value2: &Self) -> Result<Self, Self::Error> {
+        match (*value1, *value2) {
+            (IntVarValue::Unknown, IntVarValue::Unknown) => Ok(IntVarValue::Unknown),
+            (
+                IntVarValue::Unknown,
+                known @ (IntVarValue::UintType(_) | IntVarValue::IntType(_)),
+            )
+            | (
+                known @ (IntVarValue::UintType(_) | IntVarValue::IntType(_)),
+                IntVarValue::Unknown,
+            ) => Ok(known),
+            _ => panic!("differing ints should have been resolved first"),
+        }
+    }
+}
 
 #[cfg(feature = "nightly")]
 impl UnifyKey for IntVid {
-    type Value = Option<IntVarValue>;
+    type Value = IntVarValue;
     #[inline] // make this function eligible for inlining - it is quite hot.
     fn index(&self) -> u32 {
         self.as_u32()
@@ -828,11 +875,26 @@ impl UnifyKey for IntVid {
 }
 
 #[cfg(feature = "nightly")]
-impl EqUnifyValue for FloatVarValue {}
+impl UnifyValue for FloatVarValue {
+    type Error = NoError;
+
+    fn unify_values(value1: &Self, value2: &Self) -> Result<Self, Self::Error> {
+        match (*value1, *value2) {
+            (FloatVarValue::Unknown, FloatVarValue::Unknown) => Ok(FloatVarValue::Unknown),
+            (FloatVarValue::Unknown, FloatVarValue::Known(known))
+            | (FloatVarValue::Known(known), FloatVarValue::Unknown) => {
+                Ok(FloatVarValue::Known(known))
+            }
+            (FloatVarValue::Known(_), FloatVarValue::Known(_)) => {
+                panic!("differing floats should have been resolved first")
+            }
+        }
+    }
+}
 
 #[cfg(feature = "nightly")]
 impl UnifyKey for FloatVid {
-    type Value = Option<FloatVarValue>;
+    type Value = FloatVarValue;
     #[inline]
     fn index(&self) -> u32 {
         self.as_u32()
@@ -860,21 +922,6 @@ impl<CTX> HashStable<CTX> for InferTy {
     }
 }
 
-impl fmt::Debug for IntVarValue {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        match *self {
-            IntVarValue::IntType(ref v) => v.fmt(f),
-            IntVarValue::UintType(ref v) => v.fmt(f),
-        }
-    }
-}
-
-impl fmt::Debug for FloatVarValue {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        self.0.fmt(f)
-    }
-}
-
 impl fmt::Display for InferTy {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         use InferTy::*;
diff --git a/tests/ui/parser/recover/recover-range-pats.stderr b/tests/ui/parser/recover/recover-range-pats.stderr
index e0ea8ec24dc..e29b6c1c666 100644
--- a/tests/ui/parser/recover/recover-range-pats.stderr
+++ b/tests/ui/parser/recover/recover-range-pats.stderr
@@ -316,9 +316,6 @@ LL |     if let X.. .0 = 0 {}
    |            |   |
    |            |   expected `u8`, found floating-point number
    |            this is of type `u8`
-   |
-   = note: expected type `u8`
-              found type `{float}`
 
 error[E0029]: only `char` and numeric types are allowed in range patterns
   --> $DIR/recover-range-pats.rs:31:12
@@ -353,9 +350,6 @@ LL |     if let X..=.0 = 0 {}
    |            |   |
    |            |   expected `u8`, found floating-point number
    |            this is of type `u8`
-   |
-   = note: expected type `u8`
-              found type `{float}`
 
 error[E0029]: only `char` and numeric types are allowed in range patterns
   --> $DIR/recover-range-pats.rs:52:12
@@ -390,9 +384,6 @@ LL |     if let X... .0 = 0 {}
    |            |    |
    |            |    expected `u8`, found floating-point number
    |            this is of type `u8`
-   |
-   = note: expected type `u8`
-              found type `{float}`
 
 error[E0029]: only `char` and numeric types are allowed in range patterns
   --> $DIR/recover-range-pats.rs:71:12