fix: Properly prevent mir building with unknown types present

This commit is contained in:
Lukas Wirth 2024-09-06 14:44:05 +02:00
parent fdac69e4ae
commit 7c5275939a
3 changed files with 14 additions and 5 deletions

View file

@ -708,7 +708,6 @@ impl<'a> InferenceContext<'a> {
tuple_field_access_types: _, tuple_field_access_types: _,
coercion_casts, coercion_casts,
} = &mut result; } = &mut result;
table.fallback_if_possible(); table.fallback_if_possible();
// Comment from rustc: // Comment from rustc:
@ -754,7 +753,7 @@ impl<'a> InferenceContext<'a> {
*has_errors = *has_errors || ty.contains_unknown(); *has_errors = *has_errors || ty.contains_unknown();
} }
*has_errors = !type_mismatches.is_empty(); *has_errors |= !type_mismatches.is_empty();
type_mismatches.retain(|_, mismatch| { type_mismatches.retain(|_, mismatch| {
mismatch.expected = table.resolve_completely(mismatch.expected.clone()); mismatch.expected = table.resolve_completely(mismatch.expected.clone());
@ -797,20 +796,30 @@ impl<'a> InferenceContext<'a> {
}); });
for (_, subst) in method_resolutions.values_mut() { for (_, subst) in method_resolutions.values_mut() {
*subst = table.resolve_completely(subst.clone()); *subst = table.resolve_completely(subst.clone());
*has_errors =
*has_errors || subst.type_parameters(Interner).any(|ty| ty.contains_unknown());
} }
for (_, subst) in assoc_resolutions.values_mut() { for (_, subst) in assoc_resolutions.values_mut() {
*subst = table.resolve_completely(subst.clone()); *subst = table.resolve_completely(subst.clone());
*has_errors =
*has_errors || subst.type_parameters(Interner).any(|ty| ty.contains_unknown());
} }
for adjustment in expr_adjustments.values_mut().flatten() { for adjustment in expr_adjustments.values_mut().flatten() {
adjustment.target = table.resolve_completely(adjustment.target.clone()); adjustment.target = table.resolve_completely(adjustment.target.clone());
*has_errors = *has_errors || adjustment.target.contains_unknown();
} }
for adjustment in pat_adjustments.values_mut().flatten() { for adjustment in pat_adjustments.values_mut().flatten() {
*adjustment = table.resolve_completely(adjustment.clone()); *adjustment = table.resolve_completely(adjustment.clone());
*has_errors = *has_errors || adjustment.contains_unknown();
} }
result.tuple_field_access_types = tuple_field_accesses_rev result.tuple_field_access_types = tuple_field_accesses_rev
.into_iter() .into_iter()
.enumerate() .enumerate()
.map(|(idx, subst)| (TupleId(idx as u32), table.resolve_completely(subst))) .map(|(idx, subst)| (TupleId(idx as u32), table.resolve_completely(subst)))
.inspect(|(_, subst)| {
*has_errors =
*has_errors || subst.type_parameters(Interner).any(|ty| ty.contains_unknown());
})
.collect(); .collect();
result result
} }

View file

@ -185,8 +185,8 @@ impl<V, T> ProjectionElem<V, T> {
never!("Out of bound tuple field"); never!("Out of bound tuple field");
TyKind::Error.intern(Interner) TyKind::Error.intern(Interner)
}), }),
_ => { ty => {
never!("Only tuple has tuple field"); never!("Only tuple has tuple field: {:?}", ty);
TyKind::Error.intern(Interner) TyKind::Error.intern(Interner)
} }
}, },

View file

@ -824,13 +824,13 @@ fn f() {
#[test] #[test]
fn or_pattern() { fn or_pattern() {
// FIXME: `None` is inferred as unknown here for some reason
check_diagnostics( check_diagnostics(
r#" r#"
//- minicore: option //- minicore: option
fn f(_: i32) {} fn f(_: i32) {}
fn main() { fn main() {
let ((Some(mut x), None) | (_, Some(mut x))) = (None, Some(7)) else { return }; let ((Some(mut x), None) | (_, Some(mut x))) = (None, Some(7)) else { return };
//^^^^^ 💡 warn: variable does not need to be mutable
f(x); f(x);
} }
"#, "#,