Skip to content

Commit 23dd54b

Browse files
committed
Auto merge of rust-lang#16968 - roife:fix-issue-16801, r=Veykril
fix: silence mismatches involving unresolved projections fix rust-lang#16801
2 parents 3691380 + 2636e44 commit 23dd54b

File tree

4 files changed

+45
-11
lines changed

4 files changed

+45
-11
lines changed

crates/hir-ty/src/infer.rs

+17-4
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,8 @@ pub struct InferenceResult {
429429
/// Type of the result of `.into_iter()` on the for. `ExprId` is the one of the whole for loop.
430430
pub type_of_for_iterator: FxHashMap<ExprId, Ty>,
431431
type_mismatches: FxHashMap<ExprOrPatId, TypeMismatch>,
432+
/// Whether there are any type-mismatching errors in the result.
433+
pub(crate) has_errors: bool,
432434
/// Interned common types to return references to.
433435
standard_types: InternedStandardTypes,
434436
/// Stores the types which were implicitly dereferenced in pattern binding modes.
@@ -654,6 +656,7 @@ impl<'a> InferenceContext<'a> {
654656
type_of_rpit,
655657
type_of_for_iterator,
656658
type_mismatches,
659+
has_errors,
657660
standard_types: _,
658661
pat_adjustments,
659662
binding_modes: _,
@@ -695,6 +698,9 @@ impl<'a> InferenceContext<'a> {
695698
for ty in type_of_for_iterator.values_mut() {
696699
*ty = table.resolve_completely(ty.clone());
697700
}
701+
702+
*has_errors = !type_mismatches.is_empty();
703+
698704
type_mismatches.retain(|_, mismatch| {
699705
mismatch.expected = table.resolve_completely(mismatch.expected.clone());
700706
mismatch.actual = table.resolve_completely(mismatch.actual.clone());
@@ -1646,9 +1652,11 @@ impl std::ops::BitOrAssign for Diverges {
16461652
*self = *self | other;
16471653
}
16481654
}
1649-
/// A zipper that checks for unequal `{unknown}` occurrences in the two types. Used to filter out
1650-
/// mismatch diagnostics that only differ in `{unknown}`. These mismatches are usually not helpful.
1651-
/// As the cause is usually an underlying name resolution problem.
1655+
1656+
/// A zipper that checks for unequal occurrences of `{unknown}` and unresolved projections
1657+
/// in the two types. Used to filter out mismatch diagnostics that only differ in
1658+
/// `{unknown}` and unresolved projections. These mismatches are usually not helpful.
1659+
/// As the cause is usually an underlying name resolution problem
16521660
struct UnknownMismatch<'db>(&'db dyn HirDatabase);
16531661
impl chalk_ir::zip::Zipper<Interner> for UnknownMismatch<'_> {
16541662
fn zip_tys(&mut self, variance: Variance, a: &Ty, b: &Ty) -> chalk_ir::Fallible<()> {
@@ -1721,7 +1729,12 @@ impl chalk_ir::zip::Zipper<Interner> for UnknownMismatch<'_> {
17211729
zip_substs(self, None, &fn_ptr_a.substitution.0, &fn_ptr_b.substitution.0)?
17221730
}
17231731
(TyKind::Error, TyKind::Error) => (),
1724-
(TyKind::Error, _) | (_, TyKind::Error) => return Err(chalk_ir::NoSolution),
1732+
(TyKind::Error, _)
1733+
| (_, TyKind::Error)
1734+
| (TyKind::Alias(AliasTy::Projection(_)) | TyKind::AssociatedType(_, _), _)
1735+
| (_, TyKind::Alias(AliasTy::Projection(_)) | TyKind::AssociatedType(_, _)) => {
1736+
return Err(chalk_ir::NoSolution)
1737+
}
17251738
_ => (),
17261739
}
17271740

crates/hir-ty/src/mir/lower.rs

+10-7
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ pub enum MirLowerError {
9090
UnresolvedField,
9191
UnsizedTemporary(Ty),
9292
MissingFunctionDefinition(DefWithBodyId, ExprId),
93-
TypeMismatch(TypeMismatch),
93+
TypeMismatch(Option<TypeMismatch>),
9494
/// This should never happen. Type mismatch should catch everything.
9595
TypeError(&'static str),
9696
NotSupported(String),
@@ -170,14 +170,15 @@ impl MirLowerError {
170170
body.pretty_print_expr(db.upcast(), *owner, *it)
171171
)?;
172172
}
173-
MirLowerError::TypeMismatch(e) => {
174-
writeln!(
173+
MirLowerError::TypeMismatch(e) => match e {
174+
Some(e) => writeln!(
175175
f,
176176
"Type mismatch: Expected {}, found {}",
177177
e.expected.display(db),
178178
e.actual.display(db),
179-
)?;
180-
}
179+
)?,
180+
None => writeln!(f, "Type mismatch: types mismatch with {{unknown}}",)?,
181+
},
181182
MirLowerError::GenericArgNotProvided(id, subst) => {
182183
let parent = id.parent;
183184
let param = &db.generic_params(parent).type_or_consts[id.local_id];
@@ -2152,8 +2153,10 @@ pub fn lower_to_mir(
21522153
// need to take this input explicitly.
21532154
root_expr: ExprId,
21542155
) -> Result<MirBody> {
2155-
if let Some((_, it)) = infer.type_mismatches().next() {
2156-
return Err(MirLowerError::TypeMismatch(it.clone()));
2156+
if infer.has_errors {
2157+
return Err(MirLowerError::TypeMismatch(
2158+
infer.type_mismatches().next().map(|(_, it)| it.clone()),
2159+
));
21572160
}
21582161
let mut ctx = MirLowerCtx::new(db, owner, body, infer);
21592162
// 0 is return local

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

+17
Original file line numberDiff line numberDiff line change
@@ -136,3 +136,20 @@ impl Trait for () {
136136
"#,
137137
);
138138
}
139+
140+
#[test]
141+
fn no_mismatches_with_unresolved_projections() {
142+
check_no_mismatches(
143+
r#"
144+
// `Thing` is `{unknown}`
145+
fn create() -> Option<(i32, Thing)> {
146+
Some((69420, Thing))
147+
}
148+
149+
fn consume() -> Option<()> {
150+
let (number, thing) = create()?;
151+
Some(())
152+
}
153+
"#,
154+
);
155+
}

crates/hir/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1678,6 +1678,7 @@ impl DefWithBody {
16781678
for d in &infer.diagnostics {
16791679
acc.extend(AnyDiagnostic::inference_diagnostic(db, self.into(), d, &source_map));
16801680
}
1681+
16811682
for (pat_or_expr, mismatch) in infer.type_mismatches() {
16821683
let expr_or_pat = match pat_or_expr {
16831684
ExprOrPatId::ExprId(expr) => source_map.expr_syntax(expr).map(Either::Left),

0 commit comments

Comments
 (0)