@@ -987,20 +987,26 @@ pub fn ty_of_foreign_item(ccx: &CrateCtxt,
987987
988988fn ty_generics_for_type ( ccx : & CrateCtxt ,
989989 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 )
994997}
995998
996999fn ty_generics_for_trait ( ccx : & CrateCtxt ,
9971000 trait_id : ast:: NodeId ,
9981001 substs : & subst:: Substs ,
9991002 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 ) ;
10041010
10051011 // Something of a hack: use the node id for the trait, also as
10061012 // the node id for the Self type parameter.
@@ -1032,11 +1038,14 @@ fn ty_generics_for_trait(ccx: &CrateCtxt,
10321038fn ty_generics_for_fn_or_method ( ccx : & CrateCtxt ,
10331039 generics : & ast:: Generics ,
10341040 base_generics : ty:: Generics )
1035- -> ty:: Generics
1036- {
1041+ -> ty:: Generics {
10371042 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 )
10401049}
10411050
10421051// Add the Sized bound, unless the type parameter is marked as `Sized?`.
@@ -1080,9 +1089,9 @@ fn ty_generics(ccx: &CrateCtxt,
10801089 space : subst:: ParamSpace ,
10811090 lifetimes : & Vec < ast:: LifetimeDef > ,
10821091 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 {
10861095 let mut result = base_generics;
10871096
10881097 for ( i, l) in lifetimes. iter ( ) . enumerate ( ) {
@@ -1095,7 +1104,11 @@ fn ty_generics(ccx: &CrateCtxt,
10951104 }
10961105
10971106 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) ;
10991112 debug ! ( "ty_generics: def for type param: {}" , def. repr( ccx. tcx) ) ;
11001113 result. types . push ( space, def) ;
11011114 }
@@ -1105,9 +1118,9 @@ fn ty_generics(ccx: &CrateCtxt,
11051118 fn get_or_create_type_parameter_def ( ccx : & CrateCtxt ,
11061119 space : subst:: ParamSpace ,
11071120 param : & ast:: TyParam ,
1108- index : uint )
1109- -> ty :: TypeParameterDef
1110- {
1121+ index : uint ,
1122+ where_clause : & ast :: WhereClause )
1123+ -> ty :: TypeParameterDef {
11111124 match ccx. tcx . ty_param_defs . borrow ( ) . find ( & param. id ) {
11121125 Some ( d) => { return ( * d) . clone ( ) ; }
11131126 None => { }
@@ -1121,7 +1134,8 @@ fn ty_generics(ccx: &CrateCtxt,
11211134 & param. bounds ,
11221135 & param. unbound ,
11231136 param. ident ,
1124- param. span ) ) ;
1137+ param. span ,
1138+ where_clause) ) ;
11251139 let default = param. default . map ( |path| {
11261140 let ty = ast_ty_to_ty ( ccx, & ExplicitRscope , & * path) ;
11271141 let cur_idx = param_ty. idx ;
@@ -1154,14 +1168,14 @@ fn ty_generics(ccx: &CrateCtxt,
11541168 def
11551169 }
11561170
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 {
11651179 /*!
11661180 * Translate the AST's notion of ty param bounds (which are an
11671181 * enum consisting of a newtyped Ty or a region) to ty's
@@ -1174,44 +1188,23 @@ fn ty_generics(ccx: &CrateCtxt,
11741188 trait_bounds : Vec :: new ( )
11751189 } ;
11761190 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) ;
12151208 }
12161209 }
12171210
@@ -1228,6 +1221,54 @@ fn ty_generics(ccx: &CrateCtxt,
12281221 param_bounds
12291222 }
12301223
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+
12311272 fn check_bounds_compatible ( tcx : & ty:: ctxt ,
12321273 param_bounds : & ty:: ParamBounds ,
12331274 ident : ast:: Ident ,
0 commit comments