From 19559466e56ba9d1ad4714ad2d489e6b29ff9e2c Mon Sep 17 00:00:00 2001 From: Laurenz Date: Mon, 7 Jul 2025 11:51:35 +0200 Subject: [PATCH] Miri test --- .github/workflows/ci.yml | 12 ++++++ .../src/foundations/content/raw.rs | 39 +++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2354de582..70518860e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -103,3 +103,15 @@ jobs: - uses: Swatinem/rust-cache@v2 - run: cargo install --locked cargo-fuzz@0.12.0 - run: cd tests/fuzz && cargo fuzz build --dev + + miri: + name: Check unsafe code + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@master + with: + components: miri + toolchain: nightly-2024-10-29 + - uses: Swatinem/rust-cache@v2 + - run: cargo miri test -p typst-library test_miri diff --git a/crates/typst-library/src/foundations/content/raw.rs b/crates/typst-library/src/foundations/content/raw.rs index c0a3c2634..f5dfffd73 100644 --- a/crates/typst-library/src/foundations/content/raw.rs +++ b/crates/typst-library/src/foundations/content/raw.rs @@ -385,3 +385,42 @@ fn ref_count_overflow(ptr: NonNull
, elem: Element, span: Span) -> ! { drop(RawContent { ptr, elem, span }); panic!("reference count overflow"); } + +#[cfg(test)] +mod tests { + use crate::foundations::{NativeElement, Repr, StyleChain, Value}; + use crate::introspection::Location; + use crate::model::HeadingElem; + use crate::text::TextElem; + + #[test] + fn test_miri() { + let styles = StyleChain::default(); + + let mut first = HeadingElem::new(TextElem::packed("Hi!")).with_offset(2).pack(); + let hash1 = typst_utils::hash128(&first); + first.set_location(Location::new(10)); + let _ = format!("{first:?}"); + let _ = first.repr(); + + assert!(first.is::()); + assert!(!first.is::()); + assert_eq!(first.to_packed::(), None); + assert_eq!(first.location(), Some(Location::new(10))); + assert_eq!(first.field_by_name("offset"), Ok(Value::Int(2))); + assert!(!first.has("depth".into())); + + let second = first.clone(); + first.materialize(styles); + + let first_packed = first.to_packed::().unwrap(); + let second_packed = second.to_packed::().unwrap(); + + assert!(first.has("depth".into())); + assert!(!second.has("depth".into())); + assert!(first_packed.depth.is_set()); + assert!(!second_packed.depth.is_set()); + assert_ne!(first, second); + assert_ne!(hash1, typst_utils::hash128(&first)); + } +}