@@ -12,7 +12,7 @@ use syntax::codemap::{DUMMY_SP, Span};
12
12
13
13
use super :: { EvalContext , IntegerExt } ;
14
14
use error:: { EvalError , EvalResult } ;
15
- use memory:: { Pointer , FunctionDefinition } ;
15
+ use memory:: Pointer ;
16
16
17
17
impl < ' a , ' tcx > EvalContext < ' a , ' tcx > {
18
18
@@ -90,7 +90,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
90
90
ty:: TyFnPtr ( bare_fn_ty) => {
91
91
let ptr = self . eval_operand ( func) ?;
92
92
let fn_ptr = self . memory . read_ptr ( ptr) ?;
93
- let FunctionDefinition { def_id, substs, fn_ty } = self . memory . get_fn ( fn_ptr. alloc_id ) ?;
93
+ let ( def_id, substs, fn_ty) = self . memory . get_fn ( fn_ptr. alloc_id ) ?;
94
94
if fn_ty != bare_fn_ty {
95
95
return Err ( EvalError :: FunctionPointerTyMismatch ( fn_ty, bare_fn_ty) ) ;
96
96
}
@@ -172,21 +172,21 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
172
172
// TODO(solson): Adjust the first argument when calling a Fn or
173
173
// FnMut closure via FnOnce::call_once.
174
174
175
- // Only trait methods can have a Self parameter.
176
- let ( resolved_def_id, resolved_substs) =
177
- if let Some ( trait_id) = self . tcx . trait_of_item ( def_id) {
178
- self . trait_method ( trait_id, def_id, substs)
179
- } else {
180
- ( def_id, substs)
181
- } ;
182
-
183
175
let mut arg_srcs = Vec :: new ( ) ;
184
176
for arg in args {
185
177
let src = self . eval_operand ( arg) ?;
186
178
let src_ty = self . operand_ty ( arg) ;
187
179
arg_srcs. push ( ( src, src_ty) ) ;
188
180
}
189
181
182
+ // Only trait methods can have a Self parameter.
183
+ let ( resolved_def_id, resolved_substs) =
184
+ if let Some ( trait_id) = self . tcx . trait_of_item ( def_id) {
185
+ self . trait_method ( trait_id, def_id, substs, arg_srcs. get_mut ( 0 ) ) ?
186
+ } else {
187
+ ( def_id, substs)
188
+ } ;
189
+
190
190
if fn_ty. abi == Abi :: RustCall && !args. is_empty ( ) {
191
191
arg_srcs. pop ( ) ;
192
192
let last_arg = args. last ( ) . unwrap ( ) ;
@@ -464,7 +464,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
464
464
Ok ( ( ) )
465
465
}
466
466
467
- fn fulfill_obligation ( & self , trait_ref : ty:: PolyTraitRef < ' tcx > ) -> traits:: Vtable < ' tcx , ( ) > {
467
+ pub ( super ) fn fulfill_obligation ( & self , trait_ref : ty:: PolyTraitRef < ' tcx > ) -> traits:: Vtable < ' tcx , ( ) > {
468
468
// Do the initial selection for the obligation. This yields the shallow result we are
469
469
// looking for -- that is, what specific impl.
470
470
self . tcx . infer_ctxt ( None , None , Reveal :: All ) . enter ( |infcx| {
@@ -491,8 +491,9 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
491
491
& self ,
492
492
trait_id : DefId ,
493
493
def_id : DefId ,
494
- substs : & ' tcx Substs < ' tcx >
495
- ) -> ( DefId , & ' tcx Substs < ' tcx > ) {
494
+ substs : & ' tcx Substs < ' tcx > ,
495
+ first_arg : Option < & mut ( Pointer , Ty < ' tcx > ) > ,
496
+ ) -> EvalResult < ' tcx , ( DefId , & ' tcx Substs < ' tcx > ) > {
496
497
let trait_ref = ty:: TraitRef :: from_method ( self . tcx , trait_id, substs) ;
497
498
let trait_ref = self . tcx . normalize_associated_type ( & ty:: Binder ( trait_ref) ) ;
498
499
@@ -504,11 +505,11 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
504
505
// and those from the method:
505
506
let mth = get_impl_method ( self . tcx , substs, impl_did, vtable_impl. substs , mname) ;
506
507
507
- ( mth. method . def_id , mth. substs )
508
+ Ok ( ( mth. method . def_id , mth. substs ) )
508
509
}
509
510
510
511
traits:: VtableClosure ( vtable_closure) =>
511
- ( vtable_closure. closure_def_id , vtable_closure. substs . func_substs ) ,
512
+ Ok ( ( vtable_closure. closure_def_id , vtable_closure. substs . func_substs ) ) ,
512
513
513
514
traits:: VtableFnPointer ( _fn_ty) => {
514
515
let _trait_closure_kind = self . tcx . lang_items . fn_trait_kind ( trait_id) . unwrap ( ) ;
@@ -524,14 +525,22 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
524
525
// Callee::ptr(immediate_rvalue(llfn, fn_ptr_ty))
525
526
}
526
527
527
- traits:: VtableObject ( ref _data) => {
528
- unimplemented ! ( )
529
- // Callee {
530
- // data: Virtual(traits::get_vtable_index_of_object_method(
531
- // tcx, data, def_id)),
532
- // ty: def_ty(tcx, def_id, substs)
533
- // }
534
- }
528
+ traits:: VtableObject ( ref data) => {
529
+ let idx = self . tcx . get_vtable_index_of_object_method ( data, def_id) ;
530
+ if let Some ( & mut ( first_arg, ref mut first_ty) ) = first_arg {
531
+ let ( _, vtable) = self . get_fat_ptr ( first_arg) ;
532
+ let vtable = self . memory . read_ptr ( vtable) ?;
533
+ let idx = idx + 3 ;
534
+ let offset = idx * self . memory . pointer_size ( ) ;
535
+ let fn_ptr = self . memory . read_ptr ( vtable. offset ( offset as isize ) ) ?;
536
+ let ( def_id, substs, ty) = self . memory . get_fn ( fn_ptr. alloc_id ) ?;
537
+ // FIXME: skip_binder is wrong for HKL
538
+ * first_ty = ty. sig . skip_binder ( ) . inputs [ 0 ] ;
539
+ Ok ( ( def_id, substs) )
540
+ } else {
541
+ Err ( EvalError :: VtableForArgumentlessMethod )
542
+ }
543
+ } ,
535
544
vtable => bug ! ( "resolved vtable bad vtable {:?} in trans" , vtable) ,
536
545
}
537
546
}
@@ -566,14 +575,14 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
566
575
}
567
576
568
577
#[ derive( Debug ) ]
569
- struct ImplMethod < ' tcx > {
570
- method : Rc < ty:: Method < ' tcx > > ,
571
- substs : & ' tcx Substs < ' tcx > ,
572
- is_provided : bool ,
578
+ pub ( super ) struct ImplMethod < ' tcx > {
579
+ pub ( super ) method : Rc < ty:: Method < ' tcx > > ,
580
+ pub ( super ) substs : & ' tcx Substs < ' tcx > ,
581
+ pub ( super ) is_provided : bool ,
573
582
}
574
583
575
584
/// Locates the applicable definition of a method, given its name.
576
- fn get_impl_method < ' a , ' tcx > (
585
+ pub ( super ) fn get_impl_method < ' a , ' tcx > (
577
586
tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
578
587
substs : & ' tcx Substs < ' tcx > ,
579
588
impl_def_id : DefId ,
0 commit comments