@@ -26,7 +26,7 @@ use std::{convert::identity, ops::Index};
2626
2727use chalk_ir:: {
2828 cast:: Cast , fold:: TypeFoldable , interner:: HasInterner , DebruijnIndex , Mutability , Safety ,
29- Scalar , TyKind , TypeFlags ,
29+ Scalar , TyKind , TypeFlags , Variance ,
3030} ;
3131use either:: Either ;
3232use hir_def:: {
@@ -58,8 +58,9 @@ use crate::{
5858 static_lifetime, to_assoc_type_id,
5959 traits:: FnTrait ,
6060 utils:: { InTypeConstIdMetadata , UnevaluatedConstEvaluatorFolder } ,
61- AliasEq , AliasTy , ClosureId , DomainGoal , GenericArg , Goal , ImplTraitId , InEnvironment ,
62- Interner , ProjectionTy , RpitId , Substitution , TraitEnvironment , TraitRef , Ty , TyBuilder , TyExt ,
61+ AliasEq , AliasTy , Binders , ClosureId , Const , DomainGoal , GenericArg , Goal , ImplTraitId ,
62+ InEnvironment , Interner , Lifetime , ProjectionTy , RpitId , Substitution , TraitEnvironment ,
63+ TraitRef , Ty , TyBuilder , TyExt ,
6364} ;
6465
6566// This lint has a false positive here. See the link below for details.
@@ -688,10 +689,17 @@ impl<'a> InferenceContext<'a> {
688689 for ty in type_of_for_iterator. values_mut ( ) {
689690 * ty = table. resolve_completely ( ty. clone ( ) ) ;
690691 }
691- for mismatch in type_mismatches. values_mut ( ) {
692+ type_mismatches. retain ( |_ , mismatch| {
692693 mismatch. expected = table. resolve_completely ( mismatch. expected . clone ( ) ) ;
693694 mismatch. actual = table. resolve_completely ( mismatch. actual . clone ( ) ) ;
694- }
695+ chalk_ir:: zip:: Zip :: zip_with (
696+ & mut UnknownMismatch ( self . db ) ,
697+ Variance :: Invariant ,
698+ & mismatch. expected ,
699+ & mismatch. actual ,
700+ )
701+ . is_ok ( )
702+ } ) ;
695703 diagnostics. retain_mut ( |diagnostic| {
696704 use InferenceDiagnostic :: * ;
697705 match diagnostic {
@@ -1502,3 +1510,116 @@ impl std::ops::BitOrAssign for Diverges {
15021510 * self = * self | other;
15031511 }
15041512}
1513+ /// A zipper that checks for unequal `{unknown}` occurrences in the two types. Used to filter out
1514+ /// mismatch diagnostics that only differ in `{unknown}`. These mismatches are usually not helpful.
1515+ /// As the cause is usually an underlying name resolution problem.
1516+ struct UnknownMismatch < ' db > ( & ' db dyn HirDatabase ) ;
1517+ impl chalk_ir:: zip:: Zipper < Interner > for UnknownMismatch < ' _ > {
1518+ fn zip_tys ( & mut self , variance : Variance , a : & Ty , b : & Ty ) -> chalk_ir:: Fallible < ( ) > {
1519+ let zip_substs = |this : & mut Self ,
1520+ variances,
1521+ sub_a : & Substitution ,
1522+ sub_b : & Substitution | {
1523+ this. zip_substs ( variance, variances, sub_a. as_slice ( Interner ) , sub_b. as_slice ( Interner ) )
1524+ } ;
1525+ match ( a. kind ( Interner ) , b. kind ( Interner ) ) {
1526+ ( TyKind :: Adt ( id_a, sub_a) , TyKind :: Adt ( id_b, sub_b) ) if id_a == id_b => zip_substs (
1527+ self ,
1528+ Some ( self . unification_database ( ) . adt_variance ( * id_a) ) ,
1529+ sub_a,
1530+ sub_b,
1531+ ) ?,
1532+ (
1533+ TyKind :: AssociatedType ( assoc_ty_a, sub_a) ,
1534+ TyKind :: AssociatedType ( assoc_ty_b, sub_b) ,
1535+ ) if assoc_ty_a == assoc_ty_b => zip_substs ( self , None , sub_a, sub_b) ?,
1536+ ( TyKind :: Tuple ( arity_a, sub_a) , TyKind :: Tuple ( arity_b, sub_b) )
1537+ if arity_a == arity_b =>
1538+ {
1539+ zip_substs ( self , None , sub_a, sub_b) ?
1540+ }
1541+ ( TyKind :: OpaqueType ( opaque_ty_a, sub_a) , TyKind :: OpaqueType ( opaque_ty_b, sub_b) )
1542+ if opaque_ty_a == opaque_ty_b =>
1543+ {
1544+ zip_substs ( self , None , sub_a, sub_b) ?
1545+ }
1546+ ( TyKind :: Slice ( ty_a) , TyKind :: Slice ( ty_b) ) => self . zip_tys ( variance, ty_a, ty_b) ?,
1547+ ( TyKind :: FnDef ( fn_def_a, sub_a) , TyKind :: FnDef ( fn_def_b, sub_b) )
1548+ if fn_def_a == fn_def_b =>
1549+ {
1550+ zip_substs (
1551+ self ,
1552+ Some ( self . unification_database ( ) . fn_def_variance ( * fn_def_a) ) ,
1553+ sub_a,
1554+ sub_b,
1555+ ) ?
1556+ }
1557+ ( TyKind :: Ref ( mutability_a, _, ty_a) , TyKind :: Ref ( mutability_b, _, ty_b) )
1558+ if mutability_a == mutability_b =>
1559+ {
1560+ self . zip_tys ( variance, ty_a, ty_b) ?
1561+ }
1562+ ( TyKind :: Raw ( mutability_a, ty_a) , TyKind :: Raw ( mutability_b, ty_b) )
1563+ if mutability_a == mutability_b =>
1564+ {
1565+ self . zip_tys ( variance, ty_a, ty_b) ?
1566+ }
1567+ ( TyKind :: Array ( ty_a, const_a) , TyKind :: Array ( ty_b, const_b) ) if const_a == const_b => {
1568+ self . zip_tys ( variance, ty_a, ty_b) ?
1569+ }
1570+ ( TyKind :: Closure ( id_a, sub_a) , TyKind :: Closure ( id_b, sub_b) ) if id_a == id_b => {
1571+ zip_substs ( self , None , sub_a, sub_b) ?
1572+ }
1573+ ( TyKind :: Coroutine ( coroutine_a, sub_a) , TyKind :: Coroutine ( coroutine_b, sub_b) )
1574+ if coroutine_a == coroutine_b =>
1575+ {
1576+ zip_substs ( self , None , sub_a, sub_b) ?
1577+ }
1578+ (
1579+ TyKind :: CoroutineWitness ( coroutine_a, sub_a) ,
1580+ TyKind :: CoroutineWitness ( coroutine_b, sub_b) ,
1581+ ) if coroutine_a == coroutine_b => zip_substs ( self , None , sub_a, sub_b) ?,
1582+ ( TyKind :: Function ( fn_ptr_a) , TyKind :: Function ( fn_ptr_b) )
1583+ if fn_ptr_a. sig == fn_ptr_b. sig && fn_ptr_a. num_binders == fn_ptr_b. num_binders =>
1584+ {
1585+ zip_substs ( self , None , & fn_ptr_a. substitution . 0 , & fn_ptr_b. substitution . 0 ) ?
1586+ }
1587+ ( TyKind :: Error , TyKind :: Error ) => ( ) ,
1588+ ( TyKind :: Error , _) | ( _, TyKind :: Error ) => return Err ( chalk_ir:: NoSolution ) ,
1589+ _ => ( ) ,
1590+ }
1591+
1592+ Ok ( ( ) )
1593+ }
1594+
1595+ fn zip_lifetimes ( & mut self , _: Variance , _: & Lifetime , _: & Lifetime ) -> chalk_ir:: Fallible < ( ) > {
1596+ Ok ( ( ) )
1597+ }
1598+
1599+ fn zip_consts ( & mut self , _: Variance , _: & Const , _: & Const ) -> chalk_ir:: Fallible < ( ) > {
1600+ Ok ( ( ) )
1601+ }
1602+
1603+ fn zip_binders < T > (
1604+ & mut self ,
1605+ variance : Variance ,
1606+ a : & Binders < T > ,
1607+ b : & Binders < T > ,
1608+ ) -> chalk_ir:: Fallible < ( ) >
1609+ where
1610+ T : Clone
1611+ + HasInterner < Interner = Interner >
1612+ + chalk_ir:: zip:: Zip < Interner >
1613+ + TypeFoldable < Interner > ,
1614+ {
1615+ chalk_ir:: zip:: Zip :: zip_with ( self , variance, a. skip_binders ( ) , b. skip_binders ( ) )
1616+ }
1617+
1618+ fn interner ( & self ) -> Interner {
1619+ Interner
1620+ }
1621+
1622+ fn unification_database ( & self ) -> & dyn chalk_ir:: UnificationDatabase < Interner > {
1623+ & self . 0
1624+ }
1625+ }
0 commit comments