@@ -429,6 +429,8 @@ pub struct InferenceResult {
429
429
/// Type of the result of `.into_iter()` on the for. `ExprId` is the one of the whole for loop.
430
430
pub type_of_for_iterator : FxHashMap < ExprId , Ty > ,
431
431
type_mismatches : FxHashMap < ExprOrPatId , TypeMismatch > ,
432
+ /// Whether there are any type-mismatching errors in the result.
433
+ pub ( crate ) has_errors : bool ,
432
434
/// Interned common types to return references to.
433
435
standard_types : InternedStandardTypes ,
434
436
/// Stores the types which were implicitly dereferenced in pattern binding modes.
@@ -654,6 +656,7 @@ impl<'a> InferenceContext<'a> {
654
656
type_of_rpit,
655
657
type_of_for_iterator,
656
658
type_mismatches,
659
+ has_errors,
657
660
standard_types : _,
658
661
pat_adjustments,
659
662
binding_modes : _,
@@ -695,16 +698,33 @@ impl<'a> InferenceContext<'a> {
695
698
for ty in type_of_for_iterator. values_mut ( ) {
696
699
* ty = table. resolve_completely ( ty. clone ( ) ) ;
697
700
}
701
+
702
+ * has_errors = !type_mismatches. is_empty ( ) ;
703
+
698
704
type_mismatches. retain ( |_, mismatch| {
699
705
mismatch. expected = table. resolve_completely ( mismatch. expected . clone ( ) ) ;
700
706
mismatch. actual = table. resolve_completely ( mismatch. actual . clone ( ) ) ;
701
- chalk_ir:: zip:: Zip :: zip_with (
702
- & mut UnknownMismatch ( self . db ) ,
703
- Variance :: Invariant ,
704
- & mismatch. expected ,
705
- & mismatch. actual ,
706
- )
707
- . is_ok ( )
707
+ let unresolved_ty_mismatch = || {
708
+ chalk_ir:: zip:: Zip :: zip_with (
709
+ & mut UnknownMismatch ( self . db , |ty| matches ! ( ty. kind( Interner ) , TyKind :: Error ) ) ,
710
+ Variance :: Invariant ,
711
+ & mismatch. expected ,
712
+ & mismatch. actual ,
713
+ )
714
+ . is_ok ( )
715
+ } ;
716
+
717
+ let unresolved_projections_mismatch = || {
718
+ chalk_ir:: zip:: Zip :: zip_with (
719
+ & mut UnknownMismatch ( self . db , |ty| ty. contains_unknown ( ) && ty. is_projection ( ) ) ,
720
+ chalk_ir:: Variance :: Invariant ,
721
+ & mismatch. expected ,
722
+ & mismatch. actual ,
723
+ )
724
+ . is_ok ( )
725
+ } ;
726
+
727
+ unresolved_ty_mismatch ( ) && unresolved_projections_mismatch ( )
708
728
} ) ;
709
729
diagnostics. retain_mut ( |diagnostic| {
710
730
use InferenceDiagnostic :: * ;
@@ -1646,11 +1666,16 @@ impl std::ops::BitOrAssign for Diverges {
1646
1666
* self = * self | other;
1647
1667
}
1648
1668
}
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 < ' _ > {
1669
+ /// A zipper that checks for unequal `{unknown}` occurrences in the two types.
1670
+ /// Types that have different constructors are filtered out and tested by the
1671
+ /// provided closure `F`. Commonly used to filter out mismatch diagnostics that
1672
+ /// only differ in `{unknown}`. These mismatches are usually not helpful, as the
1673
+ /// cause is usually an underlying name resolution problem.
1674
+ ///
1675
+ /// E.g. when F is `|ty| matches!(ty.kind(Interer), TyKind::Unknown)`, the zipper
1676
+ /// will skip over all mismatches that only differ in `{unknown}`.
1677
+ struct UnknownMismatch < ' db , F : Fn ( & Ty ) -> bool > ( & ' db dyn HirDatabase , F ) ;
1678
+ impl < F : Fn ( & Ty ) -> bool > chalk_ir:: zip:: Zipper < Interner > for UnknownMismatch < ' _ , F > {
1654
1679
fn zip_tys ( & mut self , variance : Variance , a : & Ty , b : & Ty ) -> chalk_ir:: Fallible < ( ) > {
1655
1680
let zip_substs = |this : & mut Self ,
1656
1681
variances,
@@ -1721,7 +1746,7 @@ impl chalk_ir::zip::Zipper<Interner> for UnknownMismatch<'_> {
1721
1746
zip_substs ( self , None , & fn_ptr_a. substitution . 0 , & fn_ptr_b. substitution . 0 ) ?
1722
1747
}
1723
1748
( TyKind :: Error , TyKind :: Error ) => ( ) ,
1724
- ( TyKind :: Error , _ ) | ( _ , TyKind :: Error ) => return Err ( chalk_ir:: NoSolution ) ,
1749
+ _ if ( self . 1 ) ( a ) || ( self . 1 ) ( b ) => return Err ( chalk_ir:: NoSolution ) ,
1725
1750
_ => ( ) ,
1726
1751
}
1727
1752
0 commit comments