diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/diag.rs | 4 | ||||
| -rw-r--r-- | src/eval/func.rs | 4 | ||||
| -rw-r--r-- | src/eval/library.rs | 2 | ||||
| -rw-r--r-- | src/eval/mod.rs | 43 | ||||
| -rw-r--r-- | src/image.rs | 6 | ||||
| -rw-r--r-- | src/lib.rs | 2 | ||||
| -rw-r--r-- | src/model/mod.rs | 10 |
7 files changed, 41 insertions, 30 deletions
diff --git a/src/diag.rs b/src/diag.rs index 556d3255..a122fe1f 100644 --- a/src/diag.rs +++ b/src/diag.rs @@ -130,13 +130,13 @@ impl Display for Tracepoint { /// Enrich a [`SourceResult`] with a tracepoint. pub trait Trace<T> { /// Add the tracepoint to all errors that lie outside the `span`. - fn trace<F>(self, world: Tracked<dyn World>, make_point: F, span: Span) -> Self + fn trace<F>(self, world: Tracked<dyn World + '_>, make_point: F, span: Span) -> Self where F: Fn() -> Tracepoint; } impl<T> Trace<T> for SourceResult<T> { - fn trace<F>(self, world: Tracked<dyn World>, make_point: F, span: Span) -> Self + fn trace<F>(self, world: Tracked<dyn World + '_>, make_point: F, span: Span) -> Self where F: Fn() -> Tracepoint, { diff --git a/src/eval/func.rs b/src/eval/func.rs index 51eba564..060e72cf 100644 --- a/src/eval/func.rs +++ b/src/eval/func.rs @@ -4,7 +4,7 @@ use std::fmt::{self, Debug, Formatter}; use std::hash::{Hash, Hasher}; use std::sync::Arc; -use comemo::{Prehashed, Track, Tracked, TrackedMut}; +use comemo::{Prehashed, Tracked, TrackedMut}; use ecow::eco_format; use once_cell::sync::Lazy; @@ -317,7 +317,7 @@ impl Closure { #[allow(clippy::too_many_arguments)] fn call( this: &Func, - world: Tracked<dyn World>, + world: Tracked<dyn World + '_>, route: Tracked<Route>, tracer: TrackedMut<Tracer>, provider: TrackedMut<StabilityProvider>, diff --git a/src/eval/library.rs b/src/eval/library.rs index 25f715f8..0067bf57 100644 --- a/src/eval/library.rs +++ b/src/eval/library.rs @@ -67,7 +67,7 @@ pub struct LangItems { /// The keys contained in the bibliography and short descriptions of them. #[allow(clippy::type_complexity)] pub bibliography_keys: fn( - world: Tracked<dyn World>, + world: Tracked<dyn World + '_>, introspector: Tracked<Introspector>, ) -> Vec<(EcoString, Option<EcoString>)>, /// A section heading: `= Introduction`. diff --git a/src/eval/mod.rs b/src/eval/mod.rs index a837c9e0..95822530 100644 --- a/src/eval/mod.rs +++ b/src/eval/mod.rs @@ -41,7 +41,7 @@ use std::collections::HashSet; use std::mem; use std::path::{Path, PathBuf}; -use comemo::{Track, Tracked, TrackedMut}; +use comemo::{Track, Tracked, TrackedMut, Validate}; use ecow::{EcoString, EcoVec}; use unicode_segmentation::UnicodeSegmentation; @@ -67,7 +67,7 @@ const MAX_CALL_DEPTH: usize = 64; #[comemo::memoize] #[tracing::instrument(skip(world, route, tracer, source))] pub fn eval( - world: Tracked<dyn World>, + world: Tracked<dyn World + '_>, route: Tracked<Route>, tracer: TrackedMut<Tracer>, source: &Source, @@ -84,7 +84,7 @@ pub fn eval( set_lang_items(library.items.clone()); // Evaluate the module. - let route = unsafe { Route::insert(route, id) }; + let route = Route::insert(route, id); let scopes = Scopes::new(Some(library)); let mut provider = StabilityProvider::new(); let introspector = Introspector::new(&[]); @@ -117,7 +117,7 @@ pub fn eval( /// Everything in the output is associated with the given `span`. #[comemo::memoize] pub fn eval_string( - world: Tracked<dyn World>, + world: Tracked<dyn World + '_>, code: &str, span: Span, ) -> SourceResult<Value> { @@ -164,7 +164,7 @@ pub struct Vm<'a> { /// The language items. items: LangItems, /// The route of source ids the VM took to reach its current location. - route: Tracked<'a, Route>, + route: Tracked<'a, Route<'a>>, /// The current location. location: SourceId, /// A control flow event that is currently happening. @@ -200,7 +200,7 @@ impl<'a> Vm<'a> { } /// Access the underlying world. - pub fn world(&self) -> Tracked<'a, dyn World> { + pub fn world(&self) -> Tracked<'a, dyn World + 'a> { self.vt.world } @@ -263,34 +263,45 @@ impl Flow { /// A route of source ids. #[derive(Default)] -pub struct Route { - parent: Option<Tracked<'static, Self>>, +pub struct Route<'a> { + // We need to override the constraint's lifetime here so that `Tracked` is + // covariant over the constraint. If it becomes invariant, we're in for a + // world of lifetime pain. + outer: Option<Tracked<'a, Self, <Route<'static> as Validate>::Constraint>>, id: Option<SourceId>, } -impl Route { +impl<'a> Route<'a> { /// Create a new route with just one entry. pub fn new(id: SourceId) -> Self { - Self { id: Some(id), parent: None } + Self { id: Some(id), outer: None } } /// Insert a new id into the route. /// /// You must guarantee that `outer` lives longer than the resulting /// route is ever used. - unsafe fn insert(outer: Tracked<Route>, id: SourceId) -> Route { - Route { - parent: Some(std::mem::transmute(outer)), - id: Some(id), + pub fn insert(outer: Tracked<'a, Self>, id: SourceId) -> Self { + Route { outer: Some(outer), id: Some(id) } + } + + /// Start tracking this locator. + /// + /// In comparison to [`Track::track`], this method skips this chain link + /// if it does not contribute anything. + pub fn track(&self) -> Tracked<'_, Self> { + match self.outer { + Some(outer) if self.id.is_none() => outer, + _ => Track::track(self), } } } #[comemo::track] -impl Route { +impl<'a> Route<'a> { /// Whether the given id is part of the route. fn contains(&self, id: SourceId) -> bool { - self.id == Some(id) || self.parent.map_or(false, |parent| parent.contains(id)) + self.id == Some(id) || self.outer.map_or(false, |outer| outer.contains(id)) } } diff --git a/src/image.rs b/src/image.rs index d78c7428..f9974599 100644 --- a/src/image.rs +++ b/src/image.rs @@ -53,7 +53,7 @@ impl Image { pub fn with_fonts( data: Buffer, format: ImageFormat, - world: Tracked<dyn World>, + world: Tracked<dyn World + '_>, fallback_family: Option<&str>, alt: Option<EcoString>, ) -> StrResult<Self> { @@ -240,7 +240,7 @@ fn decode_svg(data: &Buffer) -> StrResult<Arc<DecodedImage>> { #[comemo::memoize] fn decode_svg_with_fonts( data: &Buffer, - world: Tracked<dyn World>, + world: Tracked<dyn World + '_>, fallback_family: Option<&str>, ) -> StrResult<Arc<DecodedImage>> { let mut opts = usvg::Options::default(); @@ -269,7 +269,7 @@ fn decode_svg_with_fonts( /// Discover and load the fonts referenced by an SVG. fn load_svg_fonts( tree: &usvg::Tree, - world: Tracked<dyn World>, + world: Tracked<dyn World + '_>, fallback_family: Option<&str>, ) -> fontdb::Database { let mut referenced = BTreeMap::<EcoString, bool>::new(); @@ -65,7 +65,7 @@ use crate::util::Buffer; /// Compile a source file into a fully layouted document. #[tracing::instrument(skip(world))] -pub fn compile(world: &(dyn World + 'static)) -> SourceResult<Document> { +pub fn compile(world: &dyn World) -> SourceResult<Document> { // Evaluate the source file into a module. let route = Route::default(); let mut tracer = Tracer::default(); diff --git a/src/model/mod.rs b/src/model/mod.rs index 4ec7311a..92c4293b 100644 --- a/src/model/mod.rs +++ b/src/model/mod.rs @@ -14,7 +14,7 @@ pub use self::styles::*; pub use typst_macros::element; -use comemo::{Constraint, Track, Tracked, TrackedMut}; +use comemo::{Track, Tracked, TrackedMut, Validate}; use crate::diag::SourceResult; use crate::doc::Document; @@ -25,7 +25,7 @@ use crate::World; #[comemo::memoize] #[tracing::instrument(skip(world, tracer, content))] pub fn typeset( - world: Tracked<dyn World>, + world: Tracked<dyn World + '_>, mut tracer: TrackedMut<Tracer>, content: &Content, ) -> SourceResult<Document> { @@ -42,8 +42,8 @@ pub fn typeset( loop { tracing::info!("Layout iteration {iter}"); - let constraint = Constraint::new(); let mut provider = StabilityProvider::new(); + let constraint = <Introspector as Validate>::Constraint::new(); let mut vt = Vt { world, tracer: TrackedMut::reborrow_mut(&mut tracer), @@ -56,7 +56,7 @@ pub fn typeset( introspector = Introspector::new(&document.pages); - if iter >= 5 || introspector.valid(&constraint) { + if iter >= 5 || introspector.validate(&constraint) { break; } } @@ -69,7 +69,7 @@ pub fn typeset( /// Holds the state needed to [typeset] content. pub struct Vt<'a> { /// The compilation environment. - pub world: Tracked<'a, dyn World>, + pub world: Tracked<'a, dyn World + 'a>, /// The tracer for inspection of the values an expression produces. pub tracer: TrackedMut<'a, Tracer>, /// Provides stable identities to elements. |
