Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/infer/cast.rs')
-rw-r--r--crates/hir-ty/src/infer/cast.rs51
1 files changed, 28 insertions, 23 deletions
diff --git a/crates/hir-ty/src/infer/cast.rs b/crates/hir-ty/src/infer/cast.rs
index e5ee734474..93aed344d4 100644
--- a/crates/hir-ty/src/infer/cast.rs
+++ b/crates/hir-ty/src/infer/cast.rs
@@ -10,7 +10,7 @@ use rustc_hash::FxHashSet;
use rustc_type_ir::{
InferTy, TypeVisitableExt, UintTy, elaborate,
error::TypeError,
- inherent::{AdtDef, BoundExistentialPredicates as _, IntoKind, Ty as _},
+ inherent::{BoundExistentialPredicates as _, IntoKind, Ty as _},
};
use stdx::never;
@@ -125,13 +125,14 @@ impl<'db> CastCheck<'db> {
&mut self,
ctx: &mut InferenceContext<'_, 'db>,
) -> Result<(), InferenceDiagnostic> {
- self.expr_ty = ctx.table.try_structurally_resolve_type(self.expr_ty);
- self.cast_ty = ctx.table.try_structurally_resolve_type(self.cast_ty);
+ self.expr_ty =
+ ctx.table.try_structurally_resolve_type(self.source_expr.into(), self.expr_ty);
+ self.cast_ty = ctx.table.try_structurally_resolve_type(self.expr.into(), self.cast_ty);
// This should always come first so that we apply the coercion, which impacts infer vars.
if ctx
.coerce(
- self.source_expr.into(),
+ self.source_expr,
self.expr_ty,
self.cast_ty,
AllowTwoPhase::No,
@@ -147,7 +148,8 @@ impl<'db> CastCheck<'db> {
return Ok(());
}
- if !self.cast_ty.has_infer_types() && !ctx.table.is_sized(self.cast_ty) {
+ if !self.cast_ty.has_infer_types() && !ctx.table.type_is_sized_modulo_regions(self.cast_ty)
+ {
return Err(InferenceDiagnostic::CastToUnsized {
expr: self.expr,
cast_ty: self.cast_ty.store(),
@@ -167,7 +169,7 @@ impl<'db> CastCheck<'db> {
let sig = self.expr_ty.fn_sig(ctx.interner());
let fn_ptr = Ty::new_fn_ptr(ctx.interner(), sig);
match ctx.coerce(
- self.source_expr.into(),
+ self.source_expr,
self.expr_ty,
fn_ptr,
AllowTwoPhase::No,
@@ -198,8 +200,9 @@ impl<'db> CastCheck<'db> {
},
// array-ptr-cast
CastTy::Ptr(t, m) => {
- let t = ctx.table.try_structurally_resolve_type(t);
- if !ctx.table.is_sized(t) {
+ let t =
+ ctx.table.try_structurally_resolve_type(self.expr.into(), t);
+ if !ctx.table.type_is_sized_modulo_regions(t) {
return Err(CastError::IllegalCast);
}
self.check_ref_cast(ctx, inner_ty, mutbl, t, m)
@@ -261,8 +264,8 @@ impl<'db> CastCheck<'db> {
t_cast: Ty<'db>,
m_cast: Mutability,
) -> Result<(), CastError> {
- let t_expr = ctx.table.try_structurally_resolve_type(t_expr);
- let t_cast = ctx.table.try_structurally_resolve_type(t_cast);
+ let t_expr = ctx.table.try_structurally_resolve_type(self.expr.into(), t_expr);
+ let t_cast = ctx.table.try_structurally_resolve_type(self.expr.into(), t_cast);
if m_expr >= m_cast
&& let TyKind::Array(ety, _) = t_expr.kind()
@@ -275,7 +278,7 @@ impl<'db> CastCheck<'db> {
let array_ptr_type = Ty::new_ptr(ctx.interner(), t_expr, m_expr);
if ctx
.coerce(
- self.source_expr.into(),
+ self.source_expr,
self.expr_ty,
array_ptr_type,
AllowTwoPhase::No,
@@ -305,8 +308,8 @@ impl<'db> CastCheck<'db> {
src: Ty<'db>,
dst: Ty<'db>,
) -> Result<(), CastError> {
- let src_kind = pointer_kind(src, ctx).map_err(|_| CastError::Unknown)?;
- let dst_kind = pointer_kind(dst, ctx).map_err(|_| CastError::Unknown)?;
+ let src_kind = pointer_kind(self.expr, src, ctx).map_err(|_| CastError::Unknown)?;
+ let dst_kind = pointer_kind(self.expr, dst, ctx).map_err(|_| CastError::Unknown)?;
match (src_kind, dst_kind) {
(Some(PointerKind::Error), _) | (_, Some(PointerKind::Error)) => Ok(()),
@@ -371,7 +374,7 @@ impl<'db> CastCheck<'db> {
// This is `fcx.demand_eqtype`, but inlined to give a better error.
if ctx
.table
- .at(&ObligationCause::dummy())
+ .at(&ObligationCause::new(self.expr))
.eq(src_obj, dst_obj)
.map(|infer_ok| ctx.table.register_infer_ok(infer_ok))
.is_err()
@@ -456,7 +459,7 @@ impl<'db> CastCheck<'db> {
ctx: &mut InferenceContext<'_, 'db>,
expr_ty: Ty<'db>,
) -> Result<(), CastError> {
- match pointer_kind(expr_ty, ctx).map_err(|_| CastError::Unknown)? {
+ match pointer_kind(self.expr, expr_ty, ctx).map_err(|_| CastError::Unknown)? {
// None => Err(CastError::UnknownExprPtrKind),
None => Ok(()),
Some(PointerKind::Error) => Ok(()),
@@ -470,7 +473,7 @@ impl<'db> CastCheck<'db> {
ctx: &mut InferenceContext<'_, 'db>,
cast_ty: Ty<'db>,
) -> Result<(), CastError> {
- match pointer_kind(cast_ty, ctx).map_err(|_| CastError::Unknown)? {
+ match pointer_kind(self.expr, cast_ty, ctx).map_err(|_| CastError::Unknown)? {
// None => Err(CastError::UnknownCastPtrKind),
None => Ok(()),
Some(PointerKind::Error) => Ok(()),
@@ -486,7 +489,7 @@ impl<'db> CastCheck<'db> {
ctx: &mut InferenceContext<'_, 'db>,
cast_ty: Ty<'db>,
) -> Result<(), CastError> {
- match pointer_kind(cast_ty, ctx).map_err(|_| CastError::Unknown)? {
+ match pointer_kind(self.expr, cast_ty, ctx).map_err(|_| CastError::Unknown)? {
// None => Err(CastError::UnknownCastPtrKind),
None => Ok(()),
Some(PointerKind::Error) => Ok(()),
@@ -515,12 +518,13 @@ enum PointerKind<'db> {
}
fn pointer_kind<'db>(
+ expr: ExprId,
ty: Ty<'db>,
ctx: &mut InferenceContext<'_, 'db>,
) -> Result<Option<PointerKind<'db>>, ()> {
- let ty = ctx.table.try_structurally_resolve_type(ty);
+ let ty = ctx.table.try_structurally_resolve_type(expr.into(), ty);
- if ctx.table.is_sized(ty) {
+ if ctx.table.type_is_sized_modulo_regions(ty) {
return Ok(Some(PointerKind::Thin));
}
@@ -528,7 +532,7 @@ fn pointer_kind<'db>(
TyKind::Slice(_) | TyKind::Str => Ok(Some(PointerKind::Length)),
TyKind::Dynamic(bounds, _) => Ok(Some(PointerKind::VTable(bounds))),
TyKind::Adt(adt_def, subst) => {
- let id = adt_def.def_id().0;
+ let id = adt_def.def_id();
let AdtId::StructId(id) = id else {
never!("`{:?}` should be sized but is not?", ty);
return Err(());
@@ -538,15 +542,16 @@ fn pointer_kind<'db>(
if let Some((last_field, _)) = struct_data.fields().iter().last() {
let last_field_ty = ctx.db.field_types(id.into())[last_field]
.get()
- .instantiate(ctx.interner(), subst);
- pointer_kind(last_field_ty, ctx)
+ .instantiate(ctx.interner(), subst)
+ .skip_norm_wip();
+ pointer_kind(expr, last_field_ty, ctx)
} else {
Ok(Some(PointerKind::Thin))
}
}
TyKind::Tuple(subst) => match subst.iter().next_back() {
None => Ok(Some(PointerKind::Thin)),
- Some(ty) => pointer_kind(ty, ctx),
+ Some(ty) => pointer_kind(expr, ty, ctx),
},
TyKind::Foreign(_) => Ok(Some(PointerKind::Thin)),
TyKind::Alias(..) => Ok(Some(PointerKind::OfAlias)),