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

@ -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 {