mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-27 21:43:37 +00:00
fix: Properly prevent mir building with unknown types present
This commit is contained in:
parent
fdac69e4ae
commit
7c5275939a
3 changed files with 14 additions and 5 deletions
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
|
|
Loading…
Reference in a new issue