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