@@ -183,6 +183,14 @@ impl BindgenAttrs {
183
183
_ => None ,
184
184
} )
185
185
}
186
+
187
+ /// Whether the variadic attributes is present
188
+ fn variadic ( & self ) -> bool {
189
+ self . attrs . iter ( ) . any ( |a| match * a {
190
+ BindgenAttr :: Variadic => true ,
191
+ _ => false ,
192
+ } )
193
+ }
186
194
}
187
195
188
196
impl syn:: synom:: Synom for BindgenAttrs {
@@ -219,6 +227,7 @@ pub enum BindgenAttr {
219
227
JsName ( String ) ,
220
228
JsClass ( String ) ,
221
229
Extends ( Ident ) ,
230
+ Variadic ,
222
231
}
223
232
224
233
impl syn:: synom:: Synom for BindgenAttr {
@@ -304,6 +313,8 @@ impl syn::synom::Synom for BindgenAttr {
304
313
ns: call!( term2ident) >>
305
314
( ns)
306
315
) => { BindgenAttr :: Extends }
316
+ |
317
+ call!( term, "variadic" ) => { |_| BindgenAttr :: Variadic }
307
318
) ) ;
308
319
}
309
320
@@ -365,6 +376,7 @@ impl<'a> ConvertToAst<()> for &'a mut syn::ItemStruct {
365
376
let getter = shared:: struct_field_get ( & ident, & name_str) ;
366
377
let setter = shared:: struct_field_set ( & ident, & name_str) ;
367
378
let opts = BindgenAttrs :: find ( & mut field. attrs ) ?;
379
+ assert_not_variadic ( & opts, & field) ?;
368
380
let comments = extract_doc_comments ( & field. attrs ) ;
369
381
fields. push ( ast:: StructField {
370
382
name : name. clone ( ) ,
@@ -395,6 +407,7 @@ impl<'a> ConvertToAst<(BindgenAttrs, &'a Option<String>)> for syn::ForeignItemFn
395
407
) -> Result < Self :: Target , Diagnostic > {
396
408
let default_name = self . ident . to_string ( ) ;
397
409
let js_name = opts. js_name ( ) . unwrap_or ( & default_name) ;
410
+
398
411
let wasm = function_from_decl (
399
412
js_name,
400
413
self . decl . clone ( ) ,
@@ -404,6 +417,7 @@ impl<'a> ConvertToAst<(BindgenAttrs, &'a Option<String>)> for syn::ForeignItemFn
404
417
None ,
405
418
) ?. 0 ;
406
419
let catch = opts. catch ( ) ;
420
+ let variadic = opts. variadic ( ) ;
407
421
let js_ret = if catch {
408
422
// TODO: this assumes a whole bunch:
409
423
//
@@ -533,6 +547,7 @@ impl<'a> ConvertToAst<(BindgenAttrs, &'a Option<String>)> for syn::ForeignItemFn
533
547
kind,
534
548
js_ret,
535
549
catch,
550
+ variadic,
536
551
structural : opts. structural ( ) ,
537
552
rust_name : self . ident . clone ( ) ,
538
553
shim : Ident :: new ( & shim, Span :: call_site ( ) ) ,
@@ -545,6 +560,7 @@ impl ConvertToAst<BindgenAttrs> for syn::ForeignItemType {
545
560
type Target = ast:: ImportKind ;
546
561
547
562
fn convert ( self , attrs : BindgenAttrs ) -> Result < Self :: Target , Diagnostic > {
563
+ assert_not_variadic ( & attrs, & self ) ?;
548
564
let js_name = attrs
549
565
. js_name ( )
550
566
. map_or_else ( || self . ident . to_string ( ) , |s| s. to_string ( ) ) ;
@@ -570,6 +586,7 @@ impl<'a> ConvertToAst<(BindgenAttrs, &'a Option<String>)> for syn::ForeignItemSt
570
586
if self . mutability . is_some ( ) {
571
587
bail_span ! ( self . mutability, "cannot import mutable globals yet" )
572
588
}
589
+ assert_not_variadic ( & opts, & self ) ?;
573
590
let default_name = self . ident . to_string ( ) ;
574
591
let js_name = opts. js_name ( ) . unwrap_or ( & default_name) ;
575
592
let shim = format ! (
@@ -604,6 +621,7 @@ impl ConvertToAst<BindgenAttrs> for syn::ItemFn {
604
621
if self . unsafety . is_some ( ) {
605
622
bail_span ! ( self . unsafety, "can only #[wasm_bindgen] safe functions" ) ;
606
623
}
624
+ assert_not_variadic ( & attrs, & self ) ?;
607
625
608
626
let default_name = self . ident . to_string ( ) ;
609
627
let name = attrs. js_name ( ) . unwrap_or ( & default_name) ;
@@ -1074,6 +1092,15 @@ fn assert_no_lifetimes(decl: &syn::FnDecl) -> Result<(), Diagnostic> {
1074
1092
Diagnostic :: from_vec ( walk. diagnostics )
1075
1093
}
1076
1094
1095
+ /// This method always fails if the BindgenAttrs contain variadic
1096
+ fn assert_not_variadic ( attrs : & BindgenAttrs , span : & dyn ToTokens ) -> Result < ( ) , Diagnostic > {
1097
+ if attrs. variadic ( ) {
1098
+ bail_span ! ( span, "the `variadic` attribute can only be applied to imported \
1099
+ (`extern`) functions")
1100
+ }
1101
+ Ok ( ( ) )
1102
+ }
1103
+
1077
1104
/// If the path is a single ident, return it.
1078
1105
fn extract_path_ident ( path : & syn:: Path ) -> Result < Ident , Diagnostic > {
1079
1106
if path. leading_colon . is_some ( ) {
0 commit comments