@@ -45,7 +45,7 @@ use std::cell::RefCell;
4545use std:: sync:: Arc ;
4646use std:: u32;
4747
48- use crate :: core:: { self , DocContext } ;
48+ use crate :: core:: { self , DocContext , ImplTraitParam } ;
4949use crate :: doctree;
5050use crate :: html:: render:: { cache, ExternalLocation } ;
5151use crate :: html:: item_type:: ItemType ;
@@ -1540,7 +1540,7 @@ impl Clean<GenericParamDef> for ty::GenericParamDef {
15401540 ty:: GenericParamDefKind :: Lifetime => {
15411541 ( self . name . to_string ( ) , GenericParamDefKind :: Lifetime )
15421542 }
1543- ty:: GenericParamDefKind :: Type { has_default, .. } => {
1543+ ty:: GenericParamDefKind :: Type { has_default, synthetic , .. } => {
15441544 cx. renderinfo . borrow_mut ( ) . external_param_names
15451545 . insert ( self . def_id , self . name . clean ( cx) ) ;
15461546 let default = if has_default {
@@ -1552,7 +1552,7 @@ impl Clean<GenericParamDef> for ty::GenericParamDef {
15521552 did : self . def_id ,
15531553 bounds : vec ! [ ] , // These are filled in from the where-clauses.
15541554 default,
1555- synthetic : None ,
1555+ synthetic,
15561556 } )
15571557 }
15581558 ty:: GenericParamDefKind :: Const { .. } => {
@@ -1641,7 +1641,7 @@ impl Clean<Generics> for hir::Generics {
16411641 match param. kind {
16421642 GenericParamDefKind :: Lifetime => unreachable ! ( ) ,
16431643 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 ( ) ) ;
16451645 }
16461646 GenericParamDefKind :: Const { .. } => unreachable ! ( ) ,
16471647 }
@@ -1696,25 +1696,76 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics,
16961696
16971697 let ( gens, preds) = * self ;
16981698
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+
16991703 // Bounds in the type_params and lifetimes fields are repeated in the
17001704 // predicates field (see rustc_typeck::collect::ty_generics), so remove
17011705 // 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) )
17081719 }
1709- Some ( param. clean ( cx) )
1710- }
1711- ty:: GenericParamDefKind :: Const { .. } => None ,
1712- } ) . collect :: < Vec < GenericParamDef > > ( ) ;
1720+ ty:: GenericParamDefKind :: Const { .. } => None ,
1721+ } ) . collect :: < Vec < GenericParamDef > > ( ) ;
17131722
17141723 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+ } )
17161756 . collect :: < Vec < _ > > ( ) ;
17171757
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+
17181769 // Type parameters and have a Sized bound by default unless removed with
17191770 // ?Sized. Scan through the predicates and mark any type parameter with
17201771 // a Sized bound, removing the bounds as we find them.
@@ -2791,7 +2842,7 @@ impl Clean<Type> for hir::Ty {
27912842 if let Some ( new_ty) = cx. ty_substs . borrow ( ) . get ( & did) . cloned ( ) {
27922843 return new_ty;
27932844 }
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 ( ) ) {
27952846 return ImplTrait ( bounds) ;
27962847 }
27972848 }
@@ -3082,7 +3133,13 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
30823133
30833134 ty:: Projection ( ref data) => data. clean ( cx) ,
30843135
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+ }
30863143
30873144 ty:: Opaque ( def_id, substs) => {
30883145 // Grab the "TraitA + TraitB" from `impl TraitA + TraitB`,
0 commit comments