feat(tvix/eval): add scaffolding for merging nested attribute sets

This sets up the required logic for finding and merging attribute sets
into nested bindings if they exist. This is absolutely not complete
yet and can, at this commit, probably cause undefined runtime
behaviour if nested attributes are specified.

The basic idea is that a new helper function on the `TrackedBindings`
struct is called with each encountered attribute and determines
whether the new entry can be merged into an existing attribute or not.

Right now the only effect this has in practice is that a new error
becomes available if somebody attempts to cause a merge into an
inherited key.

Change-Id: Id010df3605055eb1ad7fa65241055889dd21bab0
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6798
Tested-by: BuildkiteCI
Reviewed-by: sterni <sternenseemann@systemli.org>
This commit is contained in:
Vincent Ambo 2022-09-28 14:57:53 +03:00 committed by tazjin
parent 09a57e7857
commit 3f34af205f
2 changed files with 116 additions and 25 deletions

View file

@ -4,6 +4,7 @@ use std::{fmt::Display, num::ParseIntError};
use codemap::{CodeMap, Span};
use codemap_diagnostic::{Diagnostic, Emitter, Level, SpanLabel, SpanStyle};
use smol_str::SmolStr;
use crate::Value;
@ -88,6 +89,12 @@ pub enum ErrorKind {
length: i64,
},
// Errors specific to nested attribute sets and merges thereof.
/// Nested attributes can not be merged with an inherited value.
UnmergeableInherit {
name: SmolStr,
},
/// Tvix internal warning for features triggered by users that are
/// not actually implemented yet, and without which eval can not
/// proceed.
@ -242,6 +249,13 @@ to a missing value in the attribute set(s) included via `with`."#,
)
}
ErrorKind::UnmergeableInherit { name } => {
format!(
"cannot merge a nested attribute set into the inherited entry '{}'",
name
)
}
ErrorKind::NotImplemented(feature) => {
format!("feature not yet implemented in Tvix: {}", feature)
}
@ -275,6 +289,7 @@ to a missing value in the attribute set(s) included via `with`."#,
ErrorKind::ParseIntError(_) => "E021",
ErrorKind::NegativeLength { .. } => "E022",
ErrorKind::TailEmptyList { .. } => "E023",
ErrorKind::UnmergeableInherit { .. } => "E024",
ErrorKind::NotImplemented(_) => "E999",
}
}