@@ -45,7 +45,7 @@ use std::cell::RefCell;
45
45
use std:: sync:: Arc ;
46
46
use std:: u32;
47
47
48
- use crate :: core:: { self , DocContext } ;
48
+ use crate :: core:: { self , DocContext , ImplTraitParam } ;
49
49
use crate :: doctree;
50
50
use crate :: html:: render:: { cache, ExternalLocation } ;
51
51
use crate :: html:: item_type:: ItemType ;
@@ -1540,7 +1540,7 @@ impl Clean<GenericParamDef> for ty::GenericParamDef {
1540
1540
ty:: GenericParamDefKind :: Lifetime => {
1541
1541
( self . name . to_string ( ) , GenericParamDefKind :: Lifetime )
1542
1542
}
1543
- ty:: GenericParamDefKind :: Type { has_default, .. } => {
1543
+ ty:: GenericParamDefKind :: Type { has_default, synthetic , .. } => {
1544
1544
cx. renderinfo . borrow_mut ( ) . external_param_names
1545
1545
. insert ( self . def_id , self . name . clean ( cx) ) ;
1546
1546
let default = if has_default {
@@ -1552,7 +1552,7 @@ impl Clean<GenericParamDef> for ty::GenericParamDef {
1552
1552
did : self . def_id ,
1553
1553
bounds : vec ! [ ] , // These are filled in from the where-clauses.
1554
1554
default,
1555
- synthetic : None ,
1555
+ synthetic,
1556
1556
} )
1557
1557
}
1558
1558
ty:: GenericParamDefKind :: Const { .. } => {
@@ -1641,7 +1641,7 @@ impl Clean<Generics> for hir::Generics {
1641
1641
match param. kind {
1642
1642
GenericParamDefKind :: Lifetime => unreachable ! ( ) ,
1643
1643
GenericParamDefKind :: Type { did, ref bounds, .. } => {
1644
- cx. impl_trait_bounds . borrow_mut ( ) . insert ( did, bounds. clone ( ) ) ;
1644
+ cx. impl_trait_bounds . borrow_mut ( ) . insert ( did. into ( ) , bounds. clone ( ) ) ;
1645
1645
}
1646
1646
GenericParamDefKind :: Const { .. } => unreachable ! ( ) ,
1647
1647
}
@@ -1696,25 +1696,76 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics,
1696
1696
1697
1697
let ( gens, preds) = * self ;
1698
1698
1699
+ // Don't populate `cx.impl_trait_bounds` before `clean`ning `where` clauses,
1700
+ // since `Clean for ty::Predicate` would consume them.
1701
+ let mut impl_trait = FxHashMap :: < ImplTraitParam , Vec < _ > > :: default ( ) ;
1702
+
1699
1703
// Bounds in the type_params and lifetimes fields are repeated in the
1700
1704
// predicates field (see rustc_typeck::collect::ty_generics), so remove
1701
1705
// them.
1702
- let stripped_typarams = gens. params . iter ( ) . filter_map ( |param| match param. kind {
1703
- ty:: GenericParamDefKind :: Lifetime => None ,
1704
- ty:: GenericParamDefKind :: Type { .. } => {
1705
- if param. name . as_symbol ( ) == kw:: SelfUpper {
1706
- assert_eq ! ( param. index, 0 ) ;
1707
- return None ;
1706
+ let stripped_typarams = gens. params . iter ( )
1707
+ . filter_map ( |param| match param. kind {
1708
+ ty:: GenericParamDefKind :: Lifetime => None ,
1709
+ ty:: GenericParamDefKind :: Type { synthetic, .. } => {
1710
+ if param. name . as_symbol ( ) == kw:: SelfUpper {
1711
+ assert_eq ! ( param. index, 0 ) ;
1712
+ return None ;
1713
+ }
1714
+ if synthetic == Some ( hir:: SyntheticTyParamKind :: ImplTrait ) {
1715
+ impl_trait. insert ( param. index . into ( ) , vec ! [ ] ) ;
1716
+ return None ;
1717
+ }
1718
+ Some ( param. clean ( cx) )
1708
1719
}
1709
- Some ( param. clean ( cx) )
1710
- }
1711
- ty:: GenericParamDefKind :: Const { .. } => None ,
1712
- } ) . collect :: < Vec < GenericParamDef > > ( ) ;
1720
+ ty:: GenericParamDefKind :: Const { .. } => None ,
1721
+ } ) . collect :: < Vec < GenericParamDef > > ( ) ;
1713
1722
1714
1723
let mut where_predicates = preds. predicates . iter ( )
1715
- . flat_map ( |( p, _) | p. clean ( cx) )
1724
+ . flat_map ( |( p, _) | {
1725
+ let param_idx = if let Some ( trait_ref) = p. to_opt_poly_trait_ref ( ) {
1726
+ if let ty:: Param ( param) = trait_ref. self_ty ( ) . sty {
1727
+ Some ( param. index )
1728
+ } else {
1729
+ None
1730
+ }
1731
+ } else if let Some ( outlives) = p. to_opt_type_outlives ( ) {
1732
+ if let ty:: Param ( param) = outlives. skip_binder ( ) . 0 . sty {
1733
+ Some ( param. index )
1734
+ } else {
1735
+ None
1736
+ }
1737
+ } else {
1738
+ None
1739
+ } ;
1740
+
1741
+ let p = p. clean ( cx) ?;
1742
+
1743
+ if let Some ( b) = param_idx. and_then ( |i| impl_trait. get_mut ( & i. into ( ) ) ) {
1744
+ b. extend (
1745
+ p. get_bounds ( )
1746
+ . into_iter ( )
1747
+ . flatten ( )
1748
+ . cloned ( )
1749
+ . filter ( |b| !b. is_sized_bound ( cx) )
1750
+ ) ;
1751
+ return None ;
1752
+ }
1753
+
1754
+ Some ( p)
1755
+ } )
1716
1756
. collect :: < Vec < _ > > ( ) ;
1717
1757
1758
+ // Move `TraitPredicate`s to the front.
1759
+ for ( _, bounds) in impl_trait. iter_mut ( ) {
1760
+ bounds. sort_by_key ( |b| if let GenericBound :: TraitBound ( ..) = b {
1761
+ false
1762
+ } else {
1763
+ true
1764
+ } ) ;
1765
+ }
1766
+
1767
+ cx. impl_trait_bounds . borrow_mut ( ) . extend ( impl_trait) ;
1768
+
1718
1769
// Type parameters and have a Sized bound by default unless removed with
1719
1770
// ?Sized. Scan through the predicates and mark any type parameter with
1720
1771
// a Sized bound, removing the bounds as we find them.
@@ -2791,7 +2842,7 @@ impl Clean<Type> for hir::Ty {
2791
2842
if let Some ( new_ty) = cx. ty_substs . borrow ( ) . get ( & did) . cloned ( ) {
2792
2843
return new_ty;
2793
2844
}
2794
- if let Some ( bounds) = cx. impl_trait_bounds . borrow_mut ( ) . remove ( & did) {
2845
+ if let Some ( bounds) = cx. impl_trait_bounds . borrow_mut ( ) . remove ( & did. into ( ) ) {
2795
2846
return ImplTrait ( bounds) ;
2796
2847
}
2797
2848
}
@@ -3082,7 +3133,13 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
3082
3133
3083
3134
ty:: Projection ( ref data) => data. clean ( cx) ,
3084
3135
3085
- ty:: Param ( ref p) => Generic ( p. name . to_string ( ) ) ,
3136
+ ty:: Param ( ref p) => {
3137
+ if let Some ( bounds) = cx. impl_trait_bounds . borrow_mut ( ) . remove ( & p. index . into ( ) ) {
3138
+ ImplTrait ( bounds)
3139
+ } else {
3140
+ Generic ( p. name . to_string ( ) )
3141
+ }
3142
+ }
3086
3143
3087
3144
ty:: Opaque ( def_id, substs) => {
3088
3145
// Grab the "TraitA + TraitB" from `impl TraitA + TraitB`,
0 commit comments