Skip to content

Commit 36789fb

Browse files
committed
auto merge of #16656 : luqmana/rust/ucmla, r=pcwalton
Gets rid of a FIXME in `base::get_fn_llvm_attributes`. r? @pcwalton
2 parents c9cf3b3 + 171c542 commit 36789fb

File tree

1 file changed

+29
-11
lines changed

1 file changed

+29
-11
lines changed

src/librustc/middle/trans/base.rs

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2240,26 +2240,44 @@ pub fn get_fn_llvm_attributes(ccx: &CrateContext, fn_ty: ty::t)
22402240
ty::ty_bare_fn(ref f) => (f.sig.clone(), f.abi, false),
22412241
ty::ty_unboxed_closure(closure_did, _) => {
22422242
let unboxed_closures = ccx.tcx.unboxed_closures.borrow();
2243-
let function_type = unboxed_closures.get(&closure_did)
2244-
.closure_type
2245-
.clone();
2243+
let ref function_type = unboxed_closures.get(&closure_did)
2244+
.closure_type;
2245+
22462246
(function_type.sig.clone(), RustCall, true)
22472247
}
2248-
_ => fail!("expected closure or function.")
2248+
_ => ccx.sess().bug("expected closure or function.")
22492249
};
22502250

2251+
22512252
// Since index 0 is the return value of the llvm func, we start
22522253
// at either 1 or 2 depending on whether there's an env slot or not
22532254
let mut first_arg_offset = if has_env { 2 } else { 1 };
22542255
let mut attrs = llvm::AttrBuilder::new();
22552256
let ret_ty = fn_sig.output;
22562257

2257-
// These have an odd calling convention, so we skip them for now.
2258-
//
2259-
// FIXME(pcwalton): We don't have to skip them; just untuple the result.
2260-
if abi == RustCall {
2261-
return attrs;
2262-
}
2258+
// These have an odd calling convention, so we need to manually
2259+
// unpack the input ty's
2260+
let input_tys = match ty::get(fn_ty).sty {
2261+
ty::ty_unboxed_closure(_, _) => {
2262+
assert!(abi == RustCall);
2263+
2264+
match ty::get(fn_sig.inputs[0]).sty {
2265+
ty::ty_nil => Vec::new(),
2266+
ty::ty_tup(ref inputs) => inputs.clone(),
2267+
_ => ccx.sess().bug("expected tuple'd inputs")
2268+
}
2269+
},
2270+
ty::ty_bare_fn(_) if abi == RustCall => {
2271+
let inputs = vec![fn_sig.inputs[0]];
2272+
2273+
match ty::get(fn_sig.inputs[1]).sty {
2274+
ty::ty_nil => inputs,
2275+
ty::ty_tup(ref t_in) => inputs.append(t_in.as_slice()),
2276+
_ => ccx.sess().bug("expected tuple'd inputs")
2277+
}
2278+
}
2279+
_ => fn_sig.inputs.clone()
2280+
};
22632281

22642282
// A function pointer is called without the declaration
22652283
// available, so we have to apply any attributes with ABI
@@ -2315,7 +2333,7 @@ pub fn get_fn_llvm_attributes(ccx: &CrateContext, fn_ty: ty::t)
23152333
}
23162334
}
23172335

2318-
for (idx, &t) in fn_sig.inputs.iter().enumerate().map(|(i, v)| (i + first_arg_offset, v)) {
2336+
for (idx, &t) in input_tys.iter().enumerate().map(|(i, v)| (i + first_arg_offset, v)) {
23192337
match ty::get(t).sty {
23202338
// this needs to be first to prevent fat pointers from falling through
23212339
_ if !type_is_immediate(ccx, t) => {

0 commit comments

Comments
 (0)