@@ -429,6 +429,8 @@ pub struct InferenceResult {
429429 /// Type of the result of `.into_iter()` on the for. `ExprId` is the one of the whole for loop.
430430 pub type_of_for_iterator : FxHashMap < ExprId , Ty > ,
431431 type_mismatches : FxHashMap < ExprOrPatId , TypeMismatch > ,
432+ /// Whether there are any type-mismatching errors in the result.
433+ pub ( crate ) has_errors : bool ,
432434 /// Interned common types to return references to.
433435 standard_types : InternedStandardTypes ,
434436 /// Stores the types which were implicitly dereferenced in pattern binding modes.
@@ -654,6 +656,7 @@ impl<'a> InferenceContext<'a> {
654656 type_of_rpit,
655657 type_of_for_iterator,
656658 type_mismatches,
659+ has_errors,
657660 standard_types : _,
658661 pat_adjustments,
659662 binding_modes : _,
@@ -695,16 +698,33 @@ impl<'a> InferenceContext<'a> {
695698 for ty in type_of_for_iterator. values_mut ( ) {
696699 * ty = table. resolve_completely ( ty. clone ( ) ) ;
697700 }
701+
702+ * has_errors = !type_mismatches. is_empty ( ) ;
703+
698704 type_mismatches. retain ( |_, mismatch| {
699705 mismatch. expected = table. resolve_completely ( mismatch. expected . clone ( ) ) ;
700706 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 ( )
708728 } ) ;
709729 diagnostics. retain_mut ( |diagnostic| {
710730 use InferenceDiagnostic :: * ;
@@ -1646,11 +1666,16 @@ impl std::ops::BitOrAssign for Diverges {
16461666 * self = * self | other;
16471667 }
16481668}
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 > {
16541679 fn zip_tys ( & mut self , variance : Variance , a : & Ty , b : & Ty ) -> chalk_ir:: Fallible < ( ) > {
16551680 let zip_substs = |this : & mut Self ,
16561681 variances,
@@ -1721,7 +1746,7 @@ impl chalk_ir::zip::Zipper<Interner> for UnknownMismatch<'_> {
17211746 zip_substs ( self , None , & fn_ptr_a. substitution . 0 , & fn_ptr_b. substitution . 0 ) ?
17221747 }
17231748 ( 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 ) ,
17251750 _ => ( ) ,
17261751 }
17271752
0 commit comments