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.rs40
1 files changed, 23 insertions, 17 deletions
diff --git a/crates/hir-ty/src/infer/cast.rs b/crates/hir-ty/src/infer/cast.rs
index c128977d7b..d073b06ccc 100644
--- a/crates/hir-ty/src/infer/cast.rs
+++ b/crates/hir-ty/src/infer/cast.rs
@@ -4,14 +4,14 @@ use hir_def::{AdtId, hir::ExprId, signatures::TraitFlags};
use rustc_ast_ir::Mutability;
use rustc_type_ir::{
Flags, InferTy, TypeFlags, UintTy,
- inherent::{AdtDef, BoundExistentialPredicates as _, IntoKind, SliceLike, Ty as _},
+ inherent::{AdtDef, BoundExistentialPredicates as _, IntoKind, Ty as _},
};
use stdx::never;
use crate::{
InferenceDiagnostic,
db::HirDatabase,
- infer::{AllowTwoPhase, InferenceContext, coerce::CoerceNever},
+ infer::{AllowTwoPhase, InferenceContext, expr::ExprIsRead},
next_solver::{BoundExistentialPredicates, DbInterner, ParamTy, Ty, TyKind},
};
@@ -83,8 +83,13 @@ impl CastError {
expr: ExprId,
expr_ty: Ty<'db>,
cast_ty: Ty<'db>,
- ) -> InferenceDiagnostic<'db> {
- InferenceDiagnostic::InvalidCast { expr, error: self, expr_ty, cast_ty }
+ ) -> InferenceDiagnostic {
+ InferenceDiagnostic::InvalidCast {
+ expr,
+ error: self,
+ expr_ty: expr_ty.store(),
+ cast_ty: cast_ty.store(),
+ }
}
}
@@ -109,9 +114,9 @@ impl<'db> CastCheck<'db> {
pub(super) fn check(
&mut self,
ctx: &mut InferenceContext<'_, 'db>,
- ) -> Result<(), InferenceDiagnostic<'db>> {
- self.expr_ty = ctx.table.eagerly_normalize_and_resolve_shallow_in(self.expr_ty);
- self.cast_ty = ctx.table.eagerly_normalize_and_resolve_shallow_in(self.cast_ty);
+ ) -> 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);
// This should always come first so that we apply the coercion, which impacts infer vars.
if ctx
@@ -120,7 +125,7 @@ impl<'db> CastCheck<'db> {
self.expr_ty,
self.cast_ty,
AllowTwoPhase::No,
- CoerceNever::Yes,
+ ExprIsRead::Yes,
)
.is_ok()
{
@@ -137,7 +142,7 @@ impl<'db> CastCheck<'db> {
{
return Err(InferenceDiagnostic::CastToUnsized {
expr: self.expr,
- cast_ty: self.cast_ty,
+ cast_ty: self.cast_ty.store(),
});
}
@@ -159,7 +164,7 @@ impl<'db> CastCheck<'db> {
TyKind::FnDef(..) => {
let sig =
self.expr_ty.callable_sig(ctx.interner()).expect("FnDef had no sig");
- let sig = ctx.table.eagerly_normalize_and_resolve_shallow_in(sig);
+ let sig = ctx.table.normalize_associated_types_in(sig);
let fn_ptr = Ty::new_fn_ptr(ctx.interner(), sig);
if ctx
.coerce(
@@ -167,7 +172,7 @@ impl<'db> CastCheck<'db> {
self.expr_ty,
fn_ptr,
AllowTwoPhase::No,
- CoerceNever::Yes,
+ ExprIsRead::Yes,
)
.is_ok()
{
@@ -191,7 +196,7 @@ impl<'db> CastCheck<'db> {
},
// array-ptr-cast
CastTy::Ptr(t, m) => {
- let t = ctx.table.eagerly_normalize_and_resolve_shallow_in(t);
+ let t = ctx.table.try_structurally_resolve_type(t);
if !ctx.table.is_sized(t) {
return Err(CastError::IllegalCast);
}
@@ -248,7 +253,7 @@ impl<'db> CastCheck<'db> {
self.expr_ty,
array_ptr_type,
AllowTwoPhase::No,
- CoerceNever::Yes,
+ ExprIsRead::Yes,
)
.is_ok()
{
@@ -263,7 +268,7 @@ impl<'db> CastCheck<'db> {
// This is a less strict condition than rustc's `demand_eqtype`,
// but false negative is better than false positive
if ctx
- .coerce(self.source_expr.into(), ety, t_cast, AllowTwoPhase::No, CoerceNever::Yes)
+ .coerce(self.source_expr.into(), ety, t_cast, AllowTwoPhase::No, ExprIsRead::Yes)
.is_ok()
{
return Ok(());
@@ -375,7 +380,7 @@ fn pointer_kind<'db>(
ty: Ty<'db>,
ctx: &mut InferenceContext<'_, 'db>,
) -> Result<Option<PointerKind<'db>>, ()> {
- let ty = ctx.table.eagerly_normalize_and_resolve_shallow_in(ty);
+ let ty = ctx.table.try_structurally_resolve_type(ty);
if ctx.table.is_sized(ty) {
return Ok(Some(PointerKind::Thin));
@@ -393,8 +398,9 @@ fn pointer_kind<'db>(
let struct_data = id.fields(ctx.db);
if let Some((last_field, _)) = struct_data.fields().iter().last() {
- let last_field_ty =
- ctx.db.field_types(id.into())[last_field].instantiate(ctx.interner(), subst);
+ let last_field_ty = ctx.db.field_types(id.into())[last_field]
+ .get()
+ .instantiate(ctx.interner(), subst);
pointer_kind(last_field_ty, ctx)
} else {
Ok(Some(PointerKind::Thin))