From ac3d717944412b17d7dcd18006c2f9f522b1b3f7 Mon Sep 17 00:00:00 2001 From: Aspen Smith Date: Thu, 4 Jul 2024 23:39:51 -0400 Subject: feat(tvix/eval): Allow passing in an env to evaluation Allow passing in a top-level env, a map from name to value, to evaluation. The intent is to support bound identifiers in the REPL just like upstream nix does. Getting this working involves mucking around a bit with internals - most notably, locals now only optionally have a Span (since locals don't have an easy span we can use) - and getting that working requires propagating some minor hacks to places where we currently *need* a span (and which would require too much changing now to make spans optional; my guess is that that would essentially end up making spans optional throughout the codebase). Also, some extra care has to be taken to close out the scope in the case that we do pass in an env, to avoid breaking our assumptions about the size of the stack when we return from the toplevel Change-Id: Ie475b2d3dfc72ccbf298d2a3ea28c63ac877d653 Reviewed-on: https://cl.tvl.fyi/c/depot/+/11953 Tested-by: BuildkiteCI Autosubmit: aspen Reviewed-by: flokli --- tvix/eval/src/spans.rs | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'tvix/eval/src/spans.rs') diff --git a/tvix/eval/src/spans.rs b/tvix/eval/src/spans.rs index 9998e438b220..df2b9a725562 100644 --- a/tvix/eval/src/spans.rs +++ b/tvix/eval/src/spans.rs @@ -35,6 +35,33 @@ impl ToSpan for rnix::SyntaxNode { } } +/// A placeholder [`ToSpan`] implementation covering the entire source file. +#[derive(Debug, Clone, Copy)] +pub struct EntireFile; + +impl ToSpan for EntireFile { + fn span_for(&self, file: &File) -> Span { + file.span + } +} + +/// A placeholder [`ToSpan`] implementation which falls back to the entire file if its wrapped value +/// is [`None`] +#[derive(Debug, Clone, Copy)] +pub struct OrEntireFile(pub Option); + +impl ToSpan for OrEntireFile +where + T: ToSpan, +{ + fn span_for(&self, file: &File) -> Span { + match &self.0 { + Some(t) => t.span_for(file), + None => EntireFile.span_for(file), + } + } +} + /// Generates a `ToSpan` implementation for a type implementing /// `rowan::AstNode`. This is impossible to do as a blanket /// implementation because `rustc` forbids these implementations for -- cgit 1.4.1