@@ -186,10 +186,10 @@ pub fn trans_method_callee(bcx: @mut Block,
186
186
}
187
187
}
188
188
189
- typeck:: method_trait ( _ , off ) => {
189
+ typeck:: method_object ( ref mt ) => {
190
190
trans_trait_callee ( bcx,
191
191
callee_id,
192
- off ,
192
+ mt . real_index ,
193
193
this)
194
194
}
195
195
}
@@ -398,7 +398,6 @@ pub fn combine_impl_and_methods_tps(bcx: @mut Block,
398
398
return ( ty_substs, vtables) ;
399
399
}
400
400
401
-
402
401
pub fn trans_trait_callee ( bcx : @mut Block ,
403
402
callee_id : ast:: NodeId ,
404
403
n_method : uint ,
@@ -506,20 +505,35 @@ pub fn vtable_id(ccx: @mut CrateContext,
506
505
/// This is used only for objects.
507
506
pub fn get_vtable ( bcx : @mut Block ,
508
507
self_ty : ty:: t ,
509
- origin : typeck:: vtable_origin )
508
+ origins : typeck:: vtable_param_res )
510
509
-> ValueRef {
511
- let hash_id = vtable_id ( bcx. ccx ( ) , & origin) ;
512
- match bcx. ccx ( ) . vtables . find ( & hash_id) {
513
- Some ( & val) => val,
514
- None => {
515
- match origin {
516
- typeck:: vtable_static( id, substs, sub_vtables) => {
517
- make_impl_vtable ( bcx, id, self_ty, substs, sub_vtables)
518
- }
519
- _ => fail ! ( "get_vtable: expected a static origin" ) ,
510
+ let ccx = bcx. ccx ( ) ;
511
+ let _icx = push_ctxt ( "impl::get_vtable" ) ;
512
+
513
+ // Check the cache.
514
+ let hash_id = ( self_ty, vtable_id ( ccx, & origins[ 0 ] ) ) ;
515
+ match ccx. vtables . find ( & hash_id) {
516
+ Some ( & val) => { return val }
517
+ None => { }
518
+ }
519
+
520
+ // Not in the cache. Actually build it.
521
+ let methods = do origins. flat_map |origin| {
522
+ match * origin {
523
+ typeck:: vtable_static( id, ref substs, sub_vtables) => {
524
+ emit_vtable_methods ( bcx, id, * substs, sub_vtables)
520
525
}
526
+ _ => ccx. sess . bug ( "get_vtable: expected a static origin" ) ,
521
527
}
522
- }
528
+ } ;
529
+
530
+ // Generate a type descriptor for the vtable.
531
+ let tydesc = get_tydesc ( ccx, self_ty) ;
532
+ glue:: lazily_emit_all_tydesc_glue ( ccx, tydesc) ;
533
+
534
+ let vtable = make_vtable ( ccx, tydesc, methods) ;
535
+ ccx. vtables . insert ( hash_id, vtable) ;
536
+ return vtable;
523
537
}
524
538
525
539
/// Helper function to declare and initialize the vtable.
@@ -547,15 +561,12 @@ pub fn make_vtable(ccx: &mut CrateContext,
547
561
}
548
562
}
549
563
550
- /// Generates a dynamic vtable for objects.
551
- pub fn make_impl_vtable ( bcx : @mut Block ,
552
- impl_id : ast:: def_id ,
553
- self_ty : ty:: t ,
554
- substs : & [ ty:: t ] ,
555
- vtables : typeck:: vtable_res )
556
- -> ValueRef {
564
+ fn emit_vtable_methods ( bcx : @mut Block ,
565
+ impl_id : ast:: def_id ,
566
+ substs : & [ ty:: t ] ,
567
+ vtables : typeck:: vtable_res )
568
+ -> ~[ ValueRef ] {
557
569
let ccx = bcx. ccx ( ) ;
558
- let _icx = push_ctxt ( "impl::make_impl_vtable" ) ;
559
570
let tcx = ccx. tcx ;
560
571
561
572
let trt_id = match ty:: impl_trait_ref ( tcx, impl_id) {
@@ -565,7 +576,7 @@ pub fn make_impl_vtable(bcx: @mut Block,
565
576
} ;
566
577
567
578
let trait_method_def_ids = ty:: trait_method_def_ids ( tcx, trt_id) ;
568
- let methods = do trait_method_def_ids. map |method_def_id| {
579
+ do trait_method_def_ids. map |method_def_id| {
569
580
let im = ty:: method ( tcx, * method_def_id) ;
570
581
let fty = ty:: subst_tps ( tcx,
571
582
substs,
@@ -583,13 +594,7 @@ pub fn make_impl_vtable(bcx: @mut Block,
583
594
trans_fn_ref_with_vtables ( bcx, m_id, 0 ,
584
595
substs, Some ( vtables) ) . llfn
585
596
}
586
- } ;
587
-
588
- // Generate a type descriptor for the vtable.
589
- let tydesc = get_tydesc ( ccx, self_ty) ;
590
- glue:: lazily_emit_all_tydesc_glue ( ccx, tydesc) ;
591
-
592
- make_vtable ( ccx, tydesc, methods)
597
+ }
593
598
}
594
599
595
600
pub fn trans_trait_cast ( bcx : @mut Block ,
@@ -621,9 +626,13 @@ pub fn trans_trait_cast(bcx: @mut Block,
621
626
bcx = expr:: trans_into ( bcx, val, SaveIn ( llboxdest) ) ;
622
627
623
628
// Store the vtable into the pair or triple.
624
- let orig = ccx. maps . vtable_map . get ( & id) [ 0 ] [ 0 ] . clone ( ) ;
625
- let orig = resolve_vtable_in_fn_ctxt ( bcx. fcx , & orig) ;
626
- let vtable = get_vtable ( bcx, v_ty, orig) ;
629
+ // This is structured a bit funny because of dynamic borrow failures.
630
+ let origins = {
631
+ let res = ccx. maps . vtable_map . get ( & id) ;
632
+ let res = resolve_vtables_in_fn_ctxt ( bcx. fcx , * res) ;
633
+ res[ 0 ]
634
+ } ;
635
+ let vtable = get_vtable ( bcx, v_ty, origins) ;
627
636
Store ( bcx, vtable, PointerCast ( bcx,
628
637
GEPi ( bcx, lldest, [ 0 u, abi:: trt_field_vtable] ) ,
629
638
val_ty ( vtable) . ptr_to ( ) ) ) ;
0 commit comments