@@ -126,10 +126,6 @@ pub struct ExprContext {
126126 // address in function pointer literals.
127127 needs_address : bool ,
128128
129- /// Set to false if we should decay VaListImpl to VaList or true if we are
130- /// expect a VaListImpl in this context.
131- expecting_valistimpl : bool ,
132-
133129 ternary_needs_parens : bool ,
134130 expanding_macro : Option < CDeclId > ,
135131}
@@ -193,13 +189,6 @@ impl ExprContext {
193189 }
194190 }
195191
196- pub fn expect_valistimpl ( self ) -> Self {
197- ExprContext {
198- expecting_valistimpl : true ,
199- ..self
200- }
201- }
202-
203192 /// Are we expanding the given macro in the current context?
204193 pub fn expanding_macro ( & self , mac : & CDeclId ) -> bool {
205194 match self . expanding_macro {
@@ -505,7 +494,6 @@ pub fn translate(
505494 decay_ref : DecayRef :: Default ,
506495 is_bitfield_write : false ,
507496 needs_address : false ,
508- expecting_valistimpl : false ,
509497 ternary_needs_parens : false ,
510498 expanding_macro : None ,
511499 } ;
@@ -1272,6 +1260,11 @@ struct ConvertedVariable {
12721260 pub init : TranslationResult < WithStmts < Box < Expr > > > ,
12731261}
12741262
1263+ struct ConvertedFunctionParam {
1264+ pub ty : Box < Type > ,
1265+ pub mutbl : Mutability ,
1266+ }
1267+
12751268impl < ' c > Translation < ' c > {
12761269 pub fn new (
12771270 mut ast_context : TypedAstContext ,
@@ -2345,8 +2338,7 @@ impl<'c> Translation<'c> {
23452338
23462339 // handle regular (non-variadic) arguments
23472340 for & ( decl_id, ref var, typ) in arguments {
2348- let ConvertedVariable { ty, mutbl, init : _ } =
2349- self . convert_variable ( ctx, None , typ) ?;
2341+ let ConvertedFunctionParam { ty, mutbl } = self . convert_function_param ( ctx, typ) ?;
23502342
23512343 let pat = if var. is_empty ( ) {
23522344 mk ( ) . wild_pat ( )
@@ -3063,6 +3055,25 @@ impl<'c> Translation<'c> {
30633055 Ok ( ConvertedVariable { ty, mutbl, init } )
30643056 }
30653057
3058+ fn convert_function_param (
3059+ & self ,
3060+ ctx : ExprContext ,
3061+ typ : CQualTypeId ,
3062+ ) -> TranslationResult < ConvertedFunctionParam > {
3063+ if self . ast_context . is_va_list ( typ. ctype ) {
3064+ let mutbl = if typ. qualifiers . is_const {
3065+ Mutability :: Immutable
3066+ } else {
3067+ Mutability :: Mutable
3068+ } ;
3069+ let ty = mk ( ) . abs_path_ty ( vec ! [ "core" , "ffi" , "VaList" ] ) ;
3070+ return Ok ( ConvertedFunctionParam { mutbl, ty } ) ;
3071+ }
3072+
3073+ self . convert_variable ( ctx, None , typ)
3074+ . map ( |ConvertedVariable { ty, mutbl, .. } | ConvertedFunctionParam { ty, mutbl } )
3075+ }
3076+
30663077 fn convert_type ( & self , type_id : CTypeId ) -> TranslationResult < Box < Type > > {
30673078 self . import_type ( type_id) ;
30683079
@@ -3339,19 +3350,31 @@ impl<'c> Translation<'c> {
33393350 . collect ( )
33403351 }
33413352
3342- /// Variant of `convert_exprs` for when only a prefix of the expression types are known due to
3343- /// the relevant signature being varargs
3353+ /// Variant of `convert_exprs` for the arguments of a function call.
3354+ /// Accounts for differences in translation for arguments, and for varargs where only a prefix
3355+ /// of the expression types are known.
33443356 #[ allow( clippy:: vec_box/*, reason = "not worth a substantial refactor"*/ ) ]
3345- fn convert_exprs_partial (
3357+ fn convert_call_args (
33463358 & self ,
33473359 ctx : ExprContext ,
33483360 exprs : & [ CExprId ] ,
3349- arg_tys : & [ CQualTypeId ] ,
3361+ arg_tys : Option < & [ CQualTypeId ] > ,
3362+ is_variadic : bool ,
33503363 ) -> TranslationResult < WithStmts < Vec < Box < Expr > > > > {
3364+ let arg_tys = if let Some ( arg_tys) = arg_tys {
3365+ if !is_variadic {
3366+ assert ! ( arg_tys. len( ) == exprs. len( ) ) ;
3367+ }
3368+
3369+ arg_tys
3370+ } else {
3371+ & [ ]
3372+ } ;
3373+
33513374 exprs
33523375 . iter ( )
33533376 . enumerate ( )
3354- . map ( |( n, arg) | self . convert_expr ( ctx, * arg, arg_tys. get ( n) . copied ( ) ) )
3377+ . map ( |( n, arg) | self . convert_call_arg ( ctx, * arg, arg_tys. get ( n) . copied ( ) ) )
33553378 . collect ( )
33563379 }
33573380
@@ -3509,12 +3532,6 @@ impl<'c> Translation<'c> {
35093532 val = mk ( ) . cast_expr ( val, ty) ;
35103533 }
35113534
3512- // Most references to the va_list should refer to the VaList
3513- // type, not VaListImpl
3514- if !ctx. expecting_valistimpl && self . ast_context . is_va_list ( qual_ty. ctype ) {
3515- val = mk ( ) . method_call_expr ( val, "as_va_list" , Vec :: new ( ) ) ;
3516- }
3517-
35183535 // If we are referring to a function and need its address, we
35193536 // need to cast it to fn() to ensure that it has a real address.
35203537 let mut set_unsafe = false ;
@@ -4057,19 +4074,8 @@ impl<'c> Translation<'c> {
40574074 // We want to decay refs only when function is variadic
40584075 ctx. decay_ref = DecayRef :: from ( is_variadic) ;
40594076
4060- let args = if is_variadic {
4061- let arg_tys = arg_tys. unwrap_or_default ( ) ;
4062- self . convert_exprs_partial ( ctx. used ( ) , args, arg_tys. as_slice ( ) ) ?
4063- } else {
4064- let arg_tys = if let Some ( ref arg_tys) = arg_tys {
4065- assert ! ( arg_tys. len( ) == args. len( ) ) ;
4066- Some ( arg_tys. as_slice ( ) )
4067- } else {
4068- None
4069- } ;
4070-
4071- self . convert_exprs ( ctx. used ( ) , args, arg_tys) ?
4072- } ;
4077+ let args =
4078+ self . convert_call_args ( ctx. used ( ) , args, arg_tys. as_deref ( ) , is_variadic) ?;
40734079
40744080 let mut call_expr = args. map ( |args| mk ( ) . call_expr ( func, args) ) ;
40754081 if let Some ( expected_ty) = override_ty {
@@ -4146,14 +4152,6 @@ impl<'c> Translation<'c> {
41464152 val = val. map ( |v| mk ( ) . field_expr ( v, field_name) ) ;
41474153 } ;
41484154
4149- // Most references to the va_list should refer to the VaList
4150- // type, not VaListImpl
4151- if !ctx. expecting_valistimpl && self . ast_context . is_va_list ( qual_ty. ctype ) {
4152- val = val. map ( |v| {
4153- mk ( ) . method_call_expr ( v, "as_va_list" , Vec :: < Box < Expr > > :: new ( ) )
4154- } ) ;
4155- }
4156-
41574155 // if the context wants a different type, add a cast
41584156 if let Some ( expected_ty) = override_ty {
41594157 if expected_ty != qual_ty {
@@ -4268,6 +4266,28 @@ impl<'c> Translation<'c> {
42684266 Ok ( expr)
42694267 }
42704268
4269+ /// Wrapper around `convert_expr` for the arguments of a function call.
4270+ pub fn convert_call_arg (
4271+ & self ,
4272+ ctx : ExprContext ,
4273+ expr_id : CExprId ,
4274+ override_ty : Option < CQualTypeId > ,
4275+ ) -> TranslationResult < WithStmts < Box < Expr > > > {
4276+ let mut val;
4277+
4278+ if ( self . ast_context . index ( expr_id) . kind . get_qual_type ( ) )
4279+ . map_or ( false , |qtype| self . ast_context . is_va_list ( qtype. ctype ) )
4280+ {
4281+ // No `override_ty` to avoid unwanted casting.
4282+ val = self . convert_expr ( ctx, expr_id, None ) ?;
4283+ val = val. map ( |val| mk ( ) . method_call_expr ( val, "as_va_list" , Vec :: new ( ) ) ) ;
4284+ } else {
4285+ val = self . convert_expr ( ctx, expr_id, override_ty) ?;
4286+ }
4287+
4288+ Ok ( val)
4289+ }
4290+
42714291 /// Convert the expansion of a const-like macro.
42724292 ///
42734293 /// See [`TranspilerConfig::translate_const_macros`].
0 commit comments