Skip to content

Commit 158f2ad

Browse files
refactor(naga): extract Validator::validate_func_call_with_overloads
1 parent fe21cdc commit 158f2ad

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,
@@ -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

Comments
 (0)