@@ -2240,26 +2240,44 @@ pub fn get_fn_llvm_attributes(ccx: &CrateContext, fn_ty: ty::t)
2240
2240
ty : : ty_bare_fn( ref f) => ( f. sig. clone( ) , f. abi, false ) ,
2241
2241
ty : : ty_unboxed_closure( closure_did, _) => {
2242
2242
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
+
2246
2246
( function_type. sig. clone( ) , RustCall , true )
2247
2247
}
2248
- _ => fail ! ( "expected closure or function." )
2248
+ _ => ccx . sess ( ) . bug ( "expected closure or function." )
2249
2249
} ;
2250
2250
2251
+
2251
2252
// Since index 0 is the return value of the llvm func, we start
2252
2253
// at either 1 or 2 depending on whether there's an env slot or not
2253
2254
let mut first_arg_offset = if has_env { 2 } else { 1 } ;
2254
2255
let mut attrs = llvm:: AttrBuilder :: new( ) ;
2255
2256
let ret_ty = fn_sig. output;
2256
2257
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
+ } ;
2263
2281
2264
2282
// A function pointer is called without the declaration
2265
2283
// 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)
2315
2333
}
2316
2334
}
2317
2335
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) ) {
2319
2337
match ty:: get( t) . sty {
2320
2338
// this needs to be first to prevent fat pointers from falling through
2321
2339
_ if !type_is_immediate( ccx, t) => {
0 commit comments