diff options
author | Vincent Ambo <tazjin@tvl.su> | 2024-02-20T08·29+0700 |
---|---|---|
committer | tazjin <tazjin@tvl.su> | 2024-02-20T09·18+0000 |
commit | 3c87687798a3cfb6c3cfcc231e6c60511e3341ab (patch) | |
tree | 90dd1bb7daefbd09cd308240858689c6a405701f /tvix/eval/src/compiler/mod.rs | |
parent | b38badf2063b4eba31abffbeba01c1c8c3212be8 (diff) |
refactor(tvix/eval): add SourceCode directly into error types r/7571
With this change it's no longer necessary to track the SourceCode struct separately from the evaluation for error reporting: It's just stored directly in the errors. This also ends up resolving an issue in compiler::bindings, where we cloned the Arc containing file references way too often. In fact those clones probably compensate for all additional SourceCode clones during error construction now. Change-Id: Ice93bf161e61f8ea3d48103435e20c53e6aa8c3a Reviewed-on: https://cl.tvl.fyi/c/depot/+/10986 Reviewed-by: flokli <flokli@flokli.de> Tested-by: BuildkiteCI
Diffstat (limited to 'tvix/eval/src/compiler/mod.rs')
-rw-r--r-- | tvix/eval/src/compiler/mod.rs | 44 |
1 files changed, 26 insertions, 18 deletions
diff --git a/tvix/eval/src/compiler/mod.rs b/tvix/eval/src/compiler/mod.rs index d64202c2ad74..0f9accc13e77 100644 --- a/tvix/eval/src/compiler/mod.rs +++ b/tvix/eval/src/compiler/mod.rs @@ -24,7 +24,6 @@ use smol_str::SmolStr; use std::collections::{BTreeMap, HashMap}; use std::path::{Path, PathBuf}; use std::rc::{Rc, Weak}; -use std::sync::Arc; use crate::chunk::Chunk; use crate::errors::{CatchableErrorKind, Error, ErrorKind, EvalResult}; @@ -151,7 +150,7 @@ const GLOBAL_BUILTINS: &[&str] = &[ "__curPos", ]; -pub struct Compiler<'observer> { +pub struct Compiler<'source, 'observer> { contexts: Vec<LambdaCtx>, warnings: Vec<EvalWarning>, errors: Vec<Error>, @@ -165,10 +164,13 @@ pub struct Compiler<'observer> { /// and a function that should emit code for the token. globals: Rc<GlobalsMap>, - /// File reference in the codemap contains all known source code - /// and is used to track the spans from which instructions where - /// derived. - file: Arc<codemap::File>, + /// Reference to the struct holding all of the source code, which + /// is used for error creation. + source: &'source SourceCode, + + /// File reference in the source map for the current file, which + /// is used for creating spans. + file: &'source codemap::File, /// Carry an observer for the compilation process, which is called /// whenever a chunk is emitted. @@ -180,18 +182,19 @@ pub struct Compiler<'observer> { dead_scope: usize, } -impl Compiler<'_> { +impl Compiler<'_, '_> { pub(super) fn span_for<S: ToSpan>(&self, to_span: &S) -> Span { - to_span.span_for(&self.file) + to_span.span_for(self.file) } } /// Compiler construction -impl<'observer> Compiler<'observer> { +impl<'source, 'observer> Compiler<'source, 'observer> { pub(crate) fn new( location: Option<PathBuf>, - file: Arc<codemap::File>, globals: Rc<GlobalsMap>, + source: &'source SourceCode, + file: &'source codemap::File, observer: &'observer mut dyn CompilerObserver, ) -> EvalResult<Self> { let mut root_dir = match location { @@ -204,6 +207,7 @@ impl<'observer> Compiler<'observer> { e )), file.span, + source.clone(), ) })?; if let Some(dir) = location { @@ -226,6 +230,7 @@ impl<'observer> Compiler<'observer> { Ok(Self { root_dir, + source, file, observer, globals, @@ -239,7 +244,7 @@ impl<'observer> Compiler<'observer> { // Helper functions for emitting code and metadata to the internal // structures of the compiler. -impl Compiler<'_> { +impl Compiler<'_, '_> { fn context(&self) -> &LambdaCtx { &self.contexts[self.contexts.len() - 1] } @@ -285,7 +290,7 @@ impl Compiler<'_> { } // Actual code-emitting AST traversal methods. -impl Compiler<'_> { +impl Compiler<'_, '_> { fn compile(&mut self, slot: LocalIdx, expr: ast::Expr) { let expr = optimiser::optimise_expr(self, slot, expr); @@ -1473,7 +1478,8 @@ impl Compiler<'_> { fn emit_error<N: ToSpan>(&mut self, node: &N, kind: ErrorKind) { let span = self.span_for(node); - self.errors.push(Error::new(kind, span)) + self.errors + .push(Error::new(kind, span, self.source.clone())) } } @@ -1519,7 +1525,7 @@ fn expr_static_attr_str(node: &ast::Attr) -> Option<SmolStr> { fn compile_src_builtin( name: &'static str, code: &str, - source: &SourceCode, + source: SourceCode, weak: &Weak<GlobalsMap>, ) -> Value { use std::fmt::Write; @@ -1542,8 +1548,9 @@ fn compile_src_builtin( let result = compile( &parsed.tree().expr().unwrap(), None, - file.clone(), weak.upgrade().unwrap(), + &source, + &file, &mut crate::observer::NoOpObserver {}, ) .map_err(|e| ErrorKind::NativeError { @@ -1621,7 +1628,7 @@ pub fn prepare_globals( // If "source builtins" were supplied, compile them and insert // them. builtins.extend(src_builtins.into_iter().map(move |(name, code)| { - let compiled = compile_src_builtin(name, code, &source, weak); + let compiled = compile_src_builtin(name, code, source.clone(), weak); (name, compiled) })); @@ -1647,11 +1654,12 @@ pub fn prepare_globals( pub fn compile( expr: &ast::Expr, location: Option<PathBuf>, - file: Arc<codemap::File>, globals: Rc<GlobalsMap>, + source: &SourceCode, + file: &codemap::File, observer: &mut dyn CompilerObserver, ) -> EvalResult<CompilationOutput> { - let mut c = Compiler::new(location, file, globals.clone(), observer)?; + let mut c = Compiler::new(location, globals.clone(), source, file, observer)?; let root_span = c.span_for(expr); let root_slot = c.scope_mut().declare_phantom(root_span, false); |