@@ -987,20 +987,26 @@ pub fn ty_of_foreign_item(ccx: &CrateCtxt,
987
987
988
988
fn ty_generics_for_type ( ccx : & CrateCtxt ,
989
989
generics : & ast:: Generics )
990
- -> ty:: Generics
991
- {
992
- ty_generics ( ccx, subst:: TypeSpace , & generics. lifetimes ,
993
- & generics. ty_params , ty:: Generics :: empty ( ) )
990
+ -> ty:: Generics {
991
+ ty_generics ( ccx,
992
+ subst:: TypeSpace ,
993
+ & generics. lifetimes ,
994
+ & generics. ty_params ,
995
+ ty:: Generics :: empty ( ) ,
996
+ & generics. where_clause )
994
997
}
995
998
996
999
fn ty_generics_for_trait ( ccx : & CrateCtxt ,
997
1000
trait_id : ast:: NodeId ,
998
1001
substs : & subst:: Substs ,
999
1002
generics : & ast:: Generics )
1000
- -> ty:: Generics
1001
- {
1002
- let mut generics = ty_generics ( ccx, subst:: TypeSpace , & generics. lifetimes ,
1003
- & generics. ty_params , ty:: Generics :: empty ( ) ) ;
1003
+ -> ty:: Generics {
1004
+ let mut generics = ty_generics ( ccx,
1005
+ subst:: TypeSpace ,
1006
+ & generics. lifetimes ,
1007
+ & generics. ty_params ,
1008
+ ty:: Generics :: empty ( ) ,
1009
+ & generics. where_clause ) ;
1004
1010
1005
1011
// Something of a hack: use the node id for the trait, also as
1006
1012
// the node id for the Self type parameter.
@@ -1032,11 +1038,14 @@ fn ty_generics_for_trait(ccx: &CrateCtxt,
1032
1038
fn ty_generics_for_fn_or_method ( ccx : & CrateCtxt ,
1033
1039
generics : & ast:: Generics ,
1034
1040
base_generics : ty:: Generics )
1035
- -> ty:: Generics
1036
- {
1041
+ -> ty:: Generics {
1037
1042
let early_lifetimes = resolve_lifetime:: early_bound_lifetimes ( generics) ;
1038
- ty_generics ( ccx, subst:: FnSpace , & early_lifetimes,
1039
- & generics. ty_params , base_generics)
1043
+ ty_generics ( ccx,
1044
+ subst:: FnSpace ,
1045
+ & early_lifetimes,
1046
+ & generics. ty_params ,
1047
+ base_generics,
1048
+ & generics. where_clause )
1040
1049
}
1041
1050
1042
1051
// Add the Sized bound, unless the type parameter is marked as `Sized?`.
@@ -1080,9 +1089,9 @@ fn ty_generics(ccx: &CrateCtxt,
1080
1089
space : subst:: ParamSpace ,
1081
1090
lifetimes : & Vec < ast:: LifetimeDef > ,
1082
1091
types : & OwnedSlice < ast:: TyParam > ,
1083
- base_generics : ty:: Generics )
1084
- -> ty :: Generics
1085
- {
1092
+ base_generics : ty:: Generics ,
1093
+ where_clause : & ast :: WhereClause )
1094
+ -> ty :: Generics {
1086
1095
let mut result = base_generics;
1087
1096
1088
1097
for ( i, l) in lifetimes. iter ( ) . enumerate ( ) {
@@ -1095,7 +1104,11 @@ fn ty_generics(ccx: &CrateCtxt,
1095
1104
}
1096
1105
1097
1106
for ( i, param) in types. iter ( ) . enumerate ( ) {
1098
- let def = get_or_create_type_parameter_def ( ccx, space, param, i) ;
1107
+ let def = get_or_create_type_parameter_def ( ccx,
1108
+ space,
1109
+ param,
1110
+ i,
1111
+ where_clause) ;
1099
1112
debug ! ( "ty_generics: def for type param: {}" , def. repr( ccx. tcx) ) ;
1100
1113
result. types . push ( space, def) ;
1101
1114
}
@@ -1105,9 +1118,9 @@ fn ty_generics(ccx: &CrateCtxt,
1105
1118
fn get_or_create_type_parameter_def ( ccx : & CrateCtxt ,
1106
1119
space : subst:: ParamSpace ,
1107
1120
param : & ast:: TyParam ,
1108
- index : uint )
1109
- -> ty :: TypeParameterDef
1110
- {
1121
+ index : uint ,
1122
+ where_clause : & ast :: WhereClause )
1123
+ -> ty :: TypeParameterDef {
1111
1124
match ccx. tcx . ty_param_defs . borrow ( ) . find ( & param. id ) {
1112
1125
Some ( d) => { return ( * d) . clone ( ) ; }
1113
1126
None => { }
@@ -1121,7 +1134,8 @@ fn ty_generics(ccx: &CrateCtxt,
1121
1134
& param. bounds ,
1122
1135
& param. unbound ,
1123
1136
param. ident ,
1124
- param. span ) ) ;
1137
+ param. span ,
1138
+ where_clause) ) ;
1125
1139
let default = param. default . map ( |path| {
1126
1140
let ty = ast_ty_to_ty ( ccx, & ExplicitRscope , & * path) ;
1127
1141
let cur_idx = param_ty. idx ;
@@ -1154,14 +1168,14 @@ fn ty_generics(ccx: &CrateCtxt,
1154
1168
def
1155
1169
}
1156
1170
1157
- fn compute_bounds (
1158
- ccx : & CrateCtxt ,
1159
- param_ty : ty :: ParamTy ,
1160
- ast_bounds : & OwnedSlice < ast:: TyParamBound > ,
1161
- unbound : & Option < ast:: TyParamBound > ,
1162
- ident : ast :: Ident ,
1163
- span : Span ) -> ty :: ParamBounds
1164
- {
1171
+ fn compute_bounds ( ccx : & CrateCtxt ,
1172
+ param_ty : ty :: ParamTy ,
1173
+ ast_bounds : & OwnedSlice < ast :: TyParamBound > ,
1174
+ unbound : & Option < ast:: TyParamBound > ,
1175
+ ident : ast:: Ident ,
1176
+ span : Span ,
1177
+ where_clause : & ast :: WhereClause )
1178
+ -> ty :: ParamBounds {
1165
1179
/*!
1166
1180
* Translate the AST's notion of ty param bounds (which are an
1167
1181
* enum consisting of a newtyped Ty or a region) to ty's
@@ -1174,44 +1188,23 @@ fn ty_generics(ccx: &CrateCtxt,
1174
1188
trait_bounds : Vec :: new ( )
1175
1189
} ;
1176
1190
for ast_bound in ast_bounds. iter ( ) {
1177
- match * ast_bound {
1178
- TraitTyParamBound ( ref b) => {
1179
- let ty = ty:: mk_param ( ccx. tcx , param_ty. space ,
1180
- param_ty. idx , param_ty. def_id ) ;
1181
- let trait_ref = instantiate_trait_ref ( ccx, b, ty) ;
1182
- if !ty:: try_add_builtin_trait (
1183
- ccx. tcx , trait_ref. def_id ,
1184
- & mut param_bounds. builtin_bounds ) {
1185
- // Must be a user-defined trait
1186
- param_bounds. trait_bounds . push ( trait_ref) ;
1187
- }
1188
- }
1189
-
1190
- StaticRegionTyParamBound => {
1191
- param_bounds. builtin_bounds . add ( ty:: BoundStatic ) ;
1192
- }
1193
-
1194
- UnboxedFnTyParamBound ( ref unboxed_function) => {
1195
- let rscope = ExplicitRscope ;
1196
- let self_ty = ty:: mk_param ( ccx. tcx ,
1197
- param_ty. space ,
1198
- param_ty. idx ,
1199
- param_ty. def_id ) ;
1200
- let trait_ref =
1201
- astconv:: trait_ref_for_unboxed_function ( ccx,
1202
- & rscope,
1203
- unboxed_function,
1204
- Some ( self_ty) ) ;
1205
- param_bounds. trait_bounds . push ( Rc :: new ( trait_ref) ) ;
1206
- }
1207
-
1208
- OtherRegionTyParamBound ( span) => {
1209
- if !ccx. tcx . sess . features . issue_5723_bootstrap . get ( ) {
1210
- ccx. tcx . sess . span_err (
1211
- span,
1212
- "only the 'static lifetime is accepted here." ) ;
1213
- }
1214
- }
1191
+ compute_bound ( ccx, & mut param_bounds, param_ty, ast_bound) ;
1192
+ }
1193
+ for predicate in where_clause. predicates . iter ( ) {
1194
+ let predicate_param_id = ccx. tcx
1195
+ . def_map
1196
+ . borrow ( )
1197
+ . find ( & predicate. id )
1198
+ . expect ( "compute_bounds(): resolve \
1199
+ didn't resolve the type \
1200
+ parameter identifier in a \
1201
+ `where` clause")
1202
+ . def_id ( ) ;
1203
+ if param_ty. def_id != predicate_param_id {
1204
+ continue
1205
+ }
1206
+ for bound in predicate. bounds . iter ( ) {
1207
+ compute_bound ( ccx, & mut param_bounds, param_ty, bound) ;
1215
1208
}
1216
1209
}
1217
1210
@@ -1228,6 +1221,54 @@ fn ty_generics(ccx: &CrateCtxt,
1228
1221
param_bounds
1229
1222
}
1230
1223
1224
+ /// Translates the AST's notion of a type parameter bound to
1225
+ /// typechecking's notion of the same, and pushes the resulting bound onto
1226
+ /// the appropriate section of `param_bounds`.
1227
+ fn compute_bound ( ccx : & CrateCtxt ,
1228
+ param_bounds : & mut ty:: ParamBounds ,
1229
+ param_ty : ty:: ParamTy ,
1230
+ ast_bound : & ast:: TyParamBound ) {
1231
+ match * ast_bound {
1232
+ TraitTyParamBound ( ref b) => {
1233
+ let ty = ty:: mk_param ( ccx. tcx , param_ty. space ,
1234
+ param_ty. idx , param_ty. def_id ) ;
1235
+ let trait_ref = instantiate_trait_ref ( ccx, b, ty) ;
1236
+ if !ty:: try_add_builtin_trait (
1237
+ ccx. tcx , trait_ref. def_id ,
1238
+ & mut param_bounds. builtin_bounds ) {
1239
+ // Must be a user-defined trait
1240
+ param_bounds. trait_bounds . push ( trait_ref) ;
1241
+ }
1242
+ }
1243
+
1244
+ StaticRegionTyParamBound => {
1245
+ param_bounds. builtin_bounds . add ( ty:: BoundStatic ) ;
1246
+ }
1247
+
1248
+ UnboxedFnTyParamBound ( ref unboxed_function) => {
1249
+ let rscope = ExplicitRscope ;
1250
+ let self_ty = ty:: mk_param ( ccx. tcx ,
1251
+ param_ty. space ,
1252
+ param_ty. idx ,
1253
+ param_ty. def_id ) ;
1254
+ let trait_ref =
1255
+ astconv:: trait_ref_for_unboxed_function ( ccx,
1256
+ & rscope,
1257
+ unboxed_function,
1258
+ Some ( self_ty) ) ;
1259
+ param_bounds. trait_bounds . push ( Rc :: new ( trait_ref) ) ;
1260
+ }
1261
+
1262
+ OtherRegionTyParamBound ( span) => {
1263
+ if !ccx. tcx . sess . features . issue_5723_bootstrap . get ( ) {
1264
+ ccx. tcx . sess . span_err (
1265
+ span,
1266
+ "only the 'static lifetime is accepted here." ) ;
1267
+ }
1268
+ }
1269
+ }
1270
+ }
1271
+
1231
1272
fn check_bounds_compatible ( tcx : & ty:: ctxt ,
1232
1273
param_bounds : & ty:: ParamBounds ,
1233
1274
ident : ast:: Ident ,
0 commit comments