mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-25 11:17:13 +00:00
Merge pull request #20561 from ChayimFriedman2/no-table-for-you
minor: Don't require a full `InferenceTable` for `CastTy`
This commit is contained in:
commit
6e59defe11
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user