rukalang/elab/
validate_calls.rs1use super::prelude::*;
2
3struct ValidateRuntimeCallArgsPass<'a> {
15 elaborator: &'a mut Elaborator,
16 params: &'a [(OwnershipMode, Ty)],
17 locals: &'a mut Vec<(String, Ty)>,
18 callee_name: &'a str,
19}
20
21impl<'a> Pass for ValidateRuntimeCallArgsPass<'a> {
22 type In = Vec<CallArg>;
23 type Out = Vec<CallArg>;
24 type Error = ElabError;
25
26 const NAME: &'static str = "elab.validate_runtime_call_args";
27
28 fn run(
29 &mut self,
30 mut input: Self::In,
31 _cx: &mut PassContext,
32 ) -> Result<Self::Out, Self::Error> {
33 self.elaborator
34 .normalize_runtime_calls_and_spreads(&mut input, self.locals)?;
35
36 if input.len() != self.params.len() {
37 return Err(ElabError::ArityMismatch {
38 function: self.callee_name.to_owned(),
39 expected: self.params.len(),
40 actual: input.len(),
41 });
42 }
43
44 for (arg, (_, param_ty)) in input.iter_mut().zip(self.params.iter()) {
45 let CallArg::Expr(expr) = arg else {
46 return Err(ElabError::UnsupportedTypeExpr);
47 };
48 let _ = self
49 .elaborator
50 .elaborate_expr(expr, Some(param_ty), self.locals)?;
51 }
52
53 Ok(input)
54 }
55}
56
57impl Elaborator {
58 pub(super) fn validate_runtime_call_args(
60 &mut self,
61 args: &mut Vec<CallArg>,
62 params: &[(OwnershipMode, Ty)],
63 locals: &mut Vec<(String, Ty)>,
64 callee_name: &str,
65 ) -> Result<(), ElabError> {
66 let mut pass = ValidateRuntimeCallArgsPass {
67 elaborator: self,
68 params,
69 locals,
70 callee_name,
71 };
72 let (output, timings) = Elaborator::run_subpass(&mut pass, std::mem::take(args))?;
73 *args = output;
74 self.record_subpass_timings(&timings);
75 Ok(())
76 }
77}