Skip to content

Commit

Permalink
Fix translation of unboxing shim for rust-call ABI methods
Browse files Browse the repository at this point in the history
When translating the unboxing shim, account for the fact that the shim
translation has already performed the necessary unboxing of input
types and values when forwarding to the shimmed function.  This
prevents ICEing or generating incorrect code.

Closes #16739
  • Loading branch information
bkoropoff committed Oct 17, 2014
1 parent 1600e0b commit 4a4a434
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 6 deletions.
28 changes: 26 additions & 2 deletions src/librustc/middle/trans/callee.rs
Expand Up @@ -281,8 +281,32 @@ pub fn trans_unboxing_shim(bcx: Block,
};
let boxed_function_type =
ty::mk_bare_fn(tcx, boxed_function_type).subst(tcx, &substs);
let function_type =
ty::mk_bare_fn(tcx, (*fty).clone()).subst(tcx, &substs);
let function_type = match fty.abi {
synabi::RustCall => {
// We're passing through to a RustCall ABI function, but
// because the shim will already perform untupling, we
// need to pretend the shimmed function does not use
// RustCall so the untupled arguments can be passed
// through verbatim. This is kind of ugly.
let fake_ty = ty::FnSig {
binder_id: fty.sig.binder_id,
inputs: type_of::untuple_arguments_if_necessary(ccx,
fty.sig.inputs.as_slice(),
fty.abi),
output: fty.sig.output,
variadic: false,
};
let fake_ty = ty::BareFnTy {
fn_style: fty.fn_style,
abi: synabi::Rust,
sig: fake_ty,
};
ty::mk_bare_fn(tcx, fake_ty).subst(tcx, &substs)
}
_ => {
ty::mk_bare_fn(tcx, (*fty).clone()).subst(tcx, &substs)
}
};

let function_name = ty::with_path(tcx, method_id, |path| {
link::mangle_internal_name_by_path_and_seq(path, "unboxing_shim")
Expand Down
8 changes: 4 additions & 4 deletions src/librustc/middle/trans/type_of.rs
Expand Up @@ -44,10 +44,10 @@ pub fn type_of_explicit_arg(ccx: &CrateContext, arg_ty: ty::t) -> Type {
/// Yields the types of the "real" arguments for this function. For most
/// functions, these are simply the types of the arguments. For functions with
/// the `RustCall` ABI, however, this untuples the arguments of the function.
fn untuple_arguments_if_necessary(ccx: &CrateContext,
inputs: &[ty::t],
abi: abi::Abi)
-> Vec<ty::t> {
pub fn untuple_arguments_if_necessary(ccx: &CrateContext,
inputs: &[ty::t],
abi: abi::Abi)
-> Vec<ty::t> {
if abi != abi::RustCall {
return inputs.iter().map(|x| (*x).clone()).collect()
}
Expand Down

0 comments on commit 4a4a434

Please sign in to comment.