@@ -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