Skip to content

Commit b79a788

Browse files
committed
Rollup merge of #22935 - dotdash:method_attr, r=eddyb
... objects For method calls through trait objects, we currently generate the llvm function argument attributes using the non-opaque method signature that still has the trait object fat pointer for the self pointer. This leads to attributes that are plain wrong, e.g. noalias. As we don't know anything about the concrete type of the underlying object, we must replace the self argument with an opaque i8 pointer before applying the attributes.
2 parents 7398071 + 8b6b3c1 commit b79a788

File tree

2 files changed

+35
-6
lines changed

2 files changed

+35
-6
lines changed

src/librustc_trans/trans/callee.rs

+12-1
Original file line numberDiff line numberDiff line change
@@ -603,7 +603,18 @@ pub fn trans_method_call<'a, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
603603
let _icx = push_ctxt("trans_method_call");
604604
debug!("trans_method_call(call_expr={})", call_expr.repr(bcx.tcx()));
605605
let method_call = MethodCall::expr(call_expr.id);
606-
let method_ty = (*bcx.tcx().method_map.borrow())[method_call].ty;
606+
let method_ty = match bcx.tcx().method_map.borrow().get(&method_call) {
607+
Some(method) => match method.origin {
608+
ty::MethodTraitObject(_) => match method.ty.sty {
609+
ty::ty_bare_fn(_, ref fty) => {
610+
ty::mk_bare_fn(bcx.tcx(), None, meth::opaque_method_ty(bcx.tcx(), fty))
611+
}
612+
_ => method.ty
613+
},
614+
_ => method.ty
615+
},
616+
None => panic!("method not found in trans_method_call")
617+
};
607618
trans_call_inner(
608619
bcx,
609620
call_expr.debug_loc(),

src/librustc_trans/trans/meth.rs

+23-5
Original file line numberDiff line numberDiff line change
@@ -589,15 +589,16 @@ pub fn trans_object_shim<'a, 'tcx>(
589589
};
590590
let fty = monomorphize::apply_param_substs(tcx, &object_substs, &method_ty.fty);
591591
let fty = tcx.mk_bare_fn(fty);
592-
debug!("trans_object_shim: fty={}", fty.repr(tcx));
592+
let method_ty = opaque_method_ty(tcx, fty);
593+
debug!("trans_object_shim: fty={} method_ty={}", fty.repr(tcx), method_ty.repr(tcx));
593594

594595
//
595-
let method_bare_fn_ty =
596-
ty::mk_bare_fn(tcx, None, fty);
596+
let shim_fn_ty = ty::mk_bare_fn(tcx, None, fty);
597+
let method_bare_fn_ty = ty::mk_bare_fn(tcx, None, method_ty);
597598
let function_name =
598-
link::mangle_internal_name_by_type_and_seq(ccx, method_bare_fn_ty, "object_shim");
599+
link::mangle_internal_name_by_type_and_seq(ccx, shim_fn_ty, "object_shim");
599600
let llfn =
600-
decl_internal_rust_fn(ccx, method_bare_fn_ty, &function_name);
601+
decl_internal_rust_fn(ccx, shim_fn_ty, &function_name);
601602

602603
let sig = ty::erase_late_bound_regions(ccx.tcx(), &fty.sig);
603604

@@ -866,3 +867,20 @@ pub fn trans_trait_cast<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
866867

867868
bcx
868869
}
870+
871+
/// Replace the self type (&Self or Box<Self>) with an opaque pointer.
872+
pub fn opaque_method_ty<'tcx>(tcx: &ty::ctxt<'tcx>, method_ty: &ty::BareFnTy<'tcx>)
873+
-> &'tcx ty::BareFnTy<'tcx> {
874+
let mut inputs = method_ty.sig.0.inputs.clone();
875+
inputs[0] = ty::mk_mut_ptr(tcx, ty::mk_mach_int(tcx, ast::TyI8));
876+
877+
tcx.mk_bare_fn(ty::BareFnTy {
878+
unsafety: method_ty.unsafety,
879+
abi: method_ty.abi,
880+
sig: ty::Binder(ty::FnSig {
881+
inputs: inputs,
882+
output: method_ty.sig.0.output,
883+
variadic: method_ty.sig.0.variadic,
884+
}),
885+
})
886+
}

0 commit comments

Comments
 (0)