Properly infer types with type casts

This commit is contained in:
Ryo Yoshida 2023-07-12 23:46:23 +09:00
parent 75ac37f317
commit 074488b290
No known key found for this signature in database
GPG key ID: E25698A930586171
5 changed files with 112 additions and 28 deletions

View file

@ -46,8 +46,8 @@ use crate::{
};
use super::{
coerce::auto_deref_adjust_steps, find_breakable, BreakableContext, Diverges, Expectation,
InferenceContext, InferenceDiagnostic, TypeMismatch,
cast::CastCheck, coerce::auto_deref_adjust_steps, find_breakable, BreakableContext, Diverges,
Expectation, InferenceContext, InferenceDiagnostic, TypeMismatch,
};
impl InferenceContext<'_> {
@ -574,16 +574,8 @@ impl InferenceContext<'_> {
}
Expr::Cast { expr, type_ref } => {
let cast_ty = self.make_ty(type_ref);
// FIXME: propagate the "castable to" expectation
let inner_ty = self.infer_expr_no_expect(*expr);
match (inner_ty.kind(Interner), cast_ty.kind(Interner)) {
(TyKind::Ref(_, _, inner), TyKind::Raw(_, cast)) => {
// FIXME: record invalid cast diagnostic in case of mismatch
self.unify(inner, cast);
}
// FIXME check the other kinds of cast...
_ => (),
}
let expr_ty = self.infer_expr(*expr, &Expectation::Castable(cast_ty.clone()));
self.deferred_cast_checks.push(CastCheck::new(expr_ty, cast_ty.clone()));
cast_ty
}
Expr::Ref { expr, rawness, mutability } => {
@ -1592,7 +1584,7 @@ impl InferenceContext<'_> {
output: Ty,
inputs: Vec<Ty>,
) -> Vec<Ty> {
if let Some(expected_ty) = expected_output.to_option(&mut self.table) {
if let Some(expected_ty) = expected_output.only_has_type(&mut self.table) {
self.table.fudge_inference(|table| {
if table.try_unify(&expected_ty, &output).is_ok() {
table.resolve_with_fallback(inputs, &|var, kind, _, _| match kind {