@@ -33,10 +33,10 @@ use rustc::middle::resolve_lifetime as rl;
33
33
use rustc:: ty:: fold:: TypeFolder ;
34
34
use rustc:: middle:: lang_items;
35
35
use rustc:: mir:: interpret:: GlobalId ;
36
- use rustc:: hir:: { self , GenericArg , HirVec } ;
36
+ use rustc:: hir:: { self , HirVec } ;
37
37
use rustc:: hir:: def:: { self , Def , CtorKind } ;
38
38
use rustc:: hir:: def_id:: { CrateNum , DefId , CRATE_DEF_INDEX , LOCAL_CRATE } ;
39
- use rustc:: ty:: subst:: Substs ;
39
+ use rustc:: ty:: subst:: { Substs , UnpackedKind } ;
40
40
use rustc:: ty:: { self , TyCtxt , Region , RegionVid , Ty , AdtKind } ;
41
41
use rustc:: middle:: stability;
42
42
use rustc:: util:: nodemap:: { FxHashMap , FxHashSet } ;
@@ -1069,43 +1069,41 @@ impl Clean<GenericBound> for hir::GenericBound {
1069
1069
1070
1070
fn external_generic_args ( cx : & DocContext , trait_did : Option < DefId > , has_self : bool ,
1071
1071
bindings : Vec < TypeBinding > , substs : & Substs ) -> GenericArgs {
1072
- let lifetimes = substs. regions ( ) . filter_map ( |lt| lt. clean ( cx) ) . collect ( ) ;
1073
- let types = substs. types ( ) . skip ( has_self as usize ) . collect :: < Vec < _ > > ( ) ;
1074
- let consts = substs. consts ( ) . map ( |ct| ct. clean ( cx) ) . collect ( ) ;
1072
+ let mut skip_self = has_self;
1073
+ let mut first_ty_sty = None ;
1074
+ let args: Vec < _ > = substs. iter ( ) . filter_map ( |kind| match kind. unpack ( ) {
1075
+ UnpackedKind :: Lifetime ( lt) => {
1076
+ lt. clean ( cx) . and_then ( |lt| Some ( GenericArg :: Lifetime ( lt) ) )
1077
+ }
1078
+ UnpackedKind :: Type ( _) if skip_self => {
1079
+ skip_self = false ;
1080
+ None
1081
+ }
1082
+ UnpackedKind :: Type ( ty) => {
1083
+ first_ty_sty = Some ( & ty. sty ) ;
1084
+ Some ( GenericArg :: Type ( ty. clean ( cx) ) )
1085
+ }
1086
+ UnpackedKind :: Const ( ct) => Some ( GenericArg :: Const ( ct. clean ( cx) ) ) ,
1087
+ } ) . collect ( ) ;
1075
1088
1076
1089
match trait_did {
1077
1090
// Attempt to sugar an external path like Fn<(A, B,), C> to Fn(A, B) -> C
1078
1091
Some ( did) if cx. tcx . lang_items ( ) . fn_trait_kind ( did) . is_some ( ) => {
1079
1092
assert_eq ! ( types. len( ) , 1 ) ;
1080
1093
let inputs = match types[ 0 ] . sty {
1081
1094
ty:: Tuple ( ref tys) => tys. iter ( ) . map ( |t| t. clean ( cx) ) . collect ( ) ,
1082
- _ => {
1083
- return GenericArgs :: AngleBracketed {
1084
- lifetimes,
1085
- types : types. clean ( cx) ,
1086
- consts,
1087
- bindings,
1088
- }
1089
- }
1095
+ _ => return GenericArgs :: AngleBracketed { args, bindings } ,
1090
1096
} ;
1091
1097
let output = None ;
1092
1098
// FIXME(#20299) return type comes from a projection now
1093
1099
// match types[1].sty {
1094
1100
// ty::Tuple(ref v) if v.is_empty() => None, // -> ()
1095
1101
// _ => Some(types[1].clean(cx))
1096
1102
// };
1097
- GenericArgs :: Parenthesized {
1098
- inputs,
1099
- output,
1100
- }
1103
+ GenericArgs :: Parenthesized { inputs, output }
1101
1104
} ,
1102
1105
_ => {
1103
- GenericArgs :: AngleBracketed {
1104
- lifetimes,
1105
- types : types. clean ( cx) ,
1106
- consts,
1107
- bindings,
1108
- }
1106
+ GenericArgs :: AngleBracketed { args, bindings }
1109
1107
}
1110
1108
}
1111
1109
}
@@ -2260,12 +2258,15 @@ impl Type {
2260
2258
}
2261
2259
}
2262
2260
2263
- pub fn generics ( & self ) -> Option < & [ Type ] > {
2261
+ pub fn generics ( & self ) -> Option < Vec < Type > > {
2264
2262
match * self {
2265
2263
ResolvedPath { ref path, .. } => {
2266
2264
path. segments . last ( ) . and_then ( |seg| {
2267
- if let GenericArgs :: AngleBracketed { ref types, .. } = seg. args {
2268
- Some ( & * * types)
2265
+ if let GenericArgs :: AngleBracketed { ref args, .. } = seg. args {
2266
+ Some ( args. iter ( ) . filter_map ( |arg| match arg {
2267
+ GenericArg :: Type ( ty) => Some ( ty. clone ( ) ) ,
2268
+ _ => None ,
2269
+ } ) . collect ( ) )
2269
2270
} else {
2270
2271
None
2271
2272
}
@@ -2477,7 +2478,7 @@ impl Clean<Type> for hir::Ty {
2477
2478
let mut j = 0 ;
2478
2479
let lifetime = generic_args. args . iter ( ) . find_map ( |arg| {
2479
2480
match arg {
2480
- GenericArg :: Lifetime ( lt) => {
2481
+ hir :: GenericArg :: Lifetime ( lt) => {
2481
2482
if indices. lifetimes == j {
2482
2483
return Some ( lt) ;
2483
2484
}
@@ -2502,7 +2503,7 @@ impl Clean<Type> for hir::Ty {
2502
2503
let mut j = 0 ;
2503
2504
let type_ = generic_args. args . iter ( ) . find_map ( |arg| {
2504
2505
match arg {
2505
- GenericArg :: Type ( ty) => {
2506
+ hir :: GenericArg :: Type ( ty) => {
2506
2507
if indices. types == j {
2507
2508
return Some ( ty) ;
2508
2509
}
@@ -2525,7 +2526,7 @@ impl Clean<Type> for hir::Ty {
2525
2526
let mut j = 0 ;
2526
2527
let const_ = generic_args. args . iter ( ) . find_map ( |arg| {
2527
2528
match arg {
2528
- GenericArg :: Const ( ct) => {
2529
+ hir :: GenericArg :: Const ( ct) => {
2529
2530
if indices. consts == j {
2530
2531
return Some ( ct) ;
2531
2532
}
@@ -3117,13 +3118,27 @@ impl Clean<Path> for hir::Path {
3117
3118
}
3118
3119
}
3119
3120
3121
+ #[ derive( Clone , RustcEncodable , RustcDecodable , PartialEq , Eq , Debug , Hash ) ]
3122
+ pub enum GenericArg {
3123
+ Lifetime ( Lifetime ) ,
3124
+ Type ( Type ) ,
3125
+ Const ( Constant ) ,
3126
+ }
3127
+
3128
+ impl fmt:: Display for GenericArg {
3129
+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
3130
+ match self {
3131
+ GenericArg :: Lifetime ( lt) => lt. fmt ( f) ,
3132
+ GenericArg :: Type ( ty) => ty. fmt ( f) ,
3133
+ GenericArg :: Const ( ct) => ct. fmt ( f) ,
3134
+ }
3135
+ }
3136
+ }
3137
+
3120
3138
#[ derive( Clone , RustcEncodable , RustcDecodable , PartialEq , Eq , Debug , Hash ) ]
3121
3139
pub enum GenericArgs {
3122
3140
AngleBracketed {
3123
- // TODO(const_generics): clean this up
3124
- lifetimes : Vec < Lifetime > ,
3125
- types : Vec < Type > ,
3126
- consts : Vec < Constant > ,
3141
+ args : Vec < GenericArg > ,
3127
3142
bindings : Vec < TypeBinding > ,
3128
3143
} ,
3129
3144
Parenthesized {
@@ -3141,24 +3156,19 @@ impl Clean<GenericArgs> for hir::GenericArgs {
3141
3156
output : if output != Type :: Tuple ( Vec :: new ( ) ) { Some ( output) } else { None }
3142
3157
}
3143
3158
} else {
3144
- let ( mut lifetimes, mut types, mut consts) = ( vec ! [ ] , vec ! [ ] , vec ! [ ] ) ;
3145
- let mut elided_lifetimes = true ;
3146
- for arg in & self . args {
3147
- match arg {
3148
- GenericArg :: Lifetime ( lt) => {
3149
- if !lt. is_elided ( ) {
3150
- elided_lifetimes = false ;
3151
- }
3152
- lifetimes. push ( lt. clean ( cx) ) ;
3153
- }
3154
- GenericArg :: Type ( ty) => types. push ( ty. clean ( cx) ) ,
3155
- GenericArg :: Const ( ct) => consts. push ( ct. clean ( cx) ) ,
3156
- }
3157
- }
3159
+ let elide_lifetimes = self . args . iter ( ) . all ( |arg| match arg {
3160
+ hir:: GenericArg :: Lifetime ( lt) => lt. is_elided ( ) ,
3161
+ _ => true ,
3162
+ } ) ;
3158
3163
GenericArgs :: AngleBracketed {
3159
- lifetimes : if elided_lifetimes { vec ! [ ] } else { lifetimes } ,
3160
- types,
3161
- consts,
3164
+ args : self . args . iter ( ) . filter_map ( |arg| match arg {
3165
+ hir:: GenericArg :: Lifetime ( lt) if !elide_lifetimes => {
3166
+ Some ( GenericArg :: Lifetime ( lt. clean ( cx) ) )
3167
+ }
3168
+ hir:: GenericArg :: Lifetime ( _) => None ,
3169
+ hir:: GenericArg :: Type ( ty) => Some ( GenericArg :: Type ( ty. clean ( cx) ) ) ,
3170
+ hir:: GenericArg :: Const ( ct) => Some ( GenericArg :: Const ( ct. clean ( cx) ) ) ,
3171
+ } ) . collect ( ) ,
3162
3172
bindings : self . bindings . clean ( cx) ,
3163
3173
}
3164
3174
}
@@ -3210,9 +3220,7 @@ fn strip_path(path: &Path) -> Path {
3210
3220
PathSegment {
3211
3221
name : s. name . clone ( ) ,
3212
3222
args : GenericArgs :: AngleBracketed {
3213
- lifetimes : vec ! [ ] ,
3214
- types : vec ! [ ] ,
3215
- consts : vec ! [ ] ,
3223
+ args : vec ! [ ] ,
3216
3224
bindings : vec ! [ ] ,
3217
3225
}
3218
3226
}
0 commit comments