about summary refs log tree commit diff
diff options
context:
space:
mode:
authorChayim Refael Friedman <chayimfr@gmail.com>2025-08-28 19:24:46 +0300
committerChayim Refael Friedman <chayimfr@gmail.com>2025-08-28 19:24:46 +0300
commitc36b75bdc8634f0d9cba824410df7a8c3785bda4 (patch)
tree480c651c7222b215880dca35b1db66c8407d7846
parentda33061e1c5384cfbf83bdca4be0a946badb779b (diff)
downloadrust-c36b75bdc8634f0d9cba824410df7a8c3785bda4.tar.gz
rust-c36b75bdc8634f0d9cba824410df7a8c3785bda4.zip
Don't require a full `InferenceTable` for `CastTy`
A DB is enough.
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/infer/cast.rs100
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs11
2 files changed, 52 insertions, 59 deletions
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/cast.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/cast.rs
index 09b983a580d..43364963eb0 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/cast.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/cast.rs
@@ -6,7 +6,9 @@ use stdx::never;
 
 use crate::{
     Adjustment, Binders, DynTy, InferenceDiagnostic, Interner, PlaceholderIndex,
-    QuantifiedWhereClauses, Ty, TyExt, TyKind, TypeFlags, WhereClause, from_chalk_trait_id,
+    QuantifiedWhereClauses, Ty, TyExt, TyKind, TypeFlags, WhereClause,
+    db::HirDatabase,
+    from_chalk_trait_id,
     infer::{coerce::CoerceNever, unify::InferenceTable},
 };
 
