Skip to content

Commit 196ff98

Browse files
refactor(naga): extract Validator::validate_func_call_with_overloads
1 parent f3ad5a3 commit 196ff98

1 file changed

Lines changed: 64 additions & 37 deletions

File tree

naga/src/valid/expression.rs

Lines changed: 64 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use crate::arena::UniqueArena;
55
use 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

Comments
 (0)