Skip to content

Commit

Permalink
Auto merge of rust-lang#14891 - HKalbasi:dev, r=HKalbasi
Browse files Browse the repository at this point in the history
Evaluate `UnevaluatedConst` in unify

fix rust-lang#14844
  • Loading branch information
bors committed May 25, 2023
2 parents efd3094 + 7ef185d commit fcd3a6b
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 1 deletion.
3 changes: 3 additions & 0 deletions crates/hir-ty/src/infer/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
10 changes: 9 additions & 1 deletion crates/hir-ty/src/infer/unify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
55 changes: 55 additions & 0 deletions crates/hir-ty/src/tests/regression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>(),
};
}
"#,
);
}
22 changes: 22 additions & 0 deletions crates/ide-diagnostics/src/handlers/type_mismatch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -644,6 +644,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(
Expand Down

0 comments on commit fcd3a6b

Please sign in to comment.