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:
parent
e63d14419f
commit
2a3d498104
7 changed files with 133 additions and 13 deletions
|
|
@ -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 {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue