feat(tvix/eval): Validate closed formals

Validate "closed formals" (formal parameters without an ellipsis) via a
new ValidateClosedFormals op, which checks the arguments (in an attr set
at the top of the stack) against the formal parameters on the Lambda in
the current frame, and returns a new UnexpectedArgument error (including
the span of the formals themselves!!) if any arguments aren't allowed

Change-Id: Idcc47a59167a83be1832a6229f137d84e426c56c
Reviewed-on: https://cl.tvl.fyi/c/depot/+/7002
Reviewed-by: tazjin <tazjin@tvl.su>
Tested-by: BuildkiteCI
This commit is contained in:
Griffin Smith 2022-10-12 23:53:03 -04:00 committed by tazjin
parent e63d14419f
commit 2a3d498104
7 changed files with 133 additions and 13 deletions

View file

@ -500,6 +500,21 @@ impl<'o> VM<'o> {
self.push(Value::Bool(result));
}
OpCode::OpValidateClosedFormals => {
let formals = self.frame().lambda.formals.as_ref().expect(
"OpValidateClosedFormals called within the frame of a lambda without formals",
);
let args = self.peek(0).to_attrs().map_err(|err| self.error(err))?;
for arg in args.keys() {
if !formals.contains(arg) {
return Err(self.error(ErrorKind::UnexpectedArgument {
arg: arg.clone(),
formals_span: formals.span,
}));
}
}
}
OpCode::OpList(Count(count)) => {
let list =
NixList::construct(count, self.stack.split_off(self.stack.len() - count));