Skip to content

Commit cef455f

Browse files
committed
fix: silence mismatches involving unresolved projections
1 parent 899db83 commit cef455f

File tree

6 files changed

+36
-10
lines changed

6 files changed

+36
-10
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/hir-ty/src/chalk_ext.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ pub trait TyExt {
2929
fn contains_unknown(&self) -> bool;
3030
fn is_ty_var(&self) -> bool;
3131
fn is_union(&self) -> bool;
32+
fn is_projection(&self) -> bool;
3233

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

105+
fn is_projection(&self) -> bool {
106+
matches!(
107+
self.kind(Interner),
108+
TyKind::Alias(AliasTy::Projection(_)) | TyKind::AssociatedType(_, _)
109+
)
110+
}
111+
104112
fn as_adt(&self) -> Option<(hir_def::AdtId, &Substitution)> {
105113
match self.kind(Interner) {
106114
TyKind::Adt(AdtId(adt), parameters) => Some((*adt, parameters)),

crates/hir-ty/src/infer.rs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -699,7 +699,7 @@ impl<'a> InferenceContext<'a> {
699699
mismatch.expected = table.resolve_completely(mismatch.expected.clone());
700700
mismatch.actual = table.resolve_completely(mismatch.actual.clone());
701701
chalk_ir::zip::Zip::zip_with(
702-
&mut UnknownMismatch(self.db),
702+
&mut UnknownMismatch(self.db, |ty| matches!(ty.kind(Interner), TyKind::Error)),
703703
Variance::Invariant,
704704
&mismatch.expected,
705705
&mismatch.actual,
@@ -1646,11 +1646,16 @@ impl std::ops::BitOrAssign for Diverges {
16461646
*self = *self | other;
16471647
}
16481648
}
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.
1652-
struct UnknownMismatch<'db>(&'db dyn HirDatabase);
1653-
impl chalk_ir::zip::Zipper<Interner> for UnknownMismatch<'_> {
1649+
/// A zipper that checks for unequal `{unknown}` occurrences in the two types.
1650+
/// Types that have different constructors are filtered out and tested by the
1651+
/// provided closure `F`. Commonly used to filter out mismatch diagnostics that
1652+
/// only differ in `{unknown}`. These mismatches are usually not helpful, as the
1653+
/// cause is usually an underlying name resolution problem.
1654+
///
1655+
/// E.g. when F is `|ty| matches!(ty.kind(Interer), TyKind::Unknown)`, the zipper
1656+
/// will skip over all mismatches that only differ in `{unknown}`.
1657+
pub struct UnknownMismatch<'db, F: Fn(&Ty) -> bool>(pub &'db dyn HirDatabase, pub F);
1658+
impl<F: Fn(&Ty) -> bool> chalk_ir::zip::Zipper<Interner> for UnknownMismatch<'_, F> {
16541659
fn zip_tys(&mut self, variance: Variance, a: &Ty, b: &Ty) -> chalk_ir::Fallible<()> {
16551660
let zip_substs = |this: &mut Self,
16561661
variances,
@@ -1721,7 +1726,7 @@ impl chalk_ir::zip::Zipper<Interner> for UnknownMismatch<'_> {
17211726
zip_substs(self, None, &fn_ptr_a.substitution.0, &fn_ptr_b.substitution.0)?
17221727
}
17231728
(TyKind::Error, TyKind::Error) => (),
1724-
(TyKind::Error, _) | (_, TyKind::Error) => return Err(chalk_ir::NoSolution),
1729+
_ if (self.1)(a) || (self.1)(b) => return Err(chalk_ir::NoSolution),
17251730
_ => (),
17261731
}
17271732

crates/hir-ty/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ pub use chalk_ext::*;
8181
pub use infer::{
8282
closure::{CaptureKind, CapturedItem},
8383
could_coerce, could_unify, could_unify_deeply, Adjust, Adjustment, AutoBorrow, BindingMode,
84-
InferenceDiagnostic, InferenceResult, OverloadedDeref, PointerCast,
84+
InferenceDiagnostic, InferenceResult, OverloadedDeref, PointerCast, UnknownMismatch,
8585
};
8686
pub use interner::Interner;
8787
pub use lower::{

crates/hir/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ smallvec.workspace = true
2020
tracing.workspace = true
2121
triomphe.workspace = true
2222
once_cell = "1.17.1"
23+
chalk-ir.workspace = true
2324

2425
# local deps
2526
base-db.workspace = true

crates/hir/src/lib.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ use std::{iter, mem::discriminant, ops::ControlFlow};
3939

4040
use arrayvec::ArrayVec;
4141
use base_db::{CrateDisplayName, CrateId, CrateOrigin, FileId};
42+
use chalk_ir::TyKind;
4243
use either::Either;
4344
use hir_def::{
4445
body::{BodyDiagnostic, SyntheticSyntax},
@@ -73,8 +74,7 @@ use hir_ty::{
7374
traits::FnTrait,
7475
AliasTy, CallableDefId, CallableSig, Canonical, CanonicalVarKinds, Cast, ClosureId, GenericArg,
7576
GenericArgData, Interner, ParamKind, QuantifiedWhereClause, Scalar, Substitution,
76-
TraitEnvironment, TraitRefExt, Ty, TyBuilder, TyDefId, TyExt, TyKind, ValueTyDefId,
77-
WhereClause,
77+
TraitEnvironment, TraitRefExt, Ty, TyBuilder, TyDefId, TyExt, ValueTyDefId, WhereClause,
7878
};
7979
use itertools::Itertools;
8080
use nameres::diagnostics::DefDiagnosticKind;
@@ -1678,7 +1678,18 @@ 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() {
1683+
let contains_unknown_projection = chalk_ir::zip::Zip::zip_with(
1684+
&mut hir_ty::UnknownMismatch(db, |ty| ty.contains_unknown() && ty.is_projection()),
1685+
chalk_ir::Variance::Invariant,
1686+
&mismatch.expected,
1687+
&mismatch.actual,
1688+
);
1689+
if contains_unknown_projection.is_err() {
1690+
continue;
1691+
}
1692+
16821693
let expr_or_pat = match pat_or_expr {
16831694
ExprOrPatId::ExprId(expr) => source_map.expr_syntax(expr).map(Either::Left),
16841695
ExprOrPatId::PatId(pat) => source_map.pat_syntax(pat).map(Either::Right),

0 commit comments

Comments
 (0)