about summary refs log tree commit diff
diff options
context:
space:
mode:
authorroife <roifewu@gmail.com>2024-04-02 02:29:36 +0800
committerroife <roifewu@gmail.com>2024-04-02 03:26:32 +0800
commit2636e44378c4e1bf674e9f71f7ec672909359832 (patch)
tree31e4e45f4ab0d07f68b405c687d122caf23d19bd
parent3d373fec8c2cbaa025a2db5c519ecc89cd1e95d9 (diff)
downloadrust-2636e44378c4e1bf674e9f71f7ec672909359832.tar.gz
rust-2636e44378c4e1bf674e9f71f7ec672909359832.zip
fix: simplify the usage of UnknownMismatch
-rw-r--r--crates/hir-ty/src/chalk_ext.rs8
-rw-r--r--crates/hir-ty/src/infer.rs52
-rw-r--r--crates/hir-ty/src/tests/diagnostics.rs2
3 files changed, 21 insertions, 41 deletions
diff --git a/crates/hir-ty/src/chalk_ext.rs b/crates/hir-ty/src/chalk_ext.rs
index 436fb31bcc5..d1aebeff261 100644
--- a/crates/hir-ty/src/chalk_ext.rs
+++ b/crates/hir-ty/src/chalk_ext.rs
@@ -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>;
@@ -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)),
diff --git a/crates/hir-ty/src/infer.rs b/crates/hir-ty/src/infer.rs
index 880c2b4b419..bb558e533c4 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)
+            }
             _ => (),
         }
 
diff --git a/crates/hir-ty/src/tests/diagnostics.rs b/crates/hir-ty/src/tests/diagnostics.rs
index fde90b0a55f..119de7f050e 100644
--- a/crates/hir-ty/src/tests/diagnostics.rs
+++ b/crates/hir-ty/src/tests/diagnostics.rs
@@ -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))
 }