@@ -5,7 +5,7 @@ use crate::arena::UniqueArena;
55use crate :: {
66 arena:: Handle ,
77 proc,
8- proc:: OverloadSet as _ ,
8+ proc:: OverloadSet ,
99 proc:: { IndexableLengthError , ResolveError } ,
1010} ;
1111
@@ -237,6 +237,61 @@ impl super::Validator {
237237 Ok ( ( ) )
238238 }
239239
240+ pub ( super ) fn validate_func_call_with_overloads < ' a , F , O , A > (
241+ & self ,
242+ module : & crate :: Module ,
243+ fun : F ,
244+ overloads : O ,
245+ actuals : A ,
246+ ) -> Result < ( ) , ExpressionError >
247+ where
248+ F : core:: fmt:: Debug + Copy ,
249+ O : OverloadSet ,
250+ A : Iterator < Item = ( Handle < crate :: Expression > , & ' a crate :: TypeInner ) > + ExactSizeIterator ,
251+ {
252+ // Start with the set of all overloads available for `fun`.
253+ let mut overloads = overloads;
254+ log:: debug!(
255+ "initial overloads for {:?}: {:#?}" ,
256+ fun,
257+ overloads. for_debug( & module. types)
258+ ) ;
259+
260+ // If any argument is not a constant expression, then no
261+ // overloads that accept abstract values should be considered.
262+ // `OverloadSet::concrete_only` is supposed to help impose this
263+ // restriction. However, no `MathFunction` accepts a mix of
264+ // abstract and concrete arguments, so we don't need to worry
265+ // about that here.
266+
267+ let actuals_len = actuals. len ( ) ;
268+
269+ for ( i, ( expr, ty) ) in actuals. into_iter ( ) . enumerate ( ) {
270+ // Remove overloads that cannot accept an `i`'th
271+ // argument arguments of type `ty`.
272+ overloads = overloads. arg ( i, ty, & module. types ) ;
273+ log:: debug!(
274+ "overloads after arg {i}: {:#?}" ,
275+ overloads. for_debug( & module. types)
276+ ) ;
277+
278+ if overloads. is_empty ( ) {
279+ log:: debug!( "all overloads eliminated" ) ;
280+ return Err ( ExpressionError :: InvalidArgumentType (
281+ format ! ( "{fun:?}" ) ,
282+ i as u32 ,
283+ expr,
284+ ) ) ;
285+ }
286+ }
287+
288+ if actuals_len < overloads. min_arguments ( ) {
289+ return Err ( ExpressionError :: WrongArgumentCount ( format ! ( "{fun:?}" ) ) ) ;
290+ }
291+
292+ Ok ( ( ) )
293+ }
294+
240295 #[ allow( clippy:: too_many_arguments) ]
241296 pub ( super ) fn validate_expression (
242297 & self ,
@@ -1039,43 +1094,15 @@ impl super::Validator {
10391094 _ => unreachable ! ( ) ,
10401095 } ;
10411096
1042- // Start with the set of all overloads available for `fun`.
1043- let mut overloads = fun. overloads ( ) ;
1044- log:: debug!(
1045- "initial overloads for {:?}: {:#?}" ,
1097+ self . validate_func_call_with_overloads (
1098+ module,
10461099 fun,
1047- overloads. for_debug( & module. types)
1048- ) ;
1049-
1050- // If any argument is not a constant expression, then no
1051- // overloads that accept abstract values should be considered.
1052- // `OverloadSet::concrete_only` is supposed to help impose this
1053- // restriction. However, no `MathFunction` accepts a mix of
1054- // abstract and concrete arguments, so we don't need to worry
1055- // about that here.
1056-
1057- for ( i, ( & expr, & ty) ) in actuals. iter ( ) . zip ( actual_types) . enumerate ( ) {
1058- // Remove overloads that cannot accept an `i`'th
1059- // argument arguments of type `ty`.
1060- overloads = overloads. arg ( i, ty, & module. types ) ;
1061- log:: debug!(
1062- "overloads after arg {i}: {:#?}" ,
1063- overloads. for_debug( & module. types)
1064- ) ;
1065-
1066- if overloads. is_empty ( ) {
1067- log:: debug!( "all overloads eliminated" ) ;
1068- return Err ( ExpressionError :: InvalidArgumentType (
1069- format ! ( "{fun:?}" ) ,
1070- i as u32 ,
1071- expr,
1072- ) ) ;
1073- }
1074- }
1075-
1076- if actuals. len ( ) < overloads. min_arguments ( ) {
1077- return Err ( ExpressionError :: WrongArgumentCount ( format ! ( "{fun:?}" ) ) ) ;
1078- }
1100+ fun. overloads ( ) ,
1101+ actuals
1102+ . iter ( )
1103+ . zip ( actual_types. iter ( ) )
1104+ . map ( |( & val, & ty) | ( val, ty) ) ,
1105+ ) ?;
10791106
10801107 ShaderStages :: all ( )
10811108 }
0 commit comments