@@ -1637,9 +1637,39 @@ fn explicit_predicates_of<'a, 'tcx>(
1637
1637
def_id : DefId ,
1638
1638
) -> ty:: GenericPredicates < ' tcx > {
1639
1639
use rustc:: hir:: * ;
1640
+ use rustc_data_structures:: fx:: FxHashSet ;
1640
1641
1641
1642
debug ! ( "explicit_predicates_of(def_id={:?})" , def_id) ;
1642
1643
1644
+ /// A data structure with unique elements, which preserves order of insertion.
1645
+ /// Preserving the order of insertion is important here so as not to break
1646
+ /// compile-fail UI tests.
1647
+ struct UniquePredicates < ' tcx > {
1648
+ predicates : Vec < ( ty:: Predicate < ' tcx > , Span ) > ,
1649
+ uniques : FxHashSet < ( ty:: Predicate < ' tcx > , Span ) > ,
1650
+ }
1651
+
1652
+ impl < ' tcx > UniquePredicates < ' tcx > {
1653
+ fn new ( ) -> Self {
1654
+ UniquePredicates {
1655
+ predicates : vec ! [ ] ,
1656
+ uniques : FxHashSet :: default ( ) ,
1657
+ }
1658
+ }
1659
+
1660
+ fn push ( & mut self , value : ( ty:: Predicate < ' tcx > , Span ) ) {
1661
+ if self . uniques . insert ( value) {
1662
+ self . predicates . push ( value) ;
1663
+ }
1664
+ }
1665
+
1666
+ fn extend < I : IntoIterator < Item = ( ty:: Predicate < ' tcx > , Span ) > > ( & mut self , iter : I ) {
1667
+ for value in iter {
1668
+ self . push ( value) ;
1669
+ }
1670
+ }
1671
+ }
1672
+
1643
1673
let node_id = tcx. hir . as_local_node_id ( def_id) . unwrap ( ) ;
1644
1674
let node = tcx. hir . get ( node_id) ;
1645
1675
@@ -1649,7 +1679,7 @@ fn explicit_predicates_of<'a, 'tcx>(
1649
1679
let icx = ItemCtxt :: new ( tcx, def_id) ;
1650
1680
let no_generics = hir:: Generics :: empty ( ) ;
1651
1681
1652
- let mut predicates = vec ! [ ] ;
1682
+ let mut predicates = UniquePredicates :: new ( ) ;
1653
1683
1654
1684
let ast_generics = match node {
1655
1685
Node :: TraitItem ( item) => & item. generics ,
@@ -1744,7 +1774,7 @@ fn explicit_predicates_of<'a, 'tcx>(
1744
1774
// on a trait we need to add in the supertrait bounds and bounds found on
1745
1775
// associated types.
1746
1776
if let Some ( ( _trait_ref, _) ) = is_trait {
1747
- predicates = tcx. super_predicates_of ( def_id) . predicates ;
1777
+ predicates. extend ( tcx. super_predicates_of ( def_id) . predicates ) ;
1748
1778
}
1749
1779
1750
1780
// In default impls, we can assume that the self type implements
@@ -1895,6 +1925,8 @@ fn explicit_predicates_of<'a, 'tcx>(
1895
1925
} ) )
1896
1926
}
1897
1927
1928
+ let mut predicates = predicates. predicates ;
1929
+
1898
1930
// Subtle: before we store the predicates into the tcx, we
1899
1931
// sort them so that predicates like `T: Foo<Item=U>` come
1900
1932
// before uses of `U`. This avoids false ambiguity errors
0 commit comments