about summary refs log tree commit diff
path: root/tvix/eval/src/value/function.rs
diff options
context:
space:
mode:
authorGriffin Smith <grfn@gws.fyi>2022-10-13T03·53-0400
committertazjin <tazjin@tvl.su>2022-10-17T11·29+0000
commit2a3d49810482b36de9f2d3087e5064545183dbb3 (patch)
tree9cce6ac0209ad046f2549b15041d89b5faa94c48 /tvix/eval/src/value/function.rs
parente63d14419f5cc2ea1f0d9e9221062c2c8d40fe31 (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/value/function.rs')
-rw-r--r--tvix/eval/src/value/function.rs20
1 files changed, 20 insertions, 0 deletions
diff --git a/tvix/eval/src/value/function.rs b/tvix/eval/src/value/function.rs
index e58aab19c0e7..a3aa9325f598 100644
--- a/tvix/eval/src/value/function.rs
+++ b/tvix/eval/src/value/function.rs
@@ -2,9 +2,12 @@
 use std::{
     cell::{Ref, RefCell, RefMut},
     collections::HashMap,
+    hash::Hash,
     rc::Rc,
 };
 
+use codemap::Span;
+
 use crate::{
     chunk::Chunk,
     upvalues::{UpvalueCarrier, Upvalues},
@@ -19,6 +22,23 @@ pub(crate) struct Formals {
 
     /// Do the formals of this function accept extra arguments
     pub(crate) ellipsis: bool,
+
+    /// The span of the formals themselves, to use to emit errors
+    pub(crate) span: Span,
+}
+
+impl Formals {
+    /// Returns true if the given arg is a valid argument to these formals.
+    ///
+    /// This is true if it is either listed in the list of arguments, or the formals have an
+    /// ellipsis
+    pub(crate) fn contains<Q>(&self, arg: &Q) -> bool
+    where
+        Q: ?Sized + Hash + Eq,
+        NixString: std::borrow::Borrow<Q>,
+    {
+        self.ellipsis || self.arguments.contains_key(&arg)
+    }
 }
 
 /// The opcodes for a thunk or closure, plus the number of