Skip to content

Commit

Permalink
fix: simplify the usage of UnknownMismatch
Browse files Browse the repository at this point in the history
  • Loading branch information
roife committed Apr 1, 2024
1 parent 3d373fe commit 2636e44
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 41 deletions.
8 changes: 0 additions & 8 deletions crates/hir-ty/src/chalk_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ pub trait TyExt {
fn contains_unknown(&self) -> bool;
fn is_ty_var(&self) -> bool;
fn is_union(&self) -> bool;
fn is_projection(&self) -> bool;

fn as_adt(&self) -> Option<(hir_def::AdtId, &Substitution)>;
fn as_builtin(&self) -> Option<BuiltinType>;
Expand Down Expand Up @@ -102,13 +101,6 @@ impl TyExt for Ty {
matches!(self.adt_id(Interner), Some(AdtId(hir_def::AdtId::UnionId(_))))
}

fn is_projection(&self) -> bool {
matches!(
self.kind(Interner),
TyKind::Alias(AliasTy::Projection(_)) | TyKind::AssociatedType(_, _)
)
}

fn as_adt(&self) -> Option<(hir_def::AdtId, &Substitution)> {
match self.kind(Interner) {
TyKind::Adt(AdtId(adt), parameters) => Some((*adt, parameters)),
Expand Down
52 changes: 20 additions & 32 deletions crates/hir-ty/src/infer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::*;
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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)
}
_ => (),
}

Expand Down
2 changes: 1 addition & 1 deletion crates/hir-ty/src/tests/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ impl Trait for () {
fn no_mismatches_with_unresolved_projections() {
check_no_mismatches(
r#"
// Thing is {unknown}
// `Thing` is `{unknown}`
fn create() -> Option<(i32, Thing)> {
Some((69420, Thing))
}
Expand Down

0 comments on commit 2636e44

Please sign in to comment.