about summary refs log tree commit diff
path: root/tvix/eval/src/compiler/scope.rs
diff options
context:
space:
mode:
Diffstat (limited to 'tvix/eval/src/compiler/scope.rs')
-rw-r--r--tvix/eval/src/compiler/scope.rs31
1 files changed, 26 insertions, 5 deletions
diff --git a/tvix/eval/src/compiler/scope.rs b/tvix/eval/src/compiler/scope.rs
index 892727c107c9..7b0a66004a7f 100644
--- a/tvix/eval/src/compiler/scope.rs
+++ b/tvix/eval/src/compiler/scope.rs
@@ -38,7 +38,7 @@ pub struct Local {
     name: LocalName,
 
     /// Source span at which this local was declared.
-    pub span: codemap::Span,
+    pub span: Option<codemap::Span>,
 
     /// Scope depth of this local.
     pub depth: usize,
@@ -73,6 +73,10 @@ impl Local {
             LocalName::Phantom => false,
         }
     }
+
+    pub fn is_used(&self) -> bool {
+        self.depth == 0 || self.used || self.is_ignored()
+    }
 }
 
 /// Represents the current position of an identifier as resolved in a scope.
@@ -240,7 +244,7 @@ impl Scope {
         let idx = self.locals.len();
         self.locals.push(Local {
             initialised,
-            span,
+            span: Some(span),
             name: LocalName::Phantom,
             depth: self.scope_depth,
             needs_finaliser: false,
@@ -263,7 +267,7 @@ impl Scope {
         let idx = LocalIdx(self.locals.len());
         self.locals.push(Local {
             name: LocalName::Ident(name.clone()),
-            span,
+            span: Some(span),
             depth: self.scope_depth,
             initialised: false,
             needs_finaliser: false,
@@ -286,6 +290,23 @@ impl Scope {
         (idx, shadowed)
     }
 
+    pub fn declare_constant(&mut self, name: String) -> LocalIdx {
+        let idx = LocalIdx(self.locals.len());
+        self.locals.push(Local {
+            name: LocalName::Ident(name.clone()),
+            span: None,
+            depth: 0,
+            initialised: true,
+            used: false,
+            needs_finaliser: false,
+            must_thunk: false,
+        });
+        // We don't need to worry about shadowing for constants; they're defined at the toplevel
+        // always
+        self.by_name.insert(name, ByName::Single(idx));
+        idx
+    }
+
     /// Mark local as initialised after compiling its expression.
     pub fn mark_initialised(&mut self, idx: LocalIdx) {
         self.locals[idx.0].initialised = true;
@@ -348,8 +369,8 @@ impl Scope {
                 // lifetime, and emit a warning otherwise (unless the
                 // user explicitly chose to ignore it by prefixing the
                 // identifier with `_`)
-                if !local.used && !local.is_ignored() {
-                    unused_spans.push(local.span);
+                if local.is_used() {
+                    unused_spans.extend(local.span);
                 }
 
                 // remove the by-name index if this was a named local