From fe3f606cda083aec9564add4f7ff6ed4c4a0fff7 Mon Sep 17 00:00:00 2001 From: Masaki Hara Date: Tue, 11 Sep 2018 23:26:38 +0900 Subject: [PATCH] Add ty_fn_sig_vtable for getting adjusted signature for vtable shims. --- src/librustc_codegen_llvm/base.rs | 2 +- src/librustc_codegen_llvm/callee.rs | 2 +- src/librustc_codegen_llvm/common.rs | 19 +++++++++++++++++++ 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/librustc_codegen_llvm/base.rs b/src/librustc_codegen_llvm/base.rs index 614a562846e86..501a0b8af76bb 100644 --- a/src/librustc_codegen_llvm/base.rs +++ b/src/librustc_codegen_llvm/base.rs @@ -492,7 +492,7 @@ pub fn codegen_instance<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, instance: Instance<' info!("codegen_instance({})", instance); let fn_ty = instance.ty(cx.tcx); - let sig = common::ty_fn_sig(cx, fn_ty); + let sig = common::ty_fn_sig_vtable(cx, fn_ty, instance.is_vtable_shim()); let sig = cx.tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig); let lldecl = cx.instances.borrow().get(&instance).cloned().unwrap_or_else(|| diff --git a/src/librustc_codegen_llvm/callee.rs b/src/librustc_codegen_llvm/callee.rs index 4b4ccb3b600b3..972cccd5d68e0 100644 --- a/src/librustc_codegen_llvm/callee.rs +++ b/src/librustc_codegen_llvm/callee.rs @@ -56,7 +56,7 @@ pub fn get_fn( debug!("get_fn({:?}: {:?}) => {}", instance, fn_ty, sym); // Create a fn pointer with the substituted signature. - let fn_ptr_ty = tcx.mk_fn_ptr(common::ty_fn_sig(cx, fn_ty)); + let fn_ptr_ty = tcx.mk_fn_ptr(common::ty_fn_sig_vtable(cx, fn_ty, instance.is_vtable_shim())); let llptrty = cx.layout_of(fn_ptr_ty).llvm_type(cx); let llfn = if let Some(llfn) = declare::get_declared_value(cx, &sym) { diff --git a/src/librustc_codegen_llvm/common.rs b/src/librustc_codegen_llvm/common.rs index c08937fa9b916..df91f75837422 100644 --- a/src/librustc_codegen_llvm/common.rs +++ b/src/librustc_codegen_llvm/common.rs @@ -453,3 +453,22 @@ pub fn ty_fn_sig<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, _ => bug!("unexpected type {:?} to ty_fn_sig", ty) } } + +pub fn ty_fn_sig_vtable<'a, 'tcx>( + cx: &CodegenCx<'a, 'tcx>, + ty: Ty<'tcx>, + is_vtable_shim: bool + ) -> ty::PolyFnSig<'tcx> +{ + let mut fn_sig = ty_fn_sig(cx, ty); + if is_vtable_shim { + // Modify fn(self, ...) to fn(self: *mut Self, ...) + fn_sig = fn_sig.map_bound(|mut fn_sig| { + let mut inputs_and_output = fn_sig.inputs_and_output.to_vec(); + inputs_and_output[0] = cx.tcx.mk_mut_ptr(inputs_and_output[0]); + fn_sig.inputs_and_output = cx.tcx.intern_type_list(&inputs_and_output); + fn_sig + }); + } + fn_sig +}