diff options
author | Griffin Smith <grfn@gws.fyi> | 2022-10-13T03·53-0400 |
---|---|---|
committer | tazjin <tazjin@tvl.su> | 2022-10-17T11·29+0000 |
commit | 2a3d49810482b36de9f2d3087e5064545183dbb3 (patch) | |
tree | 9cce6ac0209ad046f2549b15041d89b5faa94c48 /tvix/eval/src/vm.rs | |
parent | e63d14419f5cc2ea1f0d9e9221062c2c8d40fe31 (diff) |
feat(tvix/eval): Validate closed formals r/5154
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
Diffstat (limited to 'tvix/eval/src/vm.rs')
-rw-r--r-- | tvix/eval/src/vm.rs | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/tvix/eval/src/vm.rs b/tvix/eval/src/vm.rs index 7fcdb9ea739b..65662ed555d3 100644 --- a/tvix/eval/src/vm.rs +++ b/tvix/eval/src/vm.rs @@ -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)); |