about summary refs log tree commit diff
path: root/tvix/eval/src/spans.rs
diff options
context:
space:
mode:
Diffstat (limited to 'tvix/eval/src/spans.rs')
-rw-r--r--tvix/eval/src/spans.rs37
1 files changed, 37 insertions, 0 deletions
diff --git a/tvix/eval/src/spans.rs b/tvix/eval/src/spans.rs
index 9998e438b220..d2a8e9badf86 100644
--- a/tvix/eval/src/spans.rs
+++ b/tvix/eval/src/spans.rs
@@ -1,9 +1,46 @@
 //! Utilities for dealing with span tracking in the compiler and in
 //! error reporting.
 
+use crate::opcode::CodeIdx;
+use crate::value::Lambda;
 use codemap::{File, Span};
 use rnix::ast;
 use rowan::ast::AstNode;
+use std::rc::Rc;
+
+/// Helper struct to carry information required for making a span, but
+/// without actually performing the (expensive) span lookup.
+///
+/// This is used for tracking spans across thunk boundaries, as they
+/// are frequently instantiated but spans are only used in error or
+/// warning cases.
+#[derive(Clone, Debug)]
+pub enum LightSpan {
+    /// The span has already been computed and can just be used right
+    /// away.
+    Actual { span: Span },
+
+    /// The span needs to be computed from the provided data, but only
+    /// when it is required.
+    Delayed { lambda: Rc<Lambda>, offset: CodeIdx },
+}
+
+impl LightSpan {
+    pub fn new_delayed(lambda: Rc<Lambda>, offset: CodeIdx) -> Self {
+        Self::Delayed { lambda, offset }
+    }
+
+    pub fn new_actual(span: Span) -> Self {
+        Self::Actual { span }
+    }
+
+    pub fn span(&self) -> Span {
+        match self {
+            LightSpan::Actual { span } => *span,
+            LightSpan::Delayed { lambda, offset } => lambda.chunk.get_span(*offset),
+        }
+    }
+}
 
 /// Trait implemented by all types from which we can retrieve a span.
 pub trait ToSpan {