refactor(tvix/eval): clean up representation flip in bindings
When encountering a nested binding for the first time, cleanly flip the representation to `Binding::Set` in `Binding::merge` before proceeding with the actual merge. This reduces the number of points where we have to deal with the (soon to be slightly more complex) construction of the nested binding representation. Change-Id: Ifd43aac7b59ebd15a72c3ec512386a5bcf26ec13 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6802 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
This commit is contained in:
parent
18fcf0d79d
commit
ccf9dd651b
1 changed files with 28 additions and 33 deletions
|
@ -77,44 +77,39 @@ impl Binding {
|
|||
c.emit_error(span, ErrorKind::UnmergeableInherit { name: name.clone() })
|
||||
}
|
||||
|
||||
Binding::Plain { expr: existing } => match existing {
|
||||
// If the value is not yet a nested binding, flip the representation
|
||||
// and recurse.
|
||||
Binding::Plain { expr } => match expr {
|
||||
ast::Expr::AttrSet(existing) => {
|
||||
if let ast::Expr::AttrSet(new) = value {
|
||||
let merged = AttributeSet {
|
||||
nesting_level: 0, // TODO
|
||||
let nested = AttributeSet {
|
||||
nesting_level: 0, // TODO
|
||||
span: c.span_for(existing),
|
||||
|
||||
span: c.span_for(existing),
|
||||
// Kind of the attrs depends on the first time it is
|
||||
// encountered. We actually believe this to be a Nix
|
||||
// bug: https://github.com/NixOS/nix/issues/7111
|
||||
kind: if existing.rec_token().is_some() {
|
||||
BindingsKind::RecAttrs
|
||||
} else {
|
||||
BindingsKind::Attrs
|
||||
},
|
||||
|
||||
// Kind of the attrs depends on the first time it is
|
||||
// encountered. We actually believe this to be a Nix
|
||||
// bug: https://github.com/NixOS/nix/issues/7111
|
||||
kind: if existing.rec_token().is_some() {
|
||||
BindingsKind::RecAttrs
|
||||
} else {
|
||||
BindingsKind::Attrs
|
||||
},
|
||||
inherits: ast::HasEntry::inherits(existing).collect(),
|
||||
|
||||
inherits: ast::HasEntry::inherits(existing)
|
||||
.chain(ast::HasEntry::inherits(&new))
|
||||
.collect(),
|
||||
entries: ast::HasEntry::attrpath_values(existing)
|
||||
.map(|entry| {
|
||||
let span = c.span_for(&entry);
|
||||
(
|
||||
span,
|
||||
entry.attrpath().unwrap().attrs(),
|
||||
entry.value().unwrap(),
|
||||
)
|
||||
})
|
||||
.collect(),
|
||||
};
|
||||
|
||||
entries: ast::HasEntry::attrpath_values(existing)
|
||||
.chain(ast::HasEntry::attrpath_values(&new))
|
||||
.map(|entry| {
|
||||
let span = c.span_for(&entry);
|
||||
(
|
||||
span,
|
||||
entry.attrpath().unwrap().attrs(),
|
||||
entry.value().unwrap(),
|
||||
)
|
||||
})
|
||||
.collect(),
|
||||
};
|
||||
|
||||
*self = Binding::Set(merged);
|
||||
} else {
|
||||
todo!()
|
||||
}
|
||||
*self = Binding::Set(nested);
|
||||
self.merge(c, value);
|
||||
}
|
||||
|
||||
_ => c.emit_error(&value, ErrorKind::UnmergeableValue),
|
||||
|
|
Loading…
Reference in a new issue