@@ -21,7 +21,7 @@ use rustc::hir::{self, GenericArg, HirVec};
2121use rustc:: hir:: def:: { self , Def , CtorKind } ;
2222use rustc:: hir:: def_id:: { CrateNum , DefId , CRATE_DEF_INDEX , LOCAL_CRATE } ;
2323use rustc:: hir:: map:: DisambiguatedDefPathData ;
24- use rustc:: ty:: subst:: { Kind , InternalSubsts , SubstsRef } ;
24+ use rustc:: ty:: subst:: { Kind , InternalSubsts , SubstsRef , UnpackedKind } ;
2525use rustc:: ty:: { self , DefIdTree , TyCtxt , Region , RegionVid , Ty , AdtKind } ;
2626use rustc:: ty:: fold:: TypeFolder ;
2727use rustc:: ty:: layout:: VariantIdx ;
@@ -1089,42 +1089,48 @@ impl Clean<GenericBound> for hir::GenericBound {
10891089 }
10901090}
10911091
1092- fn external_generic_args ( cx : & DocContext < ' _ > , trait_did : Option < DefId > , has_self : bool ,
1093- bindings : Vec < TypeBinding > , substs : SubstsRef < ' _ > ) -> GenericArgs {
1094- let lifetimes = substs. regions ( ) . filter_map ( |v| v. clean ( cx) ) . collect ( ) ;
1095- let types = substs. types ( ) . skip ( has_self as usize ) . collect :: < Vec < _ > > ( ) ;
1092+ fn external_generic_args (
1093+ cx : & DocContext < ' _ > ,
1094+ trait_did : Option < DefId > ,
1095+ has_self : bool ,
1096+ bindings : Vec < TypeBinding > ,
1097+ substs : SubstsRef < ' _ > ,
1098+ ) -> GenericArgs {
1099+ let mut skip_self = has_self;
1100+ let mut first_ty_sty = None ;
1101+ let args: Vec < _ > = substs. iter ( ) . filter_map ( |kind| match kind. unpack ( ) {
1102+ UnpackedKind :: Lifetime ( lt) => {
1103+ lt. clean ( cx) . and_then ( |lt| Some ( GenericArg :: Lifetime ( lt) ) )
1104+ }
1105+ UnpackedKind :: Type ( _) if skip_self => {
1106+ skip_self = false ;
1107+ None
1108+ }
1109+ UnpackedKind :: Type ( ty) => {
1110+ first_ty_sty = Some ( & ty. sty ) ;
1111+ Some ( GenericArg :: Type ( ty. clean ( cx) ) )
1112+ }
1113+ UnpackedKind :: Const ( ct) => Some ( GenericArg :: Const ( ct. clean ( cx) ) ) ,
1114+ } ) . collect ( ) ;
10961115
10971116 match trait_did {
10981117 // Attempt to sugar an external path like Fn<(A, B,), C> to Fn(A, B) -> C
10991118 Some ( did) if cx. tcx . lang_items ( ) . fn_trait_kind ( did) . is_some ( ) => {
1100- assert_eq ! ( types. len( ) , 1 ) ;
1101- let inputs = match types[ 0 ] . sty {
1102- ty:: Tuple ( ref tys) => tys. iter ( ) . map ( |t| t. clean ( cx) ) . collect ( ) ,
1103- _ => {
1104- return GenericArgs :: AngleBracketed {
1105- lifetimes,
1106- types : types. clean ( cx) ,
1107- bindings,
1108- }
1109- }
1119+ assert ! ( first_ty_sty. is_some( ) ) ;
1120+ let inputs = match first_ty_sty {
1121+ Some ( ty:: Tuple ( ref tys) ) => tys. iter ( ) . map ( |t| t. clean ( cx) ) . collect ( ) ,
1122+ _ => return GenericArgs :: AngleBracketed { args, bindings } ,
11101123 } ;
11111124 let output = None ;
11121125 // FIXME(#20299) return type comes from a projection now
11131126 // match types[1].sty {
11141127 // ty::Tuple(ref v) if v.is_empty() => None, // -> ()
11151128 // _ => Some(types[1].clean(cx))
11161129 // };
1117- GenericArgs :: Parenthesized {
1118- inputs,
1119- output,
1120- }
1130+ GenericArgs :: Parenthesized { inputs, output }
11211131 } ,
11221132 _ => {
1123- GenericArgs :: AngleBracketed {
1124- lifetimes,
1125- types : types. clean ( cx) ,
1126- bindings,
1127- }
1133+ GenericArgs :: AngleBracketed { args, bindings }
11281134 }
11291135 }
11301136}
@@ -1462,7 +1468,7 @@ impl GenericParamDef {
14621468 }
14631469}
14641470
1465- impl < ' tcx > Clean < GenericParamDef > for ty:: GenericParamDef {
1471+ impl Clean < GenericParamDef > for ty:: GenericParamDef {
14661472 fn clean ( & self , cx : & DocContext < ' _ > ) -> GenericParamDef {
14671473 let ( name, kind) = match self . kind {
14681474 ty:: GenericParamDefKind :: Lifetime => {
@@ -1484,7 +1490,10 @@ impl<'tcx> Clean<GenericParamDef> for ty::GenericParamDef {
14841490 } )
14851491 }
14861492 ty:: GenericParamDefKind :: Const { .. } => {
1487- unimplemented ! ( ) // FIXME(const_generics)
1493+ ( self . name . clean ( cx) , GenericParamDefKind :: Const {
1494+ did : self . def_id ,
1495+ ty : cx. tcx . type_of ( self . def_id ) . clean ( cx) ,
1496+ } )
14881497 }
14891498 } ;
14901499
@@ -1685,9 +1694,7 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics,
16851694 . flat_map ( |param| match param. kind {
16861695 ty:: GenericParamDefKind :: Lifetime => Some ( param. clean ( cx) ) ,
16871696 ty:: GenericParamDefKind :: Type { .. } => None ,
1688- ty:: GenericParamDefKind :: Const { .. } => {
1689- unimplemented ! ( ) // FIXME(const_generics)
1690- }
1697+ ty:: GenericParamDefKind :: Const { .. } => Some ( param. clean ( cx) ) ,
16911698 } ) . chain ( simplify:: ty_params ( stripped_typarams) . into_iter ( ) )
16921699 . collect ( ) ,
16931700 where_predicates : simplify:: where_clauses ( cx, where_predicates) ,
@@ -2365,12 +2372,15 @@ impl Type {
23652372 }
23662373 }
23672374
2368- pub fn generics ( & self ) -> Option < & [ Type ] > {
2375+ pub fn generics ( & self ) -> Option < Vec < Type > > {
23692376 match * self {
23702377 ResolvedPath { ref path, .. } => {
23712378 path. segments . last ( ) . and_then ( |seg| {
2372- if let GenericArgs :: AngleBracketed { ref types, .. } = seg. args {
2373- Some ( & * * types)
2379+ if let GenericArgs :: AngleBracketed { ref args, .. } = seg. args {
2380+ Some ( args. iter ( ) . filter_map ( |arg| match arg {
2381+ GenericArg :: Type ( ty) => Some ( ty. clone ( ) ) ,
2382+ _ => None ,
2383+ } ) . collect ( ) )
23742384 } else {
23752385 None
23762386 }
@@ -3267,8 +3277,7 @@ impl fmt::Display for GenericArg {
32673277#[ derive( Clone , RustcEncodable , RustcDecodable , PartialEq , Eq , Debug , Hash ) ]
32683278pub enum GenericArgs {
32693279 AngleBracketed {
3270- lifetimes : Vec < Lifetime > ,
3271- types : Vec < Type > ,
3280+ args : Vec < GenericArg > ,
32723281 bindings : Vec < TypeBinding > ,
32733282 } ,
32743283 Parenthesized {
@@ -3286,27 +3295,19 @@ impl Clean<GenericArgs> for hir::GenericArgs {
32863295 output : if output != Type :: Tuple ( Vec :: new ( ) ) { Some ( output) } else { None }
32873296 }
32883297 } else {
3289- let ( mut lifetimes, mut types) = ( vec ! [ ] , vec ! [ ] ) ;
3290- let mut elided_lifetimes = true ;
3291- for arg in & self . args {
3292- match arg {
3293- GenericArg :: Lifetime ( lt) => {
3294- if !lt. is_elided ( ) {
3295- elided_lifetimes = false ;
3296- }
3297- lifetimes. push ( lt. clean ( cx) ) ;
3298- }
3299- GenericArg :: Type ( ty) => {
3300- types. push ( ty. clean ( cx) ) ;
3301- }
3302- GenericArg :: Const ( ..) => {
3303- unimplemented ! ( ) // FIXME(const_generics)
3304- }
3305- }
3306- }
3298+ let elide_lifetimes = self . args . iter ( ) . all ( |arg| match arg {
3299+ hir:: GenericArg :: Lifetime ( lt) => lt. is_elided ( ) ,
3300+ _ => true ,
3301+ } ) ;
33073302 GenericArgs :: AngleBracketed {
3308- lifetimes : if elided_lifetimes { vec ! [ ] } else { lifetimes } ,
3309- types,
3303+ args : self . args . iter ( ) . filter_map ( |arg| match arg {
3304+ hir:: GenericArg :: Lifetime ( lt) if !elide_lifetimes => {
3305+ Some ( GenericArg :: Lifetime ( lt. clean ( cx) ) )
3306+ }
3307+ hir:: GenericArg :: Lifetime ( _) => None ,
3308+ hir:: GenericArg :: Type ( ty) => Some ( GenericArg :: Type ( ty. clean ( cx) ) ) ,
3309+ hir:: GenericArg :: Const ( ct) => Some ( GenericArg :: Const ( ct. clean ( cx) ) ) ,
3310+ } ) . collect ( ) ,
33103311 bindings : self . bindings . clean ( cx) ,
33113312 }
33123313 }
@@ -3358,9 +3359,8 @@ fn strip_path(path: &Path) -> Path {
33583359 PathSegment {
33593360 name : s. name . clone ( ) ,
33603361 args : GenericArgs :: AngleBracketed {
3361- lifetimes : Vec :: new ( ) ,
3362- types : Vec :: new ( ) ,
3363- bindings : Vec :: new ( ) ,
3362+ args : vec ! [ ] ,
3363+ bindings : vec ! [ ] ,
33643364 }
33653365 }
33663366 } ) . collect ( ) ;
@@ -3511,7 +3511,7 @@ impl Clean<Item> for doctree::Static {
35113511 }
35123512}
35133513
3514- #[ derive( Clone , RustcEncodable , RustcDecodable , Debug ) ]
3514+ #[ derive( Clone , PartialEq , Eq , Hash , RustcEncodable , RustcDecodable , Debug ) ]
35153515pub struct Constant {
35163516 pub type_ : Type ,
35173517 pub expr : String ,
0 commit comments