@@ -30,7 +32,7 @@ pub(crate) enum CastTy {
 }
 
 impl CastTy {
-    pub(crate) fn from_ty(table: &mut InferenceTable<'_>, t: &Ty) -> Option<Self> {
+    pub(crate) fn from_ty(db: &dyn HirDatabase, t: &Ty) -> Option<Self> {
         match t.kind(Interner) {
             TyKind::Scalar(Scalar::Bool) => Some(Self::Int(Int::Bool)),
             TyKind::Scalar(Scalar::Char) => Some(Self::Int(Int::Char)),
@@ -43,8 +45,8 @@ impl CastTy {
                 let (AdtId::EnumId(id), _) = t.as_adt()? else {
                     return None;
                 };
-                let enum_data = id.enum_variants(table.db);
-                if enum_data.is_payload_free(table.db) { Some(Self::Int(Int::CEnum)) } else { None }
+                let enum_data = id.enum_variants(db);
+                if enum_data.is_payload_free(db) { Some(Self::Int(Int::CEnum)) } else { None }
             }
             TyKind::Raw(m, ty) => Some(Self::Ptr(ty.clone(), *m)),
             TyKind::Function(_) => Some(Self::FnPtr),
@@ -142,58 +144,50 @@ impl CastCheck {
     where
         F: FnMut(ExprId, Vec<Adjustment>),
     {
-        let (t_from, t_cast) =
-            match (CastTy::from_ty(table, &self.expr_ty), CastTy::from_ty(table, &self.cast_ty)) {
-                (Some(t_from), Some(t_cast)) => (t_from, t_cast),
-                (None, Some(t_cast)) => match self.expr_ty.kind(Interner) {
-                    TyKind::FnDef(..) => {
-                        let sig = self.expr_ty.callable_sig(table.db).expect("FnDef had no sig");
-                        let sig = table.eagerly_normalize_and_resolve_shallow_in(sig);
-                        let fn_ptr = TyKind::Function(sig.to_fn_ptr()).intern(Interner);
-                        if let Ok((adj, _)) = table.coerce(&self.expr_ty, &fn_ptr, CoerceNever::Yes)
-                        {
-                            apply_adjustments(self.source_expr, adj);
-                        } else {
-                            return Err(CastError::IllegalCast);
-                        }
-
-                        (CastTy::FnPtr, t_cast)
+        let (t_from, t_cast) = match (
+            CastTy::from_ty(table.db, &self.expr_ty),
+            CastTy::from_ty(table.db, &self.cast_ty),
+        ) {
+            (Some(t_from), Some(t_cast)) => (t_from, t_cast),
+            (None, Some(t_cast)) => match self.expr_ty.kind(Interner) {
+                TyKind::FnDef(..) => {
+                    let sig = self.expr_ty.callable_sig(table.db).expect("FnDef had no sig");
+                    let sig = table.eagerly_normalize_and_resolve_shallow_in(sig);
+                    let fn_ptr = TyKind::Function(sig.to_fn_ptr()).intern(Interner);
+                    if let Ok((adj, _)) = table.coerce(&self.expr_ty, &fn_ptr, CoerceNever::Yes) {
+                        apply_adjustments(self.source_expr, adj);
+                    } else {
+                        return Err(CastError::IllegalCast);
                     }
-                    TyKind::Ref(mutbl, _, inner_ty) => {
-                        return match t_cast {
-                            CastTy::Int(_) | CastTy::Float => match inner_ty.kind(Interner) {
-                                TyKind::Scalar(
-                                    Scalar::Int(_) | Scalar::Uint(_) | Scalar::Float(_),
-                                )
-                                | TyKind::InferenceVar(
-                                    _,
-                                    TyVariableKind::Integer | TyVariableKind::Float,
-                                ) => Err(CastError::NeedDeref),
-
-                                _ => Err(CastError::NeedViaPtr),
-                            },
-                            // array-ptr-cast
-                            CastTy::Ptr(t, m) => {
-                                let t = table.eagerly_normalize_and_resolve_shallow_in(t);
-                                if !table.is_sized(&t) {
-                                    return Err(CastError::IllegalCast);
-                                }
-                                self.check_ref_cast(
-                                    table,
-                                    inner_ty,
-                                    *mutbl,
-                                    &t,
-                                    m,
-                                    apply_adjustments,
-                                )
+
+                    (CastTy::FnPtr, t_cast)
+                }
+                TyKind::Ref(mutbl, _, inner_ty) => {
+                    return match t_cast {
+                        CastTy::Int(_) | CastTy::Float => match inner_ty.kind(Interner) {
+                            TyKind::Scalar(Scalar::Int(_) | Scalar::Uint(_) | Scalar::Float(_))
+                            | TyKind::InferenceVar(
+                                _,
+                                TyVariableKind::Integer | TyVariableKind::Float,
+                            ) => Err(CastError::NeedDeref),
+
+                            _ => Err(CastError::NeedViaPtr),
+                        },
+                        // array-ptr-cast
+                        CastTy::Ptr(t, m) => {
+                            let t = table.eagerly_normalize_and_resolve_shallow_in(t);
+                            if !table.is_sized(&t) {
+                                return Err(CastError::IllegalCast);
                             }
-                            _ => Err(CastError::NonScalar),
-                        };
-                    }
-                    _ => return Err(CastError::NonScalar),
-                },
+                            self.check_ref_cast(table, inner_ty, *mutbl, &t, m, apply_adjustments)
+                        }
+                        _ => Err(CastError::NonScalar),
+                    };
+                }
                 _ => return Err(CastError::NonScalar),
-            };
+            },
+            _ => return Err(CastError::NonScalar),
+        };
 
         // rustc checks whether the `expr_ty` is foreign adt with `non_exhaustive` sym
 
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs
index 8c03ca939e3..2d53d16c57a 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs
@@ -31,7 +31,7 @@ use crate::{
     display::{DisplayTarget, HirDisplay, hir_display_with_store},
     error_lifetime,
     generics::generics,
-    infer::{CaptureKind, CapturedItem, TypeMismatch, cast::CastTy, unify::InferenceTable},
+    infer::{CaptureKind, CapturedItem, TypeMismatch, cast::CastTy},
     inhabitedness::is_ty_uninhabited_from,
     layout::LayoutError,
     mapping::ToChalk,
@@ -948,8 +948,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
                     let cast_kind = if source_ty.as_reference().is_some() {
                         CastKind::PointerCoercion(PointerCast::ArrayToPointer)
                     } else {
-                        let mut table = InferenceTable::new(self.db, self.env.clone());
-                        cast_kind(&mut table, &source_ty, &target_ty)?
+                        cast_kind(self.db, &source_ty, &target_ty)?
                     };
 
                     Rvalue::Cast(cast_kind, it, target_ty)
@@ -2017,9 +2016,9 @@ impl<'ctx> MirLowerCtx<'ctx> {
     }
 }
 
-fn cast_kind(table: &mut InferenceTable<'_>, source_ty: &Ty, target_ty: &Ty) -> Result<CastKind> {
-    let from = CastTy::from_ty(table, source_ty);
-    let cast = CastTy::from_ty(table, target_ty);
+fn cast_kind(db: &dyn HirDatabase, source_ty: &Ty, target_ty: &Ty) -> Result<CastKind> {
+    let from = CastTy::from_ty(db, source_ty);
+    let cast = CastTy::from_ty(db, target_ty);
     Ok(match (from, cast) {
         (Some(CastTy::Ptr(..) | CastTy::FnPtr), Some(CastTy::Int(_))) => {
             CastKind::PointerExposeAddress