about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2022-08-14T14·33+0300
committertazjin <tazjin@tvl.su>2022-08-30T17·13+0000
commite07556493f51caa8b4644c4de375c12012b8ad18 (patch)
tree78ff46b0a712847ac1fbd4dcff083bd94a185273
parent3a67f912284e22f50bb54a6f6a533b2caf8929f8 (diff)
feat(tvix/eval): Implement inherit from outer scope in attrs r/4545
Change-Id: I97fa45059b7f2cbe96eb60bd1821e3e25832df66
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6212
Reviewed-by: grfn <grfn@gws.fyi>
Tested-by: BuildkiteCI
-rw-r--r--tvix/eval/src/compiler.rs26
-rw-r--r--tvix/eval/src/tests/tvix_tests/eval-okay-attrs-simple-inherit.exp1
-rw-r--r--tvix/eval/src/tests/tvix_tests/eval-okay-attrs-simple-inherit.nix4
3 files changed, 31 insertions, 0 deletions
diff --git a/tvix/eval/src/compiler.rs b/tvix/eval/src/compiler.rs
index 4b7a7b44a522..94d91159f851 100644
--- a/tvix/eval/src/compiler.rs
+++ b/tvix/eval/src/compiler.rs
@@ -358,6 +358,32 @@ impl Compiler {
 
         let mut count = 0;
 
+        // Inherits have to be evaluated before entering the scope of
+        // a potentially recursive attribute sets (i.e. we always
+        // inherit "from the outside").
+        for inherit in node.inherits() {
+            match inherit.from() {
+                Some(_from) => todo!("inherit from attrs not implemented"),
+                None => {
+                    for ident in inherit.idents() {
+                        count += 1;
+
+                        // Leave the identifier on the stack (never
+                        // nested in case of inherits!)
+                        let idx = self
+                            .chunk
+                            .push_constant(Value::String(ident.as_str().into()));
+                        self.chunk.push_op(OpCode::OpConstant(idx));
+
+                        match self.resolve_local(ident.as_str()) {
+                            Some(idx) => self.chunk.push_op(OpCode::OpGetLocal(idx)),
+                            None => return Err(Error::UnknownStaticVariable(ident)),
+                        };
+                    }
+                }
+            }
+        }
+
         for kv in node.entries() {
             count += 1;
 
diff --git a/tvix/eval/src/tests/tvix_tests/eval-okay-attrs-simple-inherit.exp b/tvix/eval/src/tests/tvix_tests/eval-okay-attrs-simple-inherit.exp
new file mode 100644
index 000000000000..a779fce51abc
--- /dev/null
+++ b/tvix/eval/src/tests/tvix_tests/eval-okay-attrs-simple-inherit.exp
@@ -0,0 +1 @@
+{ a = 1; }
diff --git a/tvix/eval/src/tests/tvix_tests/eval-okay-attrs-simple-inherit.nix b/tvix/eval/src/tests/tvix_tests/eval-okay-attrs-simple-inherit.nix
new file mode 100644
index 000000000000..68880bcfd857
--- /dev/null
+++ b/tvix/eval/src/tests/tvix_tests/eval-okay-attrs-simple-inherit.nix
@@ -0,0 +1,4 @@
+let
+  a = 1;
+in
+{ inherit a; }