1717// closure.
1818
1919use core:: prelude:: * ;
20+ use core:: vec;
2021
2122use back:: abi;
2223use driver:: session;
@@ -194,6 +195,58 @@ pub fn trans_fn_ref_with_vtables_to_callee(
194195 type_params, vtables) ) }
195196}
196197
198+ fn get_impl_resolutions ( bcx : block ,
199+ impl_id : ast:: def_id )
200+ -> typeck:: vtable_res {
201+ if impl_id. crate == ast:: local_crate {
202+ * bcx. ccx ( ) . maps . vtable_map . get ( & impl_id. node )
203+ } else {
204+ // XXX: This is a temporary hack to work around not properly
205+ // exporting information about resolutions for impls.
206+ // This doesn't actually work if the trait has param bounds,
207+ // but it does allow us to survive the case when it does not.
208+ let trait_ref = ty:: impl_trait_ref ( bcx. tcx ( ) , impl_id) . get ( ) ;
209+ @vec:: from_elem ( trait_ref. substs . tps . len ( ) , @~[ ] )
210+ }
211+ }
212+
213+ fn resolve_default_method_vtables ( bcx : block ,
214+ impl_id : ast:: def_id ,
215+ method : & ty:: Method ,
216+ substs : & ty:: substs ,
217+ impl_vtables : Option < typeck:: vtable_res > )
218+ -> typeck:: vtable_res {
219+
220+ // Get the vtables that the impl implements the trait at
221+ let trait_vtables = get_impl_resolutions ( bcx, impl_id) ;
222+
223+ // Build up a param_substs that we are going to resolve the
224+ // trait_vtables under.
225+ let param_substs = Some ( @param_substs {
226+ tys : copy substs. tps ,
227+ self_ty : substs. self_ty ,
228+ vtables : impl_vtables,
229+ self_vtable : None
230+ } ) ;
231+
232+ let trait_vtables_fixed = resolve_vtables_under_param_substs (
233+ bcx. tcx ( ) , param_substs, trait_vtables) ;
234+
235+ // Now we pull any vtables for parameters on the actual method.
236+ let num_method_vtables = method. generics . type_param_defs . len ( ) ;
237+ let method_vtables = match impl_vtables {
238+ Some ( vtables) => {
239+ let num_impl_type_parameters =
240+ vtables. len ( ) - num_method_vtables;
241+ vtables. tailn ( num_impl_type_parameters) . to_owned ( )
242+ } ,
243+ None => vec:: from_elem ( num_method_vtables, @~[ ] )
244+ } ;
245+
246+ @( * trait_vtables_fixed + method_vtables)
247+ }
248+
249+
197250pub fn trans_fn_ref_with_vtables (
198251 bcx : block , //
199252 def_id : ast:: def_id , // def id of fn
@@ -233,15 +286,21 @@ pub fn trans_fn_ref_with_vtables(
233286 // Polytype of the function item (may have type params)
234287 let fn_tpt = ty:: lookup_item_type ( tcx, def_id) ;
235288
236- let substs = ty:: substs { self_r : None , self_ty : None ,
289+ // For simplicity, we want to use the Subst trait when composing
290+ // substitutions for default methods. The subst trait does
291+ // substitutions with regions, though, so we put a dummy self
292+ // region parameter in to keep it from failing. This is a hack.
293+ let substs = ty:: substs { self_r : Some ( ty:: re_empty) ,
294+ self_ty : None ,
237295 tps : /*bad*/ type_params. to_owned ( ) } ;
238296
239297
240298 // We need to do a bunch of special handling for default methods.
241299 // We need to modify the def_id and our substs in order to monomorphize
242300 // the function.
243- let ( def_id, opt_impl_did, substs) = match tcx. provided_method_sources . find ( & def_id) {
244- None => ( def_id, None , substs) ,
301+ let ( def_id, opt_impl_did, substs, self_vtable, vtables) =
302+ match tcx. provided_method_sources . find ( & def_id) {
303+ None => ( def_id, None , substs, None , vtables) ,
245304 Some ( source) => {
246305 // There are two relevant substitutions when compiling
247306 // default methods. First, there is the substitution for
@@ -261,20 +320,42 @@ pub fn trans_fn_ref_with_vtables(
261320 default methods") ;
262321 let method = ty:: method ( tcx, source. method_id ) ;
263322
323+ // Get all of the type params for the receiver
324+ let param_defs = method. generics . type_param_defs ;
325+ let receiver_substs =
326+ type_params. initn ( param_defs. len ( ) ) . to_owned ( ) ;
327+ let receiver_vtables = match vtables {
328+ None => @~[ ] ,
329+ Some ( call_vtables) => {
330+ @call_vtables. initn ( param_defs. len ( ) ) . to_owned ( )
331+ }
332+ } ;
333+
334+ let self_vtable =
335+ typeck:: vtable_static ( source. impl_id , receiver_substs,
336+ receiver_vtables) ;
264337 // Compute the first substitution
265338 let first_subst = make_substs_for_receiver_types (
266339 tcx, source. impl_id , trait_ref, method) ;
267340
268341 // And compose them
269342 let new_substs = first_subst. subst ( tcx, & substs) ;
343+
344+
345+ let vtables =
346+ resolve_default_method_vtables ( bcx, source. impl_id ,
347+ method, & new_substs, vtables) ;
348+
270349 debug ! ( "trans_fn_with_vtables - default method: \
271350 substs = %s, trait_subst = %s, \
272- first_subst = %s, new_subst = %s",
351+ first_subst = %s, new_subst = %s, \
352+ self_vtable = %s, vtables = %s",
273353 substs. repr( tcx) , trait_ref. substs. repr( tcx) ,
274- first_subst. repr( tcx) , new_substs. repr( tcx) ) ;
275-
354+ first_subst. repr( tcx) , new_substs. repr( tcx) ,
355+ self_vtable . repr ( tcx ) , vtables . repr ( tcx ) ) ;
276356
277- ( source. method_id , Some ( source. impl_id ) , new_substs)
357+ ( source. method_id , Some ( source. impl_id ) ,
358+ new_substs, Some ( self_vtable) , Some ( vtables) )
278359 }
279360 } ;
280361
@@ -321,7 +402,8 @@ pub fn trans_fn_ref_with_vtables(
321402
322403 let ( val, must_cast) =
323404 monomorphize:: monomorphic_fn ( ccx, def_id, & substs,
324- vtables, opt_impl_did, Some ( ref_id) ) ;
405+ vtables, self_vtable,
406+ opt_impl_did, Some ( ref_id) ) ;
325407 let mut val = val;
326408 if must_cast && ref_id != 0 {
327409 // Monotype of the REFERENCE to the function (type params
0 commit comments