refactor(tvix/eval): declare all locals before compiling them

This actually makes things full-circle, as this tree already had this
implementation once before all the other required components were in
place.

With this commit, the compiler can resolve recursive upvalues within
the same scope (though they will not yet work at runtime).

Change-Id: I6267e477d08f367257c3a6dde054b880d7b47211
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6326
Tested-by: BuildkiteCI
Reviewed-by: sterni <sternenseemann@systemli.org>
This commit is contained in:
Vincent Ambo 2022-08-28 15:41:57 +03:00 committed by tazjin
parent 47b3562867
commit 900a92935d

View file

@ -654,6 +654,9 @@ impl Compiler {
self.compile_let_inherit(node.inherits());
// First pass to ensure that all identifiers are known;
// required for resolving recursion.
let mut entries: Vec<(String, rnix::ast::Expr)> = vec![];
for entry in node.attrpath_values() {
let mut path = match normalise_ident_path(entry.attrpath().unwrap().attrs()) {
Ok(p) => p,
@ -669,7 +672,15 @@ impl Compiler {
let name = path.pop().unwrap();
self.declare_local(entry.attrpath().unwrap().syntax().clone(), &name);
self.compile(entry.value().unwrap());
entries.push((name, entry.value().unwrap()));
}
// Second pass to place the values in the correct stack slots.
for (name, value) in entries.into_iter() {
self.compile(value);
// Any code after this point will observe the value in the
// right stack slot, so mark it as initialised.
self.mark_initialised(&name);
}