summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/typst/src/model/mod.rs17
-rw-r--r--tests/ref/meta/state.pngbin53638 -> 47450 bytes
-rw-r--r--tests/src/tests.rs21
-rw-r--r--tests/typ/meta/state.typ10
4 files changed, 42 insertions, 6 deletions
diff --git a/crates/typst/src/model/mod.rs b/crates/typst/src/model/mod.rs
index cab1f71f..d839422a 100644
--- a/crates/typst/src/model/mod.rs
+++ b/crates/typst/src/model/mod.rs
@@ -28,7 +28,7 @@ use std::mem::ManuallyDrop;
use comemo::{Track, Tracked, TrackedMut, Validate};
-use crate::diag::{SourceDiagnostic, SourceResult};
+use crate::diag::{warning, SourceDiagnostic, SourceResult};
use crate::doc::Document;
use crate::eval::Tracer;
use crate::World;
@@ -82,7 +82,20 @@ pub fn typeset(
introspector = ManuallyDrop::new(Introspector::new(&document.pages));
iter += 1;
- if iter >= 5 || introspector.validate(&constraint) {
+ if introspector.validate(&constraint) {
+ break;
+ }
+
+ if iter >= 5 {
+ tracer.warn(
+ warning!(
+ world.main().root().span(),
+ "layout did not converge within 5 attempts",
+ )
+ .with_hint(
+ "check if any states or queries are updating themselves".into(),
+ ),
+ );
break;
}
}
diff --git a/tests/ref/meta/state.png b/tests/ref/meta/state.png
index d179c3c5..9b3bf57c 100644
--- a/tests/ref/meta/state.png
+++ b/tests/ref/meta/state.png
Binary files differ
diff --git a/tests/src/tests.rs b/tests/src/tests.rs
index a8cf25f7..f7eceead 100644
--- a/tests/src/tests.rs
+++ b/tests/src/tests.rs
@@ -670,8 +670,14 @@ fn parse_part_metadata(source: &Source) -> TestPartMetadata {
compare_ref = get_flag_metadata(line, "Ref").or(compare_ref);
validate_hints = get_flag_metadata(line, "Hints").or(validate_hints);
- fn num(s: &mut Scanner) -> usize {
- s.eat_while(char::is_numeric).parse().unwrap()
+ fn num(s: &mut Scanner) -> isize {
+ let mut first = true;
+ let n = &s.eat_while(|c: char| {
+ let valid = first && c == '-' || c.is_numeric();
+ first = false;
+ valid
+ });
+ n.parse().unwrap_or_else(|e| panic!("{n} is not a number ({e})"))
}
let comments_until_code =
@@ -681,8 +687,15 @@ fn parse_part_metadata(source: &Source) -> TestPartMetadata {
let first = num(s) - 1;
let (delta, column) =
if s.eat_if(':') { (first, num(s) - 1) } else { (0, first) };
- let line = (i + comments_until_code) + delta;
- source.line_column_to_byte(line, column).unwrap()
+ let line = (i + comments_until_code)
+ .checked_add_signed(delta)
+ .expect("line number overflowed limits");
+ source
+ .line_column_to_byte(
+ line,
+ usize::try_from(column).expect("column number overflowed limits"),
+ )
+ .unwrap()
};
let error_factory: fn(Range<usize>, String) -> UserOutput = UserOutput::error;
diff --git a/tests/typ/meta/state.typ b/tests/typ/meta/state.typ
index 8f460ce1..1c329a95 100644
--- a/tests/typ/meta/state.typ
+++ b/tests/typ/meta/state.typ
@@ -46,3 +46,13 @@ Was: #locate(location => {
#trait[Adventure]
#trait[Fear]
#trait[Anger]
+
+---
+// Make sure that a warning is produced if the layout fails to converge.
+// Warning: -3:1-6:1 layout did not converge within 5 attempts
+// Hint: -3:1-6:1 check if any states or queries are updating themselves
+#let s = state("x", 1)
+#locate(loc => {
+ s.update(s.final(loc) + 1)
+})
+#s.display()