@@ -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 ,
@@ -1027,43 +1082,15 @@ impl super::Validator {
10271082 _ => unreachable ! ( ) ,
10281083 } ;
10291084
1030- // Start with the set of all overloads available for `fun`.
1031- let mut overloads = fun. overloads ( ) ;
1032- log:: debug!(
1033- "initial overloads for {:?}: {:#?}" ,
1085+ self . validate_func_call_with_overloads (
1086+ module,
10341087 fun,
1035- overloads. for_debug( & module. types)
1036- ) ;
1037-
1038- // If any argument is not a constant expression, then no
1039- // overloads that accept abstract values should be considered.
1040- // `OverloadSet::concrete_only` is supposed to help impose this
1041- // restriction. However, no `MathFunction` accepts a mix of
1042- // abstract and concrete arguments, so we don't need to worry
1043- // about that here.
1044-
1045- for ( i, ( & expr, & ty) ) in actuals. iter ( ) . zip ( actual_types) . enumerate ( ) {
1046- // Remove overloads that cannot accept an `i`'th
1047- // argument arguments of type `ty`.
1048- overloads = overloads. arg ( i, ty, & module. types ) ;
1049- log:: debug!(
1050- "overloads after arg {i}: {:#?}" ,
1051- overloads. for_debug( & module. types)
1052- ) ;
1053-
1054- if overloads. is_empty ( ) {
1055- log:: debug!( "all overloads eliminated" ) ;
1056- return Err ( ExpressionError :: InvalidArgumentType (
1057- format ! ( "{fun:?}" ) ,
1058- i as u32 ,
1059- expr,
1060- ) ) ;
1061- }
1062- }
1063-
1064- if actuals. len ( ) < overloads. min_arguments ( ) {
1065- return Err ( ExpressionError :: WrongArgumentCount ( format ! ( "{fun:?}" ) ) ) ;
1066- }
1088+ fun. overloads ( ) ,
1089+ actuals
1090+ . iter ( )
1091+ . zip ( actual_types. iter ( ) )
1092+ . map ( |( & val, & ty) | ( val, ty) ) ,
1093+ ) ?;
10671094
10681095 ShaderStages :: all ( )
10691096 }
0 commit comments