Unnamed repository; edit this file 'description' to name the repository.
Auto merge of #14891 - HKalbasi:dev, r=HKalbasi
Evaluate `UnevaluatedConst` in unify fix #14844
bors 2023-05-25
parent efd3094 · parent 7ef185d · commit fcd3a6b
-rw-r--r--crates/hir-ty/src/infer/expr.rs3
-rw-r--r--crates/hir-ty/src/infer/unify.rs10
-rw-r--r--crates/hir-ty/src/tests/regression.rs55
-rw-r--r--crates/ide-diagnostics/src/handlers/type_mismatch.rs22
4 files changed, 89 insertions, 1 deletions
diff --git a/crates/hir-ty/src/infer/expr.rs b/crates/hir-ty/src/infer/expr.rs
index b800c2e32a..7772fab796 100644
--- a/crates/hir-ty/src/infer/expr.rs
+++ b/crates/hir-ty/src/infer/expr.rs
@@ -575,6 +575,9 @@ impl<'a> InferenceContext<'a> {
let field_ty = field_def.map_or(self.err_ty(), |it| {
field_types[it.local_id].clone().substitute(Interner, &substs)
});
+ // Field type might have some unknown types
+ // FIXME: we may want to emit a single type variable for all instance of type fields?
+ let field_ty = self.insert_type_vars(field_ty);
self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty));
}
if let Some(expr) = spread {
diff --git a/crates/hir-ty/src/infer/unify.rs b/crates/hir-ty/src/infer/unify.rs
index 21b962a48f..38eae475b5 100644
--- a/crates/hir-ty/src/infer/unify.rs
+++ b/crates/hir-ty/src/infer/unify.rs
@@ -781,8 +781,16 @@ impl<'a> InferenceTable<'a> {
pub(super) fn insert_const_vars_shallow(&mut self, c: Const) -> Const {
let data = c.data(Interner);
match &data.value {
- ConstValue::Concrete(cc) => match cc.interned {
+ ConstValue::Concrete(cc) => match &cc.interned {
crate::ConstScalar::Unknown => self.new_const_var(data.ty.clone()),
+ // try to evaluate unevaluated const. Replace with new var if const eval failed.
+ crate::ConstScalar::UnevaluatedConst(id, subst) => {
+ if let Ok(eval) = self.db.const_eval(*id, subst.clone()) {
+ eval
+ } else {
+ self.new_const_var(data.ty.clone())
+ }
+ }
_ => c,
},
_ => c,
diff --git a/crates/hir-ty/src/tests/regression.rs b/crates/hir-ty/src/tests/regression.rs
index 9f5f1ea325..259f43e7e2 100644
--- a/crates/hir-ty/src/tests/regression.rs
+++ b/crates/hir-ty/src/tests/regression.rs
@@ -1837,3 +1837,58 @@ fn foo() {
}",
);
}
+
+#[test]
+fn regression_14844() {
+ check_no_mismatches(
+ r#"
+pub type Ty = Unknown;
+
+pub struct Inner<T>();
+
+pub struct Outer {
+ pub inner: Inner<Ty>,
+}
+
+fn main() {
+ _ = Outer {
+ inner: Inner::<i32>(),
+ };
+}
+ "#,
+ );
+ check_no_mismatches(
+ r#"
+pub const ONE: usize = 1;
+
+pub struct Inner<const P: usize>();
+
+pub struct Outer {
+ pub inner: Inner<ONE>,
+}
+
+fn main() {
+ _ = Outer {
+ inner: Inner::<1>(),
+ };
+}
+ "#,
+ );
+ check_no_mismatches(
+ r#"
+pub const ONE: usize = unknown();
+
+pub struct Inner<const P: usize>();
+
+pub struct Outer {
+ pub inner: Inner<ONE>,
+}
+
+fn main() {
+ _ = Outer {
+ inner: Inner::<1>(),
+ };
+}
+ "#,
+ );
+}
diff --git a/crates/ide-diagnostics/src/handlers/type_mismatch.rs b/crates/ide-diagnostics/src/handlers/type_mismatch.rs
index a5359741ac..cc282bf934 100644
--- a/crates/ide-diagnostics/src/handlers/type_mismatch.rs
+++ b/crates/ide-diagnostics/src/handlers/type_mismatch.rs
@@ -645,6 +645,28 @@ fn h() {
}
#[test]
+ fn evaluate_const_generics_in_types() {
+ check_diagnostics(
+ r#"
+pub const ONE: usize = 1;
+
+pub struct Inner<const P: usize>();
+
+pub struct Outer {
+ pub inner: Inner<ONE>,
+}
+
+fn main() {
+ _ = Outer {
+ inner: Inner::<2>(),
+ //^^^^^^^^^^^^ error: expected Inner<1>, found Inner<2>
+ };
+}
+"#,
+ );
+ }
+
+ #[test]
fn type_mismatch_pat_smoke_test() {
check_diagnostics(
r#"