Skip to content

Commit 89b75f0

Browse files
authored
Refactor/printer (#122)
This PR splits `src/printer.rs` (~1700 lines) into a `src/printer/` directory module with focused submodules, then follows up with doc comments, idiomatic Rust cleanup, and a structural improvement to the phase boundary enforcement. All integration and UI tests pass unchanged. ## Structure The split creates nine submodules, each with a single responsibility: | Module | Lines | Responsibility | |--------|------:|----------------| | `schema.rs` | ~510 | Data model types (`SmirJson`, `Item`, `AllocInfo`, `TypeMetadata`, `LinkMapKey`, etc.) | | `mir_visitor.rs` | ~430 | `BodyAnalyzer`: single-pass MIR body traversal collecting calls, allocs, types, spans | | `collect.rs` | ~230 | Three-phase pipeline: collect items, analyze bodies, assemble final output | | `items.rs` | ~225 | `Item` construction from `MonoItem` with optional debug-level details | | `types.rs` | ~170 | `TypeMetadata` construction from `TyKind` + layout | | `ty_visitor.rs` | ~120 | Recursive type visitor collecting all reachable types with layout info | | `link_map.rs` | ~107 | Link-time function resolution map (type + instance kind to symbol name) | | `mod.rs` | ~83 | Module glue: macros, env-var helpers, re-exports, `emit_smir` | | `util.rs` | ~64 | Name resolution, attribute queries, small helpers | ## Changes by commit 1. **Split printer.rs into a directory module**: mechanical extraction; no code changes beyond moving `use` / `extern crate` declarations into each submodule and adjusting visibility. 2. **Add module-level doc comments to all printer submodules**: `//!` doc headers describing each module's purpose and key types. 3. **Idiomatic Rust cleanup across printer submodules**: - `if let Some(x) = y { x } else { z }` to `y.unwrap_or_else(|| z)` - `if opt.is_none() { return; } let val = opt.unwrap()` to `let Some(val) = opt else { return; }` - Remove unnecessary `.clone()` calls on `key` in `get_mut` / `insert` - Change `collect_alloc` to take `offset: usize` by value (was `&usize`) - Extract `opaque_placeholder_ty()` helper for the `Ty::to_val(0)` sentinel - Doc comments on `FnSymType`, `LinkMapKey`, `AllocInfo`, `TypeMetadata`, `SourceData`, `SmirJson`, `SmirJsonDebugInfo` 4. **Address review feedback and fix doc comment inaccuracies**. 5. **Remove `MonoItem` from `Item` for structural phase enforcement**: The three-phase collection pipeline has an invariant: phase 3 (`assemble_smir`) must not call `inst.body()` or otherwise re-enter rustc. Previously this was enforced by convention only, because `Item` carried a `pub(super) mono_item: MonoItem` field that gave any code with an `&Item` full access to `Instance::body()`. This commit removes `mono_item` from `Item` entirely, so the invariant is structural: phase 3 code literally cannot call `inst.body()` because it never has a `MonoItem` to call it on. The type system enforces what discipline previously had to. Concretely: `mk_item` now returns `(MonoItem, Item)` instead of `Item`, and the phase 1+2 maps carry `(MonoItem, Item)` tuples. The `MonoItem` lives alongside the `Item` during collection and analysis, gets passed directly to `maybe_add_to_link_map` and `warn_missing_body` (now a free function in `collect.rs`), and is naturally dropped when only the `Item` is pushed into `all_items`. By the time `assemble_smir` runs, no `MonoItem` values exist. As a bonus, this fixes a latent `PartialEq`/`Ord` inconsistency: `PartialEq` was comparing `mono_item` while `Ord` compared `symbol_name` + item-kind name. `PartialEq` now delegates to `Ord`, so the two are consistent. ## Test plan - [x] `cargo build` succeeds - [x] `cargo clippy` clean - [x] `make integration-test` passes (28/28) - [x] `make test-ui` passes (2875/2875, 0 failures)
1 parent e875066 commit 89b75f0

12 files changed

Lines changed: 2001 additions & 1715 deletions

File tree

CHANGELOG.md

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,21 +22,23 @@ retroactive best-effort summary; earlier changes were not formally tracked.
2222
- `cargo_stable_mir_json` helper binary for cargo integration ([#47])
2323
- Nix derivation for reproducible builds ([#96])
2424
- macOS support ([#97])
25+
- Mutability field on `PtrType` and `RefType` in `TypeMetadata`, needed to distinguish `PtrToPtr` casts that change mutability from those that change pointee type ([#127])
26+
- ADR-001: index-first graph architecture for MIR visualization ([#124])
2527

2628
### Changed
27-
- Restructured `printer.rs` into a declarative 3-phase pipeline: `collect_items` -> `collect_and_analyze_items` -> `assemble_smir`, with `CollectedCrate`/`DerivedInfo` interface types enforcing the boundary between collection and assembly
28-
- Added `AllocMap` with debug-mode coherence checking (`verify_coherence`): asserts that every `AllocId` in stored bodies exists in the alloc map and that no body is walked twice; zero cost in release builds
29-
- Removed dead static-item fixup from `assemble_smir` (violated the phase boundary, misclassified statics as functions; never triggered in integration tests)
30-
- Rewrote `run_ui_tests.sh`: flag-based CLI (`--verbose`, `--save-generated-output`, `--save-debug-output`), build-once-then-invoke (eliminates per-test cargo overhead), arch-aware skip logic for cross-platform test lists
31-
- UI test runners now extract and pass `//@ compile-flags:`, `//@ edition:`, and `//@ rustc-env:` directives from test files (previously silently ignored)
29+
- Restructured `printer.rs` into a declarative 3-phase pipeline: `collect_items` -> `collect_and_analyze_items` -> `assemble_smir`, with `CollectedCrate`/`DerivedInfo` interface types enforcing the boundary between collection and assembly ([#121])
30+
- Added `AllocMap` with debug-mode coherence checking (`verify_coherence`): asserts that every `AllocId` in stored bodies exists in the alloc map and that no body is walked twice; zero cost in release builds ([#121])
31+
- Removed dead static-item fixup from `assemble_smir` (violated the phase boundary, misclassified statics as functions; never triggered in integration tests) ([#121])
32+
- Rewrote `run_ui_tests.sh`: flag-based CLI (`--verbose`, `--save-generated-output`, `--save-debug-output`), build-once-then-invoke (eliminates per-test cargo overhead), arch-aware skip logic for cross-platform test lists ([#126])
33+
- UI test runners now extract and pass `//@ compile-flags:`, `//@ edition:`, and `//@ rustc-env:` directives from test files (previously silently ignored) ([#126])
3234
- Switched from compiler build to `rustup`-managed toolchain ([#33])
3335
- Removed forked rust dependency ([#19])
3436

3537
### Fixed
36-
- Fixed `get_prov_ty` to recursively walk nested struct/tuple fields when resolving provenance types; previously used exact byte-offset matching which panicked on pointers inside nested structs (e.g., `&str` at offset 56 inside `TestDesc` inside `TestDescAndFn`)
37-
- Removed incorrect `builtin_deref` assertions from VTable and Static allocation collection that rejected valid non-pointer types (raw `*const ()` vtable pointers, non-pointer statics)
38-
- Replaced panicking `unwrap`/`assert` calls in `get_prov_ty` with graceful fallbacks for layout failures, non-rigid types, and unexpected offsets
39-
- Fixed early `return` in `BodyAnalyzer::visit_terminator` that skipped `super_terminator()`, causing alloc/type/span collection to miss everything inside `Call` terminators with non-`ZeroSized` function operands (const-evaluated function pointers); bug present since [`aff2dd0`](https://github.com/runtimeverification/stable-mir-json/commit/aff2dd0)
38+
- Fixed `get_prov_ty` to recursively walk nested struct/tuple fields when resolving provenance types; previously used exact byte-offset matching which panicked on pointers inside nested structs (e.g., `&str` at offset 56 inside `TestDesc` inside `TestDescAndFn`) ([#126])
39+
- Removed incorrect `builtin_deref` assertions from VTable and Static allocation collection that rejected valid non-pointer types (raw `*const ()` vtable pointers, non-pointer statics) ([#126])
40+
- Replaced panicking `unwrap`/`assert` calls in `get_prov_ty` with graceful fallbacks for layout failures, non-rigid types, and unexpected offsets ([#126])
41+
- Fixed early `return` in `BodyAnalyzer::visit_terminator` that skipped `super_terminator()`, causing alloc/type/span collection to miss everything inside `Call` terminators with non-`ZeroSized` function operands (const-evaluated function pointers); bug present since [`aff2dd0`](https://github.com/runtimeverification/stable-mir-json/commit/aff2dd0) ([#126])
4042
- Avoided duplicate `inst.body()` calls that were reallocating `AllocId`s ([#120])
4143
- Prevented svg/png generation when `dot` is unavailable ([#117])
4244
- Removed unreachable early return in D2 legend rendering ([#118])
@@ -72,6 +74,10 @@ retroactive best-effort summary; earlier changes were not formally tracked.
7274
[#117]: https://github.com/runtimeverification/stable-mir-json/pull/117
7375
[#118]: https://github.com/runtimeverification/stable-mir-json/pull/118
7476
[#120]: https://github.com/runtimeverification/stable-mir-json/pull/120
77+
[#121]: https://github.com/runtimeverification/stable-mir-json/pull/121
78+
[#124]: https://github.com/runtimeverification/stable-mir-json/pull/124
79+
[#126]: https://github.com/runtimeverification/stable-mir-json/pull/126
80+
[#127]: https://github.com/runtimeverification/stable-mir-json/pull/127
7581

7682
## [0.1.0] - 2024-11-29
7783

src/mk_graph/index.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ pub enum TypeKind {
7575
pointee: Ty,
7676
mutability: stable_mir::mir::Mutability,
7777
},
78+
Dyn,
7879
Function,
7980
Void,
8081
}
@@ -409,6 +410,10 @@ impl TypeEntry {
409410
layout_info,
410411
)
411412
}
413+
TypeMetadata::DynType { name, layout } => {
414+
let layout_info = layout.as_ref().map(LayoutInfo::from_shape);
415+
(name.clone(), TypeKind::Dyn, layout_info)
416+
}
412417
TypeMetadata::FunType(name) => (name.clone(), TypeKind::Function, None),
413418
TypeMetadata::VoidType => ("()".to_string(), TypeKind::Void, None),
414419
};

0 commit comments

Comments
 (0)