@@ -1172,15 +1172,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
11721172 self . tcx . mk_var ( self . next_ty_var_id ( false ) )
11731173 }
11741174
1175- pub fn next_ty_var_with_default ( & self ,
1176- default : Option < type_variable:: Default < ' tcx > > ) -> Ty < ' tcx > {
1177- let ty_var_id = self . type_variables
1178- . borrow_mut ( )
1179- . new_var ( false , default) ;
1180-
1181- self . tcx . mk_var ( ty_var_id)
1182- }
1183-
11841175 pub fn next_diverging_ty_var ( & self ) -> Ty < ' tcx > {
11851176 self . tcx . mk_var ( self . next_ty_var_id ( true ) )
11861177 }
@@ -1205,35 +1196,49 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
12051196 ty:: ReVar ( self . region_vars . new_region_var ( origin) )
12061197 }
12071198
1199+ /// Create a region inference variable for the given
1200+ /// region parameter definition.
1201+ pub fn region_var_for_def ( & self ,
1202+ span : Span ,
1203+ def : & ty:: RegionParameterDef )
1204+ -> ty:: Region {
1205+ self . next_region_var ( EarlyBoundRegion ( span, def. name ) )
1206+ }
1207+
1208+ /// Create a type inference variable for the given
1209+ /// type parameter definition. The substitutions are
1210+ /// for actual parameters that may be referred to by
1211+ /// the default of this type parameter, if it exists.
1212+ /// E.g. `struct Foo<A, B, C = (A, B)>(...);` when
1213+ /// used in a path such as `Foo::<T, U>::new()` will
1214+ /// use an inference variable for `C` with `[T, U]`
1215+ /// as the substitutions for the default, `(T, U)`.
1216+ pub fn type_var_for_def ( & self ,
1217+ span : Span ,
1218+ def : & ty:: TypeParameterDef < ' tcx > ,
1219+ substs : & Substs < ' tcx > )
1220+ -> Ty < ' tcx > {
1221+ let default = def. default . map ( |default| {
1222+ type_variable:: Default {
1223+ ty : default. subst_spanned ( self . tcx , substs, Some ( span) ) ,
1224+ origin_span : span,
1225+ def_id : def. default_def_id
1226+ }
1227+ } ) ;
1228+
1229+
1230+ let ty_var_id = self . type_variables
1231+ . borrow_mut ( )
1232+ . new_var ( false , default) ;
1233+
1234+ self . tcx . mk_var ( ty_var_id)
1235+ }
1236+
12081237 pub fn region_vars_for_defs ( & self ,
12091238 span : Span ,
12101239 defs : & [ ty:: RegionParameterDef ] )
12111240 -> Vec < ty:: Region > {
1212- defs. iter ( )
1213- . map ( |d| self . next_region_var ( EarlyBoundRegion ( span, d. name ) ) )
1214- . collect ( )
1215- }
1216-
1217- // We have to take `&mut Substs` in order to provide the correct substitutions for defaults
1218- // along the way, for this reason we don't return them.
1219- pub fn type_vars_for_defs ( & self ,
1220- span : Span ,
1221- space : subst:: ParamSpace ,
1222- substs : & mut Substs < ' tcx > ,
1223- defs : & [ ty:: TypeParameterDef < ' tcx > ] ) {
1224-
1225- for def in defs. iter ( ) {
1226- let default = def. default . map ( |default| {
1227- type_variable:: Default {
1228- ty : default. subst_spanned ( self . tcx , substs, Some ( span) ) ,
1229- origin_span : span,
1230- def_id : def. default_def_id
1231- }
1232- } ) ;
1233-
1234- let ty_var = self . next_ty_var_with_default ( default) ;
1235- substs. types . push ( space, ty_var) ;
1236- }
1241+ defs. iter ( ) . map ( |def| self . region_var_for_def ( span, def) ) . collect ( )
12371242 }
12381243
12391244 /// Given a set of generics defined on a type or impl, returns a substitution mapping each
@@ -1243,21 +1248,13 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
12431248 generics : & ty:: Generics < ' tcx > )
12441249 -> & ' tcx subst:: Substs < ' tcx >
12451250 {
1246- let type_params = subst:: VecPerParamSpace :: empty ( ) ;
1247-
1248- let region_params =
1249- generics. regions . map (
1250- |d| self . next_region_var ( EarlyBoundRegion ( span, d. name ) ) ) ;
1251-
1252- let mut substs = subst:: Substs :: new ( type_params, region_params) ;
1253-
1254- for space in subst:: ParamSpace :: all ( ) . iter ( ) {
1255- self . type_vars_for_defs (
1256- span,
1257- * space,
1258- & mut substs,
1259- generics. types . get_slice ( * space) ) ;
1260- }
1251+ let type_defs = generics. types . as_full_slice ( ) ;
1252+ let region_defs = generics. regions . as_full_slice ( ) ;
1253+ let substs = Substs :: from_param_defs ( region_defs, type_defs, |def| {
1254+ self . region_var_for_def ( span, def)
1255+ } , |def, substs| {
1256+ self . type_var_for_def ( span, def, substs)
1257+ } ) ;
12611258
12621259 self . tcx . mk_substs ( substs)
12631260 }
@@ -1269,25 +1266,24 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
12691266 span : Span ,
12701267 generics : & ty:: Generics < ' tcx > ,
12711268 self_ty : Ty < ' tcx > )
1272- -> subst:: Substs < ' tcx >
1269+ -> & ' tcx subst:: Substs < ' tcx >
12731270 {
1274-
12751271 assert ! ( generics. types. len( subst:: SelfSpace ) == 1 ) ;
12761272 assert ! ( generics. types. len( subst:: FnSpace ) == 0 ) ;
1277- assert ! ( generics. regions. len( subst:: SelfSpace ) == 0 ) ;
1278- assert ! ( generics. regions. len( subst:: FnSpace ) == 0 ) ;
1279-
1280- let type_params = Vec :: new ( ) ;
1281-
1282- let region_param_defs = generics. regions . get_slice ( subst:: TypeSpace ) ;
1283- let regions = self . region_vars_for_defs ( span, region_param_defs) ;
12841273
1285- let mut substs = subst:: Substs :: new_trait ( type_params, regions, self_ty) ;
1286-
1287- let type_parameter_defs = generics. types . get_slice ( subst:: TypeSpace ) ;
1288- self . type_vars_for_defs ( span, subst:: TypeSpace , & mut substs, type_parameter_defs) ;
1274+ let type_defs = generics. types . as_full_slice ( ) ;
1275+ let region_defs = generics. regions . as_full_slice ( ) ;
1276+ let substs = Substs :: from_param_defs ( region_defs, type_defs, |def| {
1277+ self . region_var_for_def ( span, def)
1278+ } , |def, substs| {
1279+ if def. space == subst:: SelfSpace {
1280+ self_ty
1281+ } else {
1282+ self . type_var_for_def ( span, def, substs)
1283+ }
1284+ } ) ;
12891285
1290- return substs;
1286+ self . tcx . mk_substs ( substs)
12911287 }
12921288
12931289 pub fn fresh_bound_region ( & self , debruijn : ty:: DebruijnIndex ) -> ty:: Region {
0 commit comments