about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2018-08-16 10:30:56 +0200
committerRalf Jung <post@ralfj.de>2018-08-22 09:06:28 +0200
commitb1df2ae82e6a2190ab2bfa330cb37e43ab0a727b (patch)
treefb902825ec43b21d17f9e8009c3ef5fc4d33c9c6 /src
parent730098bc8d30a51351e318a3620cb63060449a16 (diff)
downloadrust-b1df2ae82e6a2190ab2bfa330cb37e43ab0a727b.tar.gz
rust-b1df2ae82e6a2190ab2bfa330cb37e43ab0a727b.zip
fix computing layout when calling virtual fn
Diffstat (limited to 'src')
-rw-r--r--src/librustc_mir/interpret/terminator/mod.rs12
1 files changed, 9 insertions, 3 deletions
diff --git a/src/librustc_mir/interpret/terminator/mod.rs b/src/librustc_mir/interpret/terminator/mod.rs
index 5ceff57bfee..9b7df90979d 100644
--- a/src/librustc_mir/interpret/terminator/mod.rs
+++ b/src/librustc_mir/interpret/terminator/mod.rs
@@ -384,10 +384,16 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
                     ptr_align
                 )?.to_ptr()?;
                 let instance = self.memory.get_fn(fn_ptr)?;
+
+                // We have to patch the self argument, in particular get the layout
+                // expected by the actual function. Cannot just use "field 0" due to
+                // Box<self>.
                 let mut args = args.to_vec();
-                let layout = args[0].layout.field(&self, 0)?;
-                args[0].layout = layout;
-                args[0].op = Operand::Immediate(Value::Scalar(ptr.into()));
+                let pointee = args[0].layout.ty.builtin_deref(true).unwrap().ty;
+                let fake_fat_ptr_ty = self.tcx.mk_mut_ptr(pointee);
+                args[0].layout = self.layout_of(fake_fat_ptr_ty)?.field(&self, 0)?;
+                args[0].op = Operand::Immediate(Value::Scalar(ptr.into())); // strip vtable
+                trace!("Patched self operand to {:#?}", args[0]);
                 // recurse with concrete function
                 self.eval_fn_call(instance, destination, &args, span, sig)
             }