@@ -1637,9 +1637,39 @@ fn explicit_predicates_of<'a, 'tcx>(
16371637 def_id : DefId ,
16381638) -> ty:: GenericPredicates < ' tcx > {
16391639 use rustc:: hir:: * ;
1640+ use rustc_data_structures:: fx:: FxHashSet ;
16401641
16411642 debug ! ( "explicit_predicates_of(def_id={:?})" , def_id) ;
16421643
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+
16431673 let node_id = tcx. hir . as_local_node_id ( def_id) . unwrap ( ) ;
16441674 let node = tcx. hir . get ( node_id) ;
16451675
@@ -1649,7 +1679,7 @@ fn explicit_predicates_of<'a, 'tcx>(
16491679 let icx = ItemCtxt :: new ( tcx, def_id) ;
16501680 let no_generics = hir:: Generics :: empty ( ) ;
16511681
1652- let mut predicates = vec ! [ ] ;
1682+ let mut predicates = UniquePredicates :: new ( ) ;
16531683
16541684 let ast_generics = match node {
16551685 Node :: TraitItem ( item) => & item. generics ,
@@ -1744,7 +1774,7 @@ fn explicit_predicates_of<'a, 'tcx>(
17441774 // on a trait we need to add in the supertrait bounds and bounds found on
17451775 // associated types.
17461776 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 ) ;
17481778 }
17491779
17501780 // In default impls, we can assume that the self type implements
@@ -1895,6 +1925,8 @@ fn explicit_predicates_of<'a, 'tcx>(
18951925 } ) )
18961926 }
18971927
1928+ let mut predicates = predicates. predicates ;
1929+
18981930 // Subtle: before we store the predicates into the tcx, we
18991931 // sort them so that predicates like `T: Foo<Item=U>` come
19001932 // before uses of `U`. This avoids false ambiguity errors
0 commit comments