Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/infer.rs')
| -rw-r--r-- | crates/hir-ty/src/infer.rs | 52 |
1 files changed, 20 insertions, 32 deletions
diff --git a/crates/hir-ty/src/infer.rs b/crates/hir-ty/src/infer.rs index 880c2b4b41..bb558e533c 100644 --- a/crates/hir-ty/src/infer.rs +++ b/crates/hir-ty/src/infer.rs @@ -704,27 +704,13 @@ impl<'a> InferenceContext<'a> { type_mismatches.retain(|_, mismatch| { mismatch.expected = table.resolve_completely(mismatch.expected.clone()); mismatch.actual = table.resolve_completely(mismatch.actual.clone()); - let unresolved_ty_mismatch = || { - chalk_ir::zip::Zip::zip_with( - &mut UnknownMismatch(self.db, |ty| matches!(ty.kind(Interner), TyKind::Error)), - Variance::Invariant, - &mismatch.expected, - &mismatch.actual, - ) - .is_ok() - }; - - let unresolved_projections_mismatch = || { - chalk_ir::zip::Zip::zip_with( - &mut UnknownMismatch(self.db, |ty| ty.contains_unknown() && ty.is_projection()), - chalk_ir::Variance::Invariant, - &mismatch.expected, - &mismatch.actual, - ) - .is_ok() - }; - - unresolved_ty_mismatch() && unresolved_projections_mismatch() + chalk_ir::zip::Zip::zip_with( + &mut UnknownMismatch(self.db), + Variance::Invariant, + &mismatch.expected, + &mismatch.actual, + ) + .is_ok() }); diagnostics.retain_mut(|diagnostic| { use InferenceDiagnostic::*; @@ -1666,16 +1652,13 @@ impl std::ops::BitOrAssign for Diverges { *self = *self | other; } } -/// A zipper that checks for unequal `{unknown}` occurrences in the two types. -/// Types that have different constructors are filtered out and tested by the -/// provided closure `F`. Commonly used to filter out mismatch diagnostics that -/// only differ in `{unknown}`. These mismatches are usually not helpful, as the -/// cause is usually an underlying name resolution problem. -/// -/// E.g. when F is `|ty| matches!(ty.kind(Interer), TyKind::Unknown)`, the zipper -/// will skip over all mismatches that only differ in `{unknown}`. -struct UnknownMismatch<'db, F: Fn(&Ty) -> bool>(&'db dyn HirDatabase, F); -impl<F: Fn(&Ty) -> bool> chalk_ir::zip::Zipper<Interner> for UnknownMismatch<'_, F> { + +/// A zipper that checks for unequal occurrences of `{unknown}` and unresolved projections +/// in the two types. Used to filter out mismatch diagnostics that only differ in +/// `{unknown}` and unresolved projections. These mismatches are usually not helpful. +/// As the cause is usually an underlying name resolution problem +struct UnknownMismatch<'db>(&'db dyn HirDatabase); +impl chalk_ir::zip::Zipper<Interner> for UnknownMismatch<'_> { fn zip_tys(&mut self, variance: Variance, a: &Ty, b: &Ty) -> chalk_ir::Fallible<()> { let zip_substs = |this: &mut Self, variances, @@ -1746,7 +1729,12 @@ impl<F: Fn(&Ty) -> bool> chalk_ir::zip::Zipper<Interner> for UnknownMismatch<'_, zip_substs(self, None, &fn_ptr_a.substitution.0, &fn_ptr_b.substitution.0)? } (TyKind::Error, TyKind::Error) => (), - _ if (self.1)(a) || (self.1)(b) => return Err(chalk_ir::NoSolution), + (TyKind::Error, _) + | (_, TyKind::Error) + | (TyKind::Alias(AliasTy::Projection(_)) | TyKind::AssociatedType(_, _), _) + | (_, TyKind::Alias(AliasTy::Projection(_)) | TyKind::AssociatedType(_, _)) => { + return Err(chalk_ir::NoSolution) + } _ => (), } |