@@ -26,7 +26,7 @@ use std::{convert::identity, ops::Index};
26
26
27
27
use chalk_ir:: {
28
28
cast:: Cast , fold:: TypeFoldable , interner:: HasInterner , DebruijnIndex , Mutability , Safety ,
29
- Scalar , TyKind , TypeFlags ,
29
+ Scalar , TyKind , TypeFlags , Variance ,
30
30
} ;
31
31
use either:: Either ;
32
32
use hir_def:: {
@@ -58,8 +58,9 @@ use crate::{
58
58
static_lifetime, to_assoc_type_id,
59
59
traits:: FnTrait ,
60
60
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 ,
63
64
} ;
64
65
65
66
// This lint has a false positive here. See the link below for details.
@@ -688,10 +689,17 @@ impl<'a> InferenceContext<'a> {
688
689
for ty in type_of_for_iterator. values_mut ( ) {
689
690
* ty = table. resolve_completely ( ty. clone ( ) ) ;
690
691
}
691
- for mismatch in type_mismatches. values_mut ( ) {
692
+ type_mismatches. retain ( |_ , mismatch| {
692
693
mismatch. expected = table. resolve_completely ( mismatch. expected . clone ( ) ) ;
693
694
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
+ } ) ;
695
703
diagnostics. retain_mut ( |diagnostic| {
696
704
use InferenceDiagnostic :: * ;
697
705
match diagnostic {
@@ -1502,3 +1510,116 @@ impl std::ops::BitOrAssign for Diverges {
1502
1510
* self = * self | other;
1503
1511
}
1504
1512
}
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