Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
target/
tests/ui/failing/*
tests/ui/passing/*
tests/ui/passing/*
tests/ui/debug/*
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,15 @@ retroactive best-effort summary; earlier changes were not formally tracked.
- 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
- 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
- Removed dead static-item fixup from `assemble_smir` (violated the phase boundary, misclassified statics as functions; never triggered in integration tests)
- 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
- UI test runners now extract and pass `//@ compile-flags:`, `//@ edition:`, and `//@ rustc-env:` directives from test files (previously silently ignored)
- Switched from compiler build to `rustup`-managed toolchain ([#33])
- Removed forked rust dependency ([#19])

### Fixed
- 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`)
- Removed incorrect `builtin_deref` assertions from VTable and Static allocation collection that rejected valid non-pointer types (raw `*const ()` vtable pointers, non-pointer statics)
- Replaced panicking `unwrap`/`assert` calls in `get_prov_ty` with graceful fallbacks for layout failures, non-rigid types, and unexpected offsets
- 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)
- Avoided duplicate `inst.body()` calls that were reallocating `AllocId`s ([#120])
- Prevented svg/png generation when `dot` is unavailable ([#117])
Expand Down
7 changes: 1 addition & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,7 @@ remake-ui-tests:

test-ui: VERBOSE?=0
test-ui:
# Check if RUST_DIR_ROOT is set
if [ -z "$$RUST_DIR_ROOT" ]; then \
echo "Error: RUST_DIR_ROOT is not set. Please set it to the absolute path to rust compiler checkout."; \
exit 1; \
fi
bash tests/ui/run_ui_tests.sh "$$RUST_DIR_ROOT" "${VERBOSE}"
bash tests/ui/run_ui_tests.sh $(if $(filter 1,$(VERBOSE)),--verbose) "$$RUST_DIR_ROOT"

.PHONY: dot svg png d2 clean-graphs check-graphviz

Expand Down
113 changes: 77 additions & 36 deletions src/printer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -844,40 +844,72 @@ fn update_link_map<'tcx>(
/// Returns the field index (source order) for a given offset and layout if
/// the layout contains fields (shared between all variants), otherwise None.
/// NB No search for fields within variants (needs recursive call).
fn field_for_offset(l: LayoutShape, offset: usize) -> Option<usize> {
// FieldIdx
match l.fields {
fn field_for_offset(l: &LayoutShape, offset: usize) -> Option<usize> {
match &l.fields {
FieldsShape::Primitive | FieldsShape::Union(_) | FieldsShape::Array { .. } => None,
FieldsShape::Arbitrary { offsets } => offsets
.iter()
.enumerate()
.find(|(_, o)| o.bytes() == offset)
.map(|(i, _)| i),
}
}

/// Find the field whose byte range contains the given offset.
/// Returns (field_index, field_start_byte_offset).
fn field_containing_offset(l: &LayoutShape, offset: usize) -> Option<(usize, usize)> {
match &l.fields {
FieldsShape::Arbitrary { offsets } => {
let fields: Vec<usize> = offsets.into_iter().map(|o| o.bytes()).collect();
fields
.into_iter()
let mut indexed: Vec<(usize, usize)> = offsets
.iter()
.enumerate()
.find(|(_, o)| *o == offset)
.map(|(i, _)| i)
.map(|(i, o)| (i, o.bytes()))
.collect();
indexed.sort_by_key(|&(_, o)| o);
// The containing field is the one with the largest start offset <= target.
indexed.into_iter().rev().find(|&(_, o)| o <= offset)
}
_ => None,
}
}

fn get_prov_ty(ty: stable_mir::ty::Ty, offset: &usize) -> Option<stable_mir::ty::Ty> {
use stable_mir::ty::RigidTy;
let ty_kind = ty.kind();
debug_log_println!("get_prov_ty: {:?} offset={}", ty_kind, offset);
// if ty is a pointer, box, or Ref, expect no offset and dereference
if let Some(ty) = ty_kind.builtin_deref(true) {
assert!(*offset == 0);
return Some(ty.ty);
if let Some(derefed) = ty_kind.builtin_deref(true) {
if *offset != 0 {
eprintln!(
"get_prov_ty: unexpected non-zero offset {} for builtin_deref type {:?}",
offset, ty_kind
);
return None;
}
debug_log_println!("get_prov_ty: resolved -> pointee {:?}", derefed.ty.kind());
return Some(derefed.ty);
}

// Otherwise the allocation is a reference within another kind of data.
// Decompose this outer data type to determine the reference type
let layout = ty
.layout()
.map(|l| l.shape())
.expect("Unable to get layout for {ty_kind:?}");
let ref_ty = match ty_kind
.rigid()
.expect("Non-rigid-ty allocation found! {ty_kind:?}")
{
let layout = match ty.layout().map(|l| l.shape()) {
Ok(l) => l,
Err(_) => {
eprintln!("get_prov_ty: unable to get layout for {:?}", ty_kind);
return None;
}
};
let rigid = match ty_kind.rigid() {
Some(r) => r,
None => {
eprintln!(
"get_prov_ty: non-rigid type in allocation: {:?} (offset={})",
ty_kind, offset
);
return None;
}
};
let ref_ty = match rigid {
// homogenous, so no choice. Could check alignment of the offset...
RigidTy::Array(ty, _) | RigidTy::Slice(ty) => Some(*ty),
// cases covered above
Expand All @@ -887,16 +919,24 @@ fn get_prov_ty(ty: stable_mir::ty::Ty, offset: &usize) -> Option<stable_mir::ty:
RigidTy::Adt(def, _) if def.is_box() => {
unreachable!("Covered by builtin_deref above")
}
// For other structs, consult layout to determine field type
// For structs, find the field containing this offset and recurse.
// The provenance offset may point into a nested struct field, so we
// walk down through the field hierarchy until we reach the pointer.
RigidTy::Adt(adt_def, args) if ty_kind.is_struct() => {
let field_idx = field_for_offset(layout, *offset).unwrap();
let (field_idx, field_start) = field_containing_offset(&layout, *offset)?;
// NB struct, single variant
let fields = adt_def.variants().pop().map(|v| v.fields()).unwrap();
fields.get(field_idx).map(|f| f.ty_with_args(args))
let fields = adt_def.variants().pop().map(|v| v.fields())?;
let field_ty = fields.get(field_idx)?.ty_with_args(args);
let relative_offset = *offset - field_start;
debug_log_println!(
"get_prov_ty: struct {:?} offset={} -> field {} (start={}) type {:?}, relative_offset={}",
adt_def, offset, field_idx, field_start, field_ty.kind(), relative_offset
);
return get_prov_ty(field_ty, &relative_offset);
}
RigidTy::Adt(_adt_def, _args) if ty_kind.is_enum() => {
// we have to figure out which variant we are dealing with (requires the data)
match field_for_offset(layout, *offset) {
match field_for_offset(&layout, *offset) {
None =>
// FIXME we'd have to figure out which variant we are dealing with (requires the data)
{
Expand All @@ -909,9 +949,20 @@ fn get_prov_ty(ty: stable_mir::ty::Ty, offset: &usize) -> Option<stable_mir::ty:
}
}
}
// Same as structs: find containing field and recurse.
RigidTy::Tuple(fields) => {
let field_idx = field_for_offset(layout, *offset)?;
fields.get(field_idx).copied()
let (field_idx, field_start) = field_containing_offset(&layout, *offset)?;
let field_ty = *fields.get(field_idx)?;
let relative_offset = *offset - field_start;
debug_log_println!(
"get_prov_ty: tuple offset={} -> field {} (start={}) type {:?}, relative_offset={}",
offset,
field_idx,
field_start,
field_ty.kind(),
relative_offset
);
return get_prov_ty(field_ty, &relative_offset);
}
RigidTy::FnPtr(_) => None,
_unimplemented => {
Expand Down Expand Up @@ -972,21 +1023,11 @@ fn collect_alloc(
}
}
GlobalAlloc::Static(_) => {
assert!(
kind.clone().builtin_deref(true).is_some(),
"Allocated pointer is not a built-in pointer type: {:?}",
kind
);
val_collector
.visited_allocs
.insert(val, (ty, global_alloc.clone()));
}
GlobalAlloc::VTable(_, _) => {
assert!(
kind.clone().builtin_deref(true).is_some(),
"Allocated pointer is not a built-in pointer type: {:?}",
kind
);
val_collector
.visited_allocs
.insert(val, (ty, global_alloc.clone()));
Expand Down
25 changes: 1 addition & 24 deletions tests/ui/failing.tsv
Original file line number Diff line number Diff line change
@@ -1,25 +1,2 @@
tests/ui/async-await/issue-60709.rs 101
tests/ui/async-await/issues/issue-59972.rs 101
tests/ui/box/thin_align.rs 101
tests/ui/box/thin_drop.rs 101
tests/ui/box/thin_new.rs 101
tests/ui/box/thin_zst.rs 101
tests/ui/cfg/cfg_attr.rs 101
tests/ui/cfg/cfgs-on-items.rs 101
tests/ui/consts/const-eval/const_fn_ptr.rs 101
tests/ui/consts/const-int-arithmetic-overflow.rs 101
tests/ui/consts/const-trait-to-trait.rs 101
tests/ui/env-macro/env-env-overload.rs 101
tests/ui/env-macro/env-env.rs 101
tests/ui/fmt/fmt_debug/none.rs 101
tests/ui/issues/issue-11205.rs 101
tests/ui/issues/issue-26641.rs 101
tests/ui/label/label_break_value_desugared_break.rs 101
tests/ui/macros/macro-meta-items.rs 101
tests/ui/rfcs/rfc-2091-track-caller/caller-location-fnptr-rt-ctfe-equiv.rs 101
tests/ui/test-attrs/test-panic-while-printing.rs 101
tests/ui/traits/const-traits/const-drop.rs 101
tests/ui/try-block/issue-45124.rs 101
tests/ui/try-block/try-block-in-match.rs 101
tests/ui/try-block/try-block-in-return.rs 101
tests/ui/try-block/try-block.rs 101
tests/ui/sanitizer/cfi/drop-in-place.rs 101
25 changes: 24 additions & 1 deletion tests/ui/passing.tsv
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,8 @@ tests/ui/associated-types/issue-54467.rs
tests/ui/associated-types/issue-55846.rs
tests/ui/associated-types/object-method-numbering.rs
tests/ui/async-await/context-is-sorta-unwindsafe.rs
tests/ui/async-await/issue-60709.rs
tests/ui/async-await/issues/issue-59972.rs
tests/ui/attributes/tool_attributes.rs
tests/ui/augmented-assignments-rpass.rs
tests/ui/auto-instantiate.rs
Expand Down Expand Up @@ -350,6 +352,10 @@ tests/ui/box/into-boxed-slice.rs
tests/ui/box/new-box-syntax.rs
tests/ui/box/new-box.rs
tests/ui/box/new.rs
tests/ui/box/thin_align.rs
tests/ui/box/thin_drop.rs
tests/ui/box/thin_new.rs
tests/ui/box/thin_zst.rs
tests/ui/box/unit/expr-block-generic-unique1.rs
tests/ui/box/unit/expr-block-generic-unique2.rs
tests/ui/box/unit/expr-if-unique.rs
Expand Down Expand Up @@ -412,7 +418,9 @@ tests/ui/cfg/cfg-macros-notfoo.rs
tests/ui/cfg/cfg-target-abi.rs
tests/ui/cfg/cfg-target-compact.rs
tests/ui/cfg/cfg-target-vendor.rs
tests/ui/cfg/cfg_attr.rs
tests/ui/cfg/cfg_stmt_expr.rs
tests/ui/cfg/cfgs-on-items.rs
tests/ui/cfg/conditional-compile.rs
tests/ui/cfg/true-false.rs
tests/ui/cfguard-run.rs
Expand Down Expand Up @@ -629,6 +637,7 @@ tests/ui/consts/const-enum-vec-index.rs
tests/ui/consts/const-enum-vec-ptr.rs
tests/ui/consts/const-enum-vector.rs
tests/ui/consts/const-err-rpass.rs
tests/ui/consts/const-eval/const_fn_ptr.rs
tests/ui/consts/const-eval/enum_discr.rs
tests/ui/consts/const-eval/float_methods.rs
tests/ui/consts/const-eval/heap/alloc_intrinsic_nontransient.rs
Expand All @@ -654,6 +663,7 @@ tests/ui/consts/const-fn-type-name.rs
tests/ui/consts/const-fn-val.rs
tests/ui/consts/const-fn.rs
tests/ui/consts/const-index-feature-gate.rs
tests/ui/consts/const-int-arithmetic-overflow.rs
tests/ui/consts/const-int-arithmetic.rs
tests/ui/consts/const-int-conversion-rpass.rs
tests/ui/consts/const-int-overflowing-rpass.rs
Expand All @@ -678,6 +688,7 @@ tests/ui/consts/const-repeated-values.rs
tests/ui/consts/const-size_of-align_of.rs
tests/ui/consts/const-size_of_val-align_of_val.rs
tests/ui/consts/const-struct.rs
tests/ui/consts/const-trait-to-trait.rs
tests/ui/consts/const-tuple-struct.rs
tests/ui/consts/const-typeid-of-rpass.rs
tests/ui/consts/const-unit-struct.rs
Expand Down Expand Up @@ -959,6 +970,8 @@ tests/ui/enum/issue-19340-2.rs
tests/ui/enum/issue-23304-1.rs
tests/ui/enum/issue-23304-2.rs
tests/ui/enum/issue-42747.rs
tests/ui/env-macro/env-env-overload.rs
tests/ui/env-macro/env-env.rs
tests/ui/env-macro/option_env-not-defined.rs
tests/ui/errors/remap-path-prefix-macro.rs
tests/ui/explicit-i-suffix.rs
Expand Down Expand Up @@ -998,6 +1011,7 @@ tests/ui/float/classify-runtime-const.rs
tests/ui/float/conv-bits-runtime-const.rs
tests/ui/float/int-to-float-miscompile-issue-105626.rs
tests/ui/fmt/fmt_debug/full.rs
tests/ui/fmt/fmt_debug/none.rs
tests/ui/fmt/fmt_debug/shallow.rs
tests/ui/fmt/format-args-capture-macro-hygiene-pass.rs
tests/ui/fmt/format-args-capture.rs
Expand Down Expand Up @@ -1249,6 +1263,7 @@ tests/ui/issues/issue-10802.rs
tests/ui/issues/issue-10806.rs
tests/ui/issues/issue-11047.rs
tests/ui/issues/issue-11085.rs
tests/ui/issues/issue-11205.rs
tests/ui/issues/issue-11267.rs
tests/ui/issues/issue-11382.rs
tests/ui/issues/issue-11552.rs
Expand Down Expand Up @@ -1647,6 +1662,7 @@ tests/ui/iterators/iter-sum-overflow-debug.rs
tests/ui/iterators/iter-sum-overflow-ndebug.rs
tests/ui/iterators/iter-sum-overflow-overflow-checks.rs
tests/ui/iterators/skip-count-overflow.rs
tests/ui/label/label_break_value_desugared_break.rs
tests/ui/last-use-in-cap-clause.rs
tests/ui/last-use-is-capture.rs
tests/ui/late-bound-lifetimes/issue-36381.rs
Expand Down Expand Up @@ -1742,6 +1758,7 @@ tests/ui/macros/macro-lifetime-used-with-labels.rs
tests/ui/macros/macro-lifetime-used-with-static.rs
tests/ui/macros/macro-lifetime.rs
tests/ui/macros/macro-literal.rs
tests/ui/macros/macro-meta-items.rs
tests/ui/macros/macro-metavar-expr-concat/allowed-operations.rs
tests/ui/macros/macro-metavar-expr-concat/repetitions.rs
tests/ui/macros/macro-metavar-expr-concat/unicode-expansion.rs
Expand Down Expand Up @@ -2271,6 +2288,7 @@ tests/ui/rfcs/rfc-2008-non-exhaustive/structs_same_crate.rs
tests/ui/rfcs/rfc-2008-non-exhaustive/variants_same_crate.rs
tests/ui/rfcs/rfc-2027-dyn-compatible-for-dispatch/manual-self-impl-for-unsafe-obj.rs
tests/ui/rfcs/rfc-2091-track-caller/call-chain.rs
tests/ui/rfcs/rfc-2091-track-caller/caller-location-fnptr-rt-ctfe-equiv.rs
tests/ui/rfcs/rfc-2091-track-caller/caller-location-intrinsic.rs
tests/ui/rfcs/rfc-2091-track-caller/const-caller-location.rs
tests/ui/rfcs/rfc-2091-track-caller/intrinsic-wrapper.rs
Expand Down Expand Up @@ -2308,7 +2326,6 @@ tests/ui/runtime/stdout-before-main.rs
tests/ui/runtime/stdout-during-shutdown-unix.rs
tests/ui/runtime/stdout-during-shutdown-windows.rs
tests/ui/sanitizer/cfi/complex-receiver.rs
tests/ui/sanitizer/cfi/drop-in-place.rs
tests/ui/sanitizer/cfi/fn-ptr.rs
tests/ui/sanitizer/cfi/self-ref.rs
tests/ui/sanitizer/cfi/sized-associated-ty.rs
Expand Down Expand Up @@ -2527,6 +2544,7 @@ tests/ui/syntax-extension-minor.rs
tests/ui/tail-call-arg-leak.rs
tests/ui/tail-cps.rs
tests/ui/test-attrs/test-main-not-dead.rs
tests/ui/test-attrs/test-panic-while-printing.rs
tests/ui/test-attrs/test-runner-hides-main.rs
tests/ui/thread-local/tls.rs
tests/ui/threads-sendsync/child-outlives-parent.rs
Expand Down Expand Up @@ -2602,6 +2620,7 @@ tests/ui/traits/bug-7295.rs
tests/ui/traits/coercion-generic.rs
tests/ui/traits/coercion.rs
tests/ui/traits/conditional-dispatch.rs
tests/ui/traits/const-traits/const-drop.rs
tests/ui/traits/const-traits/specialization/const-default-const-specialized.rs
tests/ui/traits/const-traits/specialization/non-const-default-const-specialized.rs
tests/ui/traits/const-traits/trait-where-clause-run.rs
Expand Down Expand Up @@ -2713,6 +2732,10 @@ tests/ui/traits/with-bounds-default.rs
tests/ui/transmute-non-immediate-to-immediate.rs
tests/ui/transmute/transmute-zst-generics.rs
tests/ui/trivial_casts-rpass.rs
tests/ui/try-block/issue-45124.rs
tests/ui/try-block/try-block-in-match.rs
tests/ui/try-block/try-block-in-return.rs
tests/ui/try-block/try-block.rs
tests/ui/try-block/try-is-identifier-edition2015.rs
tests/ui/try-from-int-error-partial-eq.rs
tests/ui/try-operator-hygiene.rs
Expand Down
Loading