@@ -40,6 +40,20 @@ fn pointer_flags(ty: &ast::Type) -> (bool, bool) {
4040 flags
4141}
4242
43+ fn is_va_args_type ( ty : & ast:: Type ) -> bool {
44+ if let ast:: Type :: RefType ( r) = ty
45+ && let Some ( ast:: Type :: SliceType ( slice) ) = r. ty ( )
46+ {
47+ return matches ! ( slice. ty( ) , Some ( ast:: Type :: PathType ( path) )
48+ if path
49+ . path( )
50+ . and_then( |p| p. segment( ) )
51+ . and_then( |s| s. name_ref( ) )
52+ . is_some_and( |name| name. text( ) == "VaArg" ) ) ;
53+ }
54+ false
55+ }
56+
4357fn cfg_matches_host ( fn_item : & ast:: Fn ) -> bool {
4458 for attr in fn_item. attrs ( ) {
4559 let Some ( meta) = attr. meta ( ) else { continue } ;
@@ -205,6 +219,13 @@ impl<'a> FragmentCtx<'a> {
205219 }
206220 if token. kind ( ) == SyntaxKind :: IDENT {
207221 if let Some ( param) = self . params . iter ( ) . find ( |p| p. name == token. text ( ) ) {
222+ if param. is_va_args {
223+ self . flush_text ( ) ;
224+ self . fragments . push ( BodyFragment :: VaArgs {
225+ va_args : std:: marker:: PhantomData ,
226+ } ) ;
227+ return ;
228+ }
208229 let mut access = self . builder . classify_access ( token) ;
209230 if param. is_mut_ref && self . text_buf . ends_with ( '*' ) {
210231 self . text_buf . pop ( ) ;
@@ -272,6 +293,7 @@ struct ParamInfo {
272293 is_refcount_pointer : bool ,
273294 is_unsafe_pointer : bool ,
274295 is_mut_ref : bool ,
296+ is_va_args : bool ,
275297}
276298
277299struct FnIrBuilder < ' a > {
@@ -297,15 +319,22 @@ impl<'a> FnIrBuilder<'a> {
297319 } ;
298320
299321 let ( is_refcount_pointer, is_unsafe_pointer) = pointer_flags ( & ty) ;
322+ let name = ident
323+ . name ( )
324+ . map ( |n| n. text ( ) . to_string ( ) )
325+ . unwrap_or_default ( ) ;
326+ let is_va_args = is_va_args_type ( & ty) ;
327+ assert ! (
328+ !is_va_args || name == "va" ,
329+ "variadic argument parameter must be named `va`, found `{name}`"
330+ ) ;
300331 params. push ( ParamInfo {
301- name : ident
302- . name ( )
303- . map ( |n| n. text ( ) . to_string ( ) )
304- . unwrap_or_default ( ) ,
332+ name,
305333 ty : ty. syntax ( ) . text ( ) . to_string ( ) ,
306334 is_refcount_pointer,
307335 is_unsafe_pointer,
308336 is_mut_ref : matches ! ( & ty, ast:: Type :: RefType ( r) if r. mut_token( ) . is_some( ) ) ,
337+ is_va_args,
309338 } ) ;
310339 }
311340 params
@@ -482,6 +511,7 @@ impl<'a> FnIrBuilder<'a> {
482511
483512 let params_map: BTreeMap < String , TypeInfo > = params
484513 . iter ( )
514+ . filter ( |p| !p. is_va_args )
485515 . map ( |p| {
486516 (
487517 p. name . clone ( ) ,
0 commit comments