about summary refs log tree commit diff
path: root/tvix/eval/src/errors.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/errors.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/errors.rs')
-rw-r--r--tvix/eval/src/errors.rs33
1 files changed, 32 insertions, 1 deletions
diff --git a/tvix/eval/src/errors.rs b/tvix/eval/src/errors.rs
index 33b12daa5d..a3fe387609 100644
--- a/tvix/eval/src/errors.rs
+++ b/tvix/eval/src/errors.rs
@@ -1,5 +1,5 @@
 use crate::spans::ToSpan;
-use crate::value::CoercionKind;
+use crate::value::{CoercionKind, NixString};
 use std::io;
 use std::path::PathBuf;
 use std::rc::Rc;
@@ -132,6 +132,12 @@ pub enum ErrorKind {
     /// Errors converting JSON to a value
     FromJsonError(String),
 
+    /// An unexpected argument was supplied to a function that takes formal parameters
+    UnexpectedArgument {
+        arg: NixString,
+        formals_span: Span,
+    },
+
     /// Tvix internal warning for features triggered by users that are
     /// not actually implemented yet, and without which eval can not
     /// proceed.
@@ -357,6 +363,14 @@ to a missing value in the attribute set(s) included via `with`."#,
                 write!(f, "Error converting JSON to a Nix value: {msg}")
             }
 
+            ErrorKind::UnexpectedArgument { arg, .. } => {
+                write!(
+                    f,
+                    "Unexpected argument `{}` supplied to function",
+                    arg.as_str()
+                )
+            }
+
             ErrorKind::NotImplemented(feature) => {
                 write!(f, "feature not yet implemented in Tvix: {}", feature)
             }
@@ -606,6 +620,7 @@ impl Error {
             ErrorKind::DuplicateAttrsKey { .. } => "in this attribute set",
             ErrorKind::InvalidAttributeName(_) => "in this attribute set",
             ErrorKind::PathResolution(_) => "in this path literal",
+            ErrorKind::UnexpectedArgument { .. } => "in this function call",
 
             // The spans for some errors don't have any more descriptive stuff
             // in them, or we don't utilise it yet.
@@ -675,6 +690,7 @@ impl Error {
             ErrorKind::ImportCompilerError { .. } => "E028",
             ErrorKind::IO { .. } => "E029",
             ErrorKind::FromJsonError { .. } => "E030",
+            ErrorKind::UnexpectedArgument { .. } => "E031",
 
             // Placeholder error while Tvix is under construction.
             ErrorKind::NotImplemented(_) => "E999",
@@ -720,6 +736,21 @@ impl Error {
                 labels
             }
 
+            ErrorKind::UnexpectedArgument { formals_span, .. } => {
+                vec![
+                    SpanLabel {
+                        label: self.span_label(),
+                        span: self.span,
+                        style: SpanStyle::Primary,
+                    },
+                    SpanLabel {
+                        label: Some("the accepted arguments".into()),
+                        span: *formals_span,
+                        style: SpanStyle::Secondary,
+                    },
+                ]
+            }
+
             // All other errors pretty much have the same shape.
             _ => {
                 vec![SpanLabel {