Emit proper function argument attributes for closure environments

This commit is contained in:
Björn Steinbrink 2015-02-28 21:38:49 +01:00
parent 8a69110c3b
commit 549be5f867

View File

@ -2430,21 +2430,19 @@ pub fn get_fn_llvm_attributes<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_ty: Ty<
use middle::ty::{BrAnon, ReLateBound};
let function_type;
let (fn_sig, abi, has_env) = match fn_ty.sty {
ty::ty_bare_fn(_, ref f) => (&f.sig, f.abi, false),
let (fn_sig, abi, env_ty) = match fn_ty.sty {
ty::ty_bare_fn(_, ref f) => (&f.sig, f.abi, None),
ty::ty_closure(closure_did, _, substs) => {
let typer = common::NormalizingClosureTyper::new(ccx.tcx());
function_type = typer.closure_type(closure_did, substs);
(&function_type.sig, RustCall, true)
let self_type = self_type_for_closure(ccx, closure_did, fn_ty);
(&function_type.sig, RustCall, Some(self_type))
}
_ => ccx.sess().bug("expected closure or function.")
};
let fn_sig = ty::erase_late_bound_regions(ccx.tcx(), fn_sig);
// Since index 0 is the return value of the llvm func, we start
// at either 1 or 2 depending on whether there's an env slot or not
let mut first_arg_offset = if has_env { 2 } else { 1 };
let mut attrs = llvm::AttrBuilder::new();
let ret_ty = fn_sig.output;
@ -2455,7 +2453,11 @@ pub fn get_fn_llvm_attributes<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_ty: Ty<
assert!(abi == RustCall);
match fn_sig.inputs[0].sty {
ty::ty_tup(ref inputs) => inputs.clone(),
ty::ty_tup(ref inputs) => {
let mut full_inputs = vec![env_ty.expect("Missing closure environment")];
full_inputs.push_all(inputs);
full_inputs
}
_ => ccx.sess().bug("expected tuple'd inputs")
}
},
@ -2473,6 +2475,8 @@ pub fn get_fn_llvm_attributes<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_ty: Ty<
_ => fn_sig.inputs.clone()
};
// Index 0 is the return value of the llvm func, so we start at 1
let mut first_arg_offset = 1;
if let ty::FnConverging(ret_ty) = ret_ty {
// A function pointer is called without the declaration
// available, so we have to apply any attributes with ABI