about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMasaki Hara <ackie.h.gmai@gmail.com>2018-09-11 23:31:48 +0900
committerMasaki Hara <ackie.h.gmai@gmail.com>2018-10-24 21:59:07 +0900
commit250979c0ae90aa9c309efc9dcdac9e559b72b74d (patch)
treed4a1e0e19011d49ef8be2930466fc0d2bec18be2
parent1fb085511e61c3d97f020c9d8d28e567f7cb1694 (diff)
downloadrust-250979c0ae90aa9c309efc9dcdac9e559b72b74d.tar.gz
rust-250979c0ae90aa9c309efc9dcdac9e559b72b74d.zip
Implement vtable shim generation.
-rw-r--r--src/librustc_mir/shim.rs19
1 files changed, 17 insertions, 2 deletions
diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs
index 867b630bb66..4618c44cdde 100644
--- a/src/librustc_mir/shim.rs
+++ b/src/librustc_mir/shim.rs
@@ -43,8 +43,14 @@ fn make_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     let mut result = match instance {
         ty::InstanceDef::Item(..) =>
             bug!("item {:?} passed to make_shim", instance),
-        ty::InstanceDef::VtableShim(..) => {
-            unimplemented!("make_shim({:?})", instance);
+        ty::InstanceDef::VtableShim(def_id) => {
+            build_call_shim(
+                tcx,
+                def_id,
+                Adjustment::DerefMove,
+                CallKind::Direct(def_id),
+                None,
+            )
         }
         ty::InstanceDef::FnPtrShim(def_id, ty) => {
             let trait_ = tcx.trait_of_item(def_id).unwrap();
@@ -131,6 +137,7 @@ fn make_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 enum Adjustment {
     Identity,
     Deref,
+    DerefMove,
     RefMut,
 }
 
@@ -704,6 +711,14 @@ fn build_call_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     let rcvr = match rcvr_adjustment {
         Adjustment::Identity => Operand::Move(rcvr_l),
         Adjustment::Deref => Operand::Copy(rcvr_l.deref()),
+        Adjustment::DerefMove => {
+            // fn(Self, ...) -> fn(*mut Self, ...)
+            let arg_ty = local_decls[rcvr_arg].ty;
+            assert!(arg_ty.is_self());
+            local_decls[rcvr_arg].ty = tcx.mk_mut_ptr(arg_ty);
+
+            Operand::Copy(rcvr_l.deref())
+        }
         Adjustment::RefMut => {
             // let rcvr = &mut rcvr;
             let ref_rcvr = local_decls.push(temp_decl(