@@ -2496,13 +2496,19 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
24962496 } else {
24972497 match function. name {
24982498 "select" => {
2499- let mut args = ctx . prepare_args ( arguments , 3 , span ) ;
2500-
2501- let reject = self . expression ( args. next ( ) ? , ctx ) ? ;
2502- let accept = self . expression ( args . next ( ) ?, ctx ) ? ;
2503- let condition = self . expression ( args . next ( ) ? , ctx ) ?;
2499+ const NUM_ARGS : usize = 3 ;
2500+ let mut args_iter = ctx . prepare_args ( arguments , NUM_ARGS as u32 , span ) ;
2501+ let args: [ _ ; NUM_ARGS ] =
2502+ [ args_iter . next ( ) ? , args_iter . next ( ) ?, args_iter . next ( ) ? ] ;
2503+ args_iter . finish ( ) ?;
25042504
2505- args. finish ( ) ?;
2505+ let [ reject, accept, condition] = self . function_helper_array (
2506+ span,
2507+ proc:: select:: WgslSymbol ,
2508+ |_args, _ctx| proc:: select:: overloads ( ) ,
2509+ args,
2510+ ctx,
2511+ ) ?;
25062512
25072513 ir:: Expression :: Select {
25082514 reject,
@@ -2999,6 +3005,39 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
29993005 Ok ( lowered_arguments)
30003006 }
30013007
3008+ /// A convenience around [`Self::function_helper`] that marshals to and from fixed-size arrays.
3009+ ///
3010+ /// Useful for resolving function calls with a fixed number of arguments at parse time, like
3011+ /// [`ir::Expression::Select`].
3012+ fn function_helper_array < const NUM_ARGS : usize , F , O , R > (
3013+ & mut self ,
3014+ span : Span ,
3015+ fun : F ,
3016+ resolve_overloads : R ,
3017+ ast_arguments : [ Handle < ast:: Expression < ' source > > ; NUM_ARGS ] ,
3018+ ctx : & mut ExpressionContext < ' source , ' _ , ' _ > ,
3019+ ) -> Result < ' source , [ Handle < ir:: Expression > ; NUM_ARGS ] >
3020+ where
3021+ F : TryToWgsl + core:: fmt:: Debug + Copy ,
3022+ O : proc:: OverloadSet ,
3023+ R : FnOnce (
3024+ & [ Handle < ir:: Expression > ; NUM_ARGS ] ,
3025+ & mut ExpressionContext < ' source , ' _ , ' _ > ,
3026+ ) -> O ,
3027+ {
3028+ self . function_helper (
3029+ span,
3030+ fun,
3031+ |args, ctx| {
3032+ let args = args. try_into ( ) . unwrap ( ) ;
3033+ resolve_overloads ( args, ctx)
3034+ } ,
3035+ ast_arguments. into ( ) ,
3036+ ctx,
3037+ )
3038+ . map ( |arr| arr. into_inner ( ) . unwrap ( ) )
3039+ }
3040+
30023041 /// Choose the right overload for a function call.
30033042 ///
30043043 /// Return a [`Rule`] representing the most preferred overload in
0 commit comments