mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-27 13:33:31 +00:00
evaluate UnevaluatedConst
in unify
This commit is contained in:
parent
efd3094aba
commit
7ef185d65e
4 changed files with 89 additions and 1 deletions
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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>(),
|
||||
};
|
||||
}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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(
|
||||
|
|
Loading…
Reference in a new issue