diff --git a/crates/typst-ide/src/analyze.rs b/crates/typst-ide/src/analyze.rs index 2d48039b6..f3e417d5c 100644 --- a/crates/typst-ide/src/analyze.rs +++ b/crates/typst-ide/src/analyze.rs @@ -1,6 +1,5 @@ use comemo::Track; use ecow::{eco_vec, EcoString, EcoVec}; -use typst::diag::DelayedErrors; use typst::eval::{Route, Tracer, Vm}; use typst::foundations::{Label, Scopes, Value}; use typst::introspection::{Introspector, Locator}; @@ -55,13 +54,11 @@ pub fn analyze_import(world: &dyn World, source: &LinkedNode) -> Option { let mut locator = Locator::default(); let introspector = Introspector::default(); - let mut delayed = DelayedErrors::new(); let mut tracer = Tracer::new(); let vt = Vt { world: world.track(), introspector: introspector.track(), locator: &mut locator, - delayed: delayed.track_mut(), tracer: tracer.track_mut(), }; diff --git a/crates/typst/src/diag.rs b/crates/typst/src/diag.rs index c0106b6af..4634f41ed 100644 --- a/crates/typst/src/diag.rs +++ b/crates/typst/src/diag.rs @@ -165,25 +165,6 @@ impl From for SourceDiagnostic { } } -/// Holds delayed errors. -#[derive(Default, Clone)] -pub struct DelayedErrors(pub EcoVec); - -impl DelayedErrors { - /// Create an empty list of delayed errors. - pub fn new() -> Self { - Self::default() - } -} - -#[comemo::track] -impl DelayedErrors { - /// Push a delayed error. - pub fn push(&mut self, error: SourceDiagnostic) { - self.0.push(error); - } -} - /// A part of a diagnostic's [trace](SourceDiagnostic::trace). #[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] pub enum Tracepoint { diff --git a/crates/typst/src/eval/call.rs b/crates/typst/src/eval/call.rs index f87ac7713..7ccebe858 100644 --- a/crates/typst/src/eval/call.rs +++ b/crates/typst/src/eval/call.rs @@ -1,9 +1,7 @@ use comemo::{Prehashed, Tracked, TrackedMut}; use ecow::EcoVec; -use crate::diag::{ - bail, error, At, DelayedErrors, HintedStrResult, SourceResult, Trace, Tracepoint, -}; +use crate::diag::{bail, error, At, HintedStrResult, SourceResult, Trace, Tracepoint}; use crate::eval::{Access, Eval, FlowEvent, Route, Tracer, Vm}; use crate::foundations::{ call_method_mut, is_mutating_method, Arg, Args, Bytes, Closure, Content, Func, @@ -251,7 +249,6 @@ pub(crate) fn call_closure( route: Tracked, introspector: Tracked, locator: Tracked, - delayed: TrackedMut, tracer: TrackedMut, depth: usize, mut args: Args, @@ -265,13 +262,7 @@ pub(crate) fn call_closure( // Prepare VT. let mut locator = Locator::chained(locator); - let vt = Vt { - world, - introspector, - locator: &mut locator, - delayed, - tracer, - }; + let vt = Vt { world, introspector, locator: &mut locator, tracer }; // Prepare VM. let mut vm = Vm::new(vt, route, closure.file, scopes); diff --git a/crates/typst/src/eval/mod.rs b/crates/typst/src/eval/mod.rs index f1bd691b0..eaba69e0c 100644 --- a/crates/typst/src/eval/mod.rs +++ b/crates/typst/src/eval/mod.rs @@ -25,7 +25,7 @@ pub(crate) use self::flow::*; use comemo::{Track, Tracked, TrackedMut}; -use crate::diag::{bail, DelayedErrors, SourceResult}; +use crate::diag::{bail, SourceResult}; use crate::foundations::{Cast, Module, NativeElement, Scope, Scopes, Value}; use crate::introspection::{Introspector, Locator}; use crate::layout::Vt; @@ -51,12 +51,10 @@ pub fn eval( // Prepare VT. let mut locator = Locator::new(); let introspector = Introspector::default(); - let mut delayed = DelayedErrors::new(); let vt = Vt { world, introspector: introspector.track(), locator: &mut locator, - delayed: delayed.track_mut(), tracer, }; @@ -118,13 +116,11 @@ pub fn eval_string( // Prepare VT. let mut tracer = Tracer::new(); let mut locator = Locator::new(); - let mut delayed = DelayedErrors::new(); let introspector = Introspector::default(); let vt = Vt { world, introspector: introspector.track(), locator: &mut locator, - delayed: delayed.track_mut(), tracer: tracer.track_mut(), }; diff --git a/crates/typst/src/eval/tracer.rs b/crates/typst/src/eval/tracer.rs index af53a945f..53494895e 100644 --- a/crates/typst/src/eval/tracer.rs +++ b/crates/typst/src/eval/tracer.rs @@ -11,9 +11,10 @@ use crate::util::hash128; #[derive(Default, Clone)] pub struct Tracer { inspected: Option, - values: EcoVec, warnings: EcoVec, warnings_set: HashSet, + delayed: EcoVec, + values: EcoVec, } impl Tracer { @@ -25,25 +26,44 @@ impl Tracer { Self::default() } - /// Mark a span as inspected. All values observed for this span can be - /// retrieved via `values` later. - pub fn inspect(&mut self, span: Span) { - self.inspected = Some(span); - } - - /// Get the values for the inspeted span. - pub fn values(self) -> EcoVec { - self.values + /// Get the stored delayed errors. + pub fn delayed(&mut self) -> EcoVec { + std::mem::take(&mut self.delayed) } /// Get the stored warnings. pub fn warnings(self) -> EcoVec { self.warnings } + + /// Mark a span as inspected. All values observed for this span can be + /// retrieved via `values` later. + pub fn inspect(&mut self, span: Span) { + self.inspected = Some(span); + } + + /// Get the values for the inspected span. + pub fn values(self) -> EcoVec { + self.values + } } #[comemo::track] impl Tracer { + /// Push delayed errors. + pub fn delay(&mut self, errors: EcoVec) { + self.delayed.extend(errors); + } + + /// Add a warning. + pub fn warn(&mut self, warning: SourceDiagnostic) { + // Check if warning is a duplicate. + let hash = hash128(&(&warning.span, &warning.message)); + if self.warnings_set.insert(hash) { + self.warnings.push(warning); + } + } + /// The inspected span if it is part of the given source file. pub fn inspected(&self, id: FileId) -> Option { if self.inspected.and_then(Span::id) == Some(id) { @@ -59,13 +79,4 @@ impl Tracer { self.values.push(v); } } - - /// Add a warning. - pub fn warn(&mut self, warning: SourceDiagnostic) { - // Check if warning is a duplicate. - let hash = hash128(&(&warning.span, &warning.message)); - if self.warnings_set.insert(hash) { - self.warnings.push(warning); - } - } } diff --git a/crates/typst/src/foundations/func.rs b/crates/typst/src/foundations/func.rs index 7d6b94ba6..f1da6e37f 100644 --- a/crates/typst/src/foundations/func.rs +++ b/crates/typst/src/foundations/func.rs @@ -281,7 +281,6 @@ impl Func { route, vm.vt.introspector, vm.vt.locator.track(), - TrackedMut::reborrow_mut(&mut vm.vt.delayed), TrackedMut::reborrow_mut(&mut vm.vt.tracer), vm.depth + 1, args, @@ -308,7 +307,6 @@ impl Func { world: vt.world, introspector: vt.introspector, locator: &mut locator, - delayed: TrackedMut::reborrow_mut(&mut vt.delayed), tracer: TrackedMut::reborrow_mut(&mut vt.tracer), }; let mut vm = Vm::new(vt, route.track(), None, scopes); diff --git a/crates/typst/src/introspection/counter.rs b/crates/typst/src/introspection/counter.rs index 0af655630..16403320a 100644 --- a/crates/typst/src/introspection/counter.rs +++ b/crates/typst/src/introspection/counter.rs @@ -5,7 +5,7 @@ use comemo::{Tracked, TrackedMut}; use ecow::{eco_format, eco_vec, EcoString, EcoVec}; use smallvec::{smallvec, SmallVec}; -use crate::diag::{At, DelayedErrors, SourceResult, StrResult}; +use crate::diag::{At, SourceResult, StrResult}; use crate::eval::Tracer; use crate::foundations::{ cast, elem, func, scope, select_where, ty, Array, Content, Element, Func, IntoValue, @@ -253,7 +253,6 @@ impl Counter { vt.world, vt.introspector, vt.locator.track(), - TrackedMut::reborrow_mut(&mut vt.delayed), TrackedMut::reborrow_mut(&mut vt.tracer), ) } @@ -265,17 +264,10 @@ impl Counter { world: Tracked, introspector: Tracked, locator: Tracked, - delayed: TrackedMut, tracer: TrackedMut, ) -> SourceResult> { let mut locator = Locator::chained(locator); - let mut vt = Vt { - world, - introspector, - locator: &mut locator, - delayed, - tracer, - }; + let mut vt = Vt { world, introspector, locator: &mut locator, tracer }; let mut state = CounterState::init(&self.0); let mut page = NonZeroUsize::ONE; diff --git a/crates/typst/src/introspection/state.rs b/crates/typst/src/introspection/state.rs index 4b559b3e2..af6d7933f 100644 --- a/crates/typst/src/introspection/state.rs +++ b/crates/typst/src/introspection/state.rs @@ -1,7 +1,7 @@ use comemo::{Tracked, TrackedMut}; use ecow::{eco_format, eco_vec, EcoString, EcoVec}; -use crate::diag::{DelayedErrors, SourceResult}; +use crate::diag::SourceResult; use crate::eval::Tracer; use crate::foundations::{ cast, elem, func, scope, select_where, ty, Content, Func, NativeElement, Repr, @@ -209,7 +209,6 @@ impl State { vt.world, vt.introspector, vt.locator.track(), - TrackedMut::reborrow_mut(&mut vt.delayed), TrackedMut::reborrow_mut(&mut vt.tracer), ) } @@ -221,17 +220,10 @@ impl State { world: Tracked, introspector: Tracked, locator: Tracked, - delayed: TrackedMut, tracer: TrackedMut, ) -> SourceResult> { let mut locator = Locator::chained(locator); - let mut vt = Vt { - world, - introspector, - locator: &mut locator, - delayed, - tracer, - }; + let mut vt = Vt { world, introspector, locator: &mut locator, tracer }; let mut state = self.init.clone(); let mut stops = eco_vec![state.clone()]; diff --git a/crates/typst/src/layout/inline/mod.rs b/crates/typst/src/layout/inline/mod.rs index 35d332d68..44b2e113b 100644 --- a/crates/typst/src/layout/inline/mod.rs +++ b/crates/typst/src/layout/inline/mod.rs @@ -10,7 +10,7 @@ use self::shaping::{ is_gb_style, is_of_cjk_script, shape, ShapedGlyph, ShapedText, BEGIN_PUNCT_PAT, END_PUNCT_PAT, }; -use crate::diag::{bail, DelayedErrors, SourceResult}; +use crate::diag::{bail, SourceResult}; use crate::eval::Tracer; use crate::foundations::{Content, Resolve, Smart, StyleChain}; use crate::introspection::{Introspector, Locator, MetaElem}; @@ -43,7 +43,6 @@ pub(crate) fn layout_inline( world: Tracked, introspector: Tracked, locator: Tracked, - delayed: TrackedMut, tracer: TrackedMut, styles: StyleChain, consecutive: bool, @@ -51,13 +50,7 @@ pub(crate) fn layout_inline( expand: bool, ) -> SourceResult { let mut locator = Locator::chained(locator); - let mut vt = Vt { - world, - introspector, - locator: &mut locator, - delayed, - tracer, - }; + let mut vt = Vt { world, introspector, locator: &mut locator, tracer }; // Collect all text into one string for BiDi analysis. let (text, segments, spans) = collect(children, &styles, consecutive)?; @@ -79,7 +72,6 @@ pub(crate) fn layout_inline( vt.world, vt.introspector, vt.locator.track(), - TrackedMut::reborrow_mut(&mut vt.delayed), TrackedMut::reborrow_mut(&mut vt.tracer), styles, consecutive, diff --git a/crates/typst/src/layout/mod.rs b/crates/typst/src/layout/mod.rs index 1627b8e74..f291cfe95 100644 --- a/crates/typst/src/layout/mod.rs +++ b/crates/typst/src/layout/mod.rs @@ -73,7 +73,6 @@ pub(crate) use self::inline::*; use comemo::{Tracked, TrackedMut}; -use crate::diag::DelayedErrors; use crate::diag::SourceResult; use crate::eval::Tracer; use crate::foundations::{category, Category, Content, Scope, StyleChain}; @@ -153,7 +152,6 @@ pub trait Layout { introspector: vt.introspector, locator: &mut locator, tracer: TrackedMut::reborrow_mut(&mut vt.tracer), - delayed: TrackedMut::reborrow_mut(&mut vt.delayed), }; self.layout(&mut vt, styles, regions) } @@ -168,18 +166,11 @@ impl LayoutRoot for Content { world: Tracked, introspector: Tracked, locator: Tracked, - delayed: TrackedMut, tracer: TrackedMut, styles: StyleChain, ) -> SourceResult { let mut locator = Locator::chained(locator); - let mut vt = Vt { - world, - introspector, - locator: &mut locator, - delayed, - tracer, - }; + let mut vt = Vt { world, introspector, locator: &mut locator, tracer }; let scratch = Scratch::default(); let (realized, styles) = realize_root(&mut vt, &scratch, content, styles)?; realized @@ -194,7 +185,6 @@ impl LayoutRoot for Content { vt.world, vt.introspector, vt.locator.track(), - TrackedMut::reborrow_mut(&mut vt.delayed), TrackedMut::reborrow_mut(&mut vt.tracer), styles, ) @@ -216,19 +206,12 @@ impl Layout for Content { world: Tracked, introspector: Tracked, locator: Tracked, - delayed: TrackedMut, tracer: TrackedMut, styles: StyleChain, regions: Regions, ) -> SourceResult { let mut locator = Locator::chained(locator); - let mut vt = Vt { - world, - introspector, - locator: &mut locator, - delayed, - tracer, - }; + let mut vt = Vt { world, introspector, locator: &mut locator, tracer }; let scratch = Scratch::default(); let (realized, styles) = realize_block(&mut vt, &scratch, content, styles)?; realized @@ -244,7 +227,6 @@ impl Layout for Content { vt.world, vt.introspector, vt.locator.track(), - TrackedMut::reborrow_mut(&mut vt.delayed), TrackedMut::reborrow_mut(&mut vt.tracer), styles, regions, diff --git a/crates/typst/src/layout/vt.rs b/crates/typst/src/layout/vt.rs index 7b316a285..78b8c5116 100644 --- a/crates/typst/src/layout/vt.rs +++ b/crates/typst/src/layout/vt.rs @@ -1,6 +1,6 @@ use comemo::{Tracked, TrackedMut}; -use crate::diag::{DelayedErrors, SourceResult}; +use crate::diag::SourceResult; use crate::eval::Tracer; use crate::introspection::{Introspector, Locator}; use crate::World; @@ -15,8 +15,6 @@ pub struct Vt<'a> { pub introspector: Tracked<'a, Introspector>, /// Provides stable identities to elements. pub locator: &'a mut Locator<'a>, - /// Delayed errors that do not immediately terminate execution. - pub delayed: TrackedMut<'a, DelayedErrors>, /// The tracer for inspection of the values an expression produces. pub tracer: TrackedMut<'a, Tracer>, } @@ -33,9 +31,7 @@ impl Vt<'_> { match f(self) { Ok(value) => value, Err(errors) => { - for error in errors { - self.delayed.push(error); - } + self.tracer.delay(errors); T::default() } } diff --git a/crates/typst/src/lib.rs b/crates/typst/src/lib.rs index 92f824928..8d0001c80 100644 --- a/crates/typst/src/lib.rs +++ b/crates/typst/src/lib.rs @@ -61,7 +61,7 @@ use std::ops::Range; use comemo::{Prehashed, Track, Tracked, Validate}; use ecow::{EcoString, EcoVec}; -use crate::diag::{warning, DelayedErrors, FileResult, SourceDiagnostic, SourceResult}; +use crate::diag::{warning, FileResult, SourceDiagnostic, SourceResult}; use crate::eval::{Route, Tracer}; use crate::foundations::{ Array, Bytes, Content, Datetime, Module, Scope, StyleChain, Styles, @@ -110,7 +110,6 @@ fn typeset( let mut iter = 0; let mut document; - let mut delayed; let mut introspector = Introspector::new(&[]); // Relayout until all introspections stabilize. @@ -119,7 +118,7 @@ fn typeset( tracing::info!("Layout iteration {iter}"); // Clear delayed errors. - delayed = DelayedErrors::new(); + tracer.delayed(); let constraint = ::Constraint::new(); let mut locator = Locator::new(); @@ -127,7 +126,6 @@ fn typeset( world, tracer: tracer.track_mut(), locator: &mut locator, - delayed: delayed.track_mut(), introspector: introspector.track_with(&constraint), }; @@ -150,8 +148,9 @@ fn typeset( } // Promote delayed errors. - if !delayed.0.is_empty() { - return Err(delayed.0); + let delayed = tracer.delayed(); + if !delayed.is_empty() { + return Err(delayed); } Ok(document)