Skip to content

Commit fcd3a6b

Browse files
committed
Auto merge of rust-lang#14891 - HKalbasi:dev, r=HKalbasi
Evaluate `UnevaluatedConst` in unify fix rust-lang#14844
2 parents efd3094 + 7ef185d commit fcd3a6b

File tree

4 files changed

+89
-1
lines changed

4 files changed

+89
-1
lines changed

crates/hir-ty/src/infer/expr.rs

+3
Original file line numberDiff line numberDiff line change
@@ -575,6 +575,9 @@ impl<'a> InferenceContext<'a> {
575575
let field_ty = field_def.map_or(self.err_ty(), |it| {
576576
field_types[it.local_id].clone().substitute(Interner, &substs)
577577
});
578+
// Field type might have some unknown types
579+
// FIXME: we may want to emit a single type variable for all instance of type fields?
580+
let field_ty = self.insert_type_vars(field_ty);
578581
self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty));
579582
}
580583
if let Some(expr) = spread {

crates/hir-ty/src/infer/unify.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -781,8 +781,16 @@ impl<'a> InferenceTable<'a> {
781781
pub(super) fn insert_const_vars_shallow(&mut self, c: Const) -> Const {
782782
let data = c.data(Interner);
783783
match &data.value {
784-
ConstValue::Concrete(cc) => match cc.interned {
784+
ConstValue::Concrete(cc) => match &cc.interned {
785785
crate::ConstScalar::Unknown => self.new_const_var(data.ty.clone()),
786+
// try to evaluate unevaluated const. Replace with new var if const eval failed.
787+
crate::ConstScalar::UnevaluatedConst(id, subst) => {
788+
if let Ok(eval) = self.db.const_eval(*id, subst.clone()) {
789+
eval
790+
} else {
791+
self.new_const_var(data.ty.clone())
792+
}
793+
}
786794
_ => c,
787795
},
788796
_ => c,

crates/hir-ty/src/tests/regression.rs

+55
Original file line numberDiff line numberDiff line change
@@ -1837,3 +1837,58 @@ fn foo() {
18371837
}",
18381838
);
18391839
}
1840+
1841+
#[test]
1842+
fn regression_14844() {
1843+
check_no_mismatches(
1844+
r#"
1845+
pub type Ty = Unknown;
1846+
1847+
pub struct Inner<T>();
1848+
1849+
pub struct Outer {
1850+
pub inner: Inner<Ty>,
1851+
}
1852+
1853+
fn main() {
1854+
_ = Outer {
1855+
inner: Inner::<i32>(),
1856+
};
1857+
}
1858+
"#,
1859+
);
1860+
check_no_mismatches(
1861+
r#"
1862+
pub const ONE: usize = 1;
1863+
1864+
pub struct Inner<const P: usize>();
1865+
1866+
pub struct Outer {
1867+
pub inner: Inner<ONE>,
1868+
}
1869+
1870+
fn main() {
1871+
_ = Outer {
1872+
inner: Inner::<1>(),
1873+
};
1874+
}
1875+
"#,
1876+
);
1877+
check_no_mismatches(
1878+
r#"
1879+
pub const ONE: usize = unknown();
1880+
1881+
pub struct Inner<const P: usize>();
1882+
1883+
pub struct Outer {
1884+
pub inner: Inner<ONE>,
1885+
}
1886+
1887+
fn main() {
1888+
_ = Outer {
1889+
inner: Inner::<1>(),
1890+
};
1891+
}
1892+
"#,
1893+
);
1894+
}

crates/ide-diagnostics/src/handlers/type_mismatch.rs

+22
Original file line numberDiff line numberDiff line change
@@ -644,6 +644,28 @@ fn h() {
644644
);
645645
}
646646

647+
#[test]
648+
fn evaluate_const_generics_in_types() {
649+
check_diagnostics(
650+
r#"
651+
pub const ONE: usize = 1;
652+
653+
pub struct Inner<const P: usize>();
654+
655+
pub struct Outer {
656+
pub inner: Inner<ONE>,
657+
}
658+
659+
fn main() {
660+
_ = Outer {
661+
inner: Inner::<2>(),
662+
//^^^^^^^^^^^^ error: expected Inner<1>, found Inner<2>
663+
};
664+
}
665+
"#,
666+
);
667+
}
668+
647669
#[test]
648670
fn type_mismatch_pat_smoke_test() {
649671
check_diagnostics(

0 commit comments

Comments
 (0)