@@ -314,24 +314,37 @@ fn args_from_ty_and_cursor(
314
314
cursor : & clang:: Cursor ,
315
315
ctx : & mut BindgenContext ,
316
316
) -> Vec < ( Option < String > , TypeId ) > {
317
- match ( cursor. args ( ) , ty. args ( ) ) {
318
- ( Some ( cursor_args) , Some ( ty_args) ) => {
319
- ty_args. iter ( ) . enumerate ( ) . map ( |( i, ty) | {
320
- let name = cursor_args. get ( i)
321
- . map ( |c| c. spelling ( ) )
322
- . and_then ( |name| if name. is_empty ( ) { None } else { Some ( name) } ) ;
323
- ( name, Item :: from_ty_or_ref ( * ty, * cursor, None , ctx) )
324
- } ) . collect ( )
325
- }
326
- ( Some ( cursor_args) , None ) => {
327
- cursor_args. iter ( ) . map ( |cursor| {
328
- let name = cursor. spelling ( ) ;
329
- let name = if name. is_empty ( ) { None } else { Some ( name) } ;
330
- ( name, Item :: from_ty_or_ref ( cursor. cur_type ( ) , * cursor, None , ctx) )
331
- } ) . collect ( )
332
- }
333
- _ => panic ! ( )
334
- }
317
+ let cursor_args = cursor. args ( ) . unwrap ( ) . into_iter ( ) ;
318
+ let type_args = ty. args ( ) . unwrap_or_default ( ) . into_iter ( ) ;
319
+
320
+ // Argument types can be found in either the cursor or the type, but argument names may only be
321
+ // found on the cursor. We often have access to both a type and a cursor for each argument, but
322
+ // in some cases we may only have one.
323
+ //
324
+ // Prefer using the type as the source of truth for the argument's type, but fall back to
325
+ // inspecting the cursor (this happens for Objective C interfaces).
326
+ //
327
+ // Prefer using the cursor for the argument's type, but fall back to using the parent's cursor
328
+ // (this happens for function pointer return types).
329
+ cursor_args
330
+ . map ( Some )
331
+ . chain ( std:: iter:: repeat ( None ) )
332
+ . zip (
333
+ type_args
334
+ . map ( Some )
335
+ . chain ( std:: iter:: repeat ( None ) )
336
+ )
337
+ . take_while ( |( cur, ty) | cur. is_some ( ) || ty. is_some ( ) )
338
+ . map ( |( arg_cur, arg_ty) | {
339
+ let name = arg_cur
340
+ . map ( |a| a. spelling ( ) )
341
+ . and_then ( |name| if name. is_empty ( ) { None } else { Some ( name) } ) ;
342
+
343
+ let cursor = arg_cur. unwrap_or ( * cursor) ;
344
+ let ty = arg_ty. unwrap_or ( cursor. cur_type ( ) ) ;
345
+ ( name, Item :: from_ty_or_ref ( ty, cursor, None , ctx) )
346
+ } )
347
+ . collect ( )
335
348
}
336
349
337
350
impl FunctionSig {
0 commit comments