Skip to content

Commit 05b3cf8

Browse files
refactor(naga): extract Validator::validate_func_call_with_overloads
1 parent e9d7644 commit 05b3cf8

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

Comments
 (0)