about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2022-08-11T12·40+0300
committertazjin <tazjin@tvl.su>2022-08-26T09·02+0000
commit5eb523e882264ab3491ae2c6ce318e00a3fb3dfd (patch)
tree102fa03e9de62a71a6bcc3a1e8f8505801d4e91b
parent20f5ccefeb88ce4b79369085977b674c612e8fed (diff)
fix(tvix/compiler): support identifier literals in select expression r/4493
With this change, attribute set access is working as intended.

Change-Id: Ic5dbbd68aa59156106069289e7375a696909f78b
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6159
Tested-by: BuildkiteCI
Reviewed-by: sterni <sternenseemann@systemli.org>
Reviewed-by: grfn <grfn@gws.fyi>
-rw-r--r--tvix/eval/src/compiler.rs20
1 files changed, 19 insertions, 1 deletions
diff --git a/tvix/eval/src/compiler.rs b/tvix/eval/src/compiler.rs
index 3a6c685c7d..7ab1dce193 100644
--- a/tvix/eval/src/compiler.rs
+++ b/tvix/eval/src/compiler.rs
@@ -94,6 +94,24 @@ impl Compiler {
         }
     }
 
+    /// Compiles nodes the same way that `Self::compile` does, with
+    /// the exception of identifiers which are added literally to the
+    /// stack as string values.
+    ///
+    /// This is needed for correctly accessing attribute sets.
+    fn compile_with_literal_ident(&mut self, node: rnix::SyntaxNode) -> EvalResult<()> {
+        if node.kind() == rnix::SyntaxKind::NODE_IDENT {
+            let ident = rnix::types::Ident::cast(node).unwrap();
+            let idx = self
+                .chunk
+                .add_constant(Value::String(ident.as_str().to_string().into()));
+            self.chunk.add_op(OpCode::OpConstant(idx));
+            return Ok(());
+        }
+
+        self.compile(node)
+    }
+
     fn compile_literal(&mut self, value: rnix::value::Value) -> EvalResult<()> {
         match value {
             rnix::NixValue::Float(f) => {
@@ -292,7 +310,7 @@ impl Compiler {
         //
         // This order matters because the key needs to be evaluated
         // first to fail in the correct order on type errors.
-        self.compile(node.index().unwrap())?;
+        self.compile_with_literal_ident(node.index().unwrap())?;
         self.chunk.add_op(OpCode::OpAttrsSelect);
 
         Ok(())