From cbfb88e1a6591092e503118f385b527877cc1475 Mon Sep 17 00:00:00 2001 From: cds-amal Date: Wed, 4 Mar 2026 12:53:01 -0500 Subject: [PATCH 01/13] feat: add pipeline trace instrumentation and visualization Adds TRACE=1-gated instrumentation that emits *.smir.trace.json files, source location tracking for trace events, test programs for reify-fn-pointer and unevaluated-const cases, and presenterm slide decks for trace visualization. Squashed from spike/trace (6 commits); compat-layer commits dropped as already on master via d650c1e. --- .gitignore | 1 + docs/slides/reify-fn-pointer.md | 530 ++ docs/slides/unevaluated-const.md | 611 ++ src/printer/collect.rs | 115 +- src/printer/mir_visitor.rs | 107 +- src/printer/mod.rs | 18 +- src/printer/schema.rs | 4 + src/printer/tracer.rs | 230 + src/printer/ty_visitor.rs | 29 +- .../integration/programs/reify-fn-pointer.rs | 17 + .../reify-fn-pointer.smir.json.expected | 5980 +++++++++++++ .../integration/programs/unevaluated-const.rs | 37 + .../unevaluated-const.smir.json.expected | 7411 +++++++++++++++++ 13 files changed, 15059 insertions(+), 31 deletions(-) create mode 100644 docs/slides/reify-fn-pointer.md create mode 100644 docs/slides/unevaluated-const.md create mode 100644 src/printer/tracer.rs create mode 100644 tests/integration/programs/reify-fn-pointer.rs create mode 100644 tests/integration/programs/reify-fn-pointer.smir.json.expected create mode 100644 tests/integration/programs/unevaluated-const.rs create mode 100644 tests/integration/programs/unevaluated-const.smir.json.expected diff --git a/.gitignore b/.gitignore index 8e0c979c..8e1883e8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ target/ +*.smir.trace.json tests/ui/failing/* tests/ui/passing/* tests/ui/debug/* \ No newline at end of file diff --git a/docs/slides/reify-fn-pointer.md b/docs/slides/reify-fn-pointer.md new file mode 100644 index 00000000..d81bf66d --- /dev/null +++ b/docs/slides/reify-fn-pointer.md @@ -0,0 +1,530 @@ +--- +title: "From Rust Source to SMIR JSON" +author: stable-mir-json +--- + +# From Rust Source to SMIR JSON + +Tracing how stable-mir-json reads a Rust program +and builds its JSON output, step by step. + + + +# Quick glossary + +A few terms that show up repeatedly in the trace: + + + +**MIR** (Mid-level IR): the compiler's intermediate representation. +Think of it as typed assembly with structured control flow. +Each function compiles down to a MIR "body." + + + +**Mono item**: a concrete function after all generics have been +filled in. `Vec::::push` is a mono item; `Vec::::push` +is not. Even non-generic functions like `main` are mono items +(they just have zero type parameters to fill in). + + + +**Allocation**: a chunk of compile-time-known memory: a string +literal, a static variable, a constant value, a vtable. + +**Span**: a region of source code (a file + start/end positions). + + + +# A few more terms + +**Terminator**: MIR splits function bodies into "basic blocks" +(straight-line sequences of instructions). Each block ends with +a terminator: a function call, a return, a branch, or a drop. + +That's why function calls appear under "visit terminator" +in the trace: the call is the last thing in its block. + + + +**Function item vs. function pointer**: In Rust, the name `add` +has a unique zero-sized type (a "function item"). Writing +`let f: fn(i32,i32)->i32 = add` converts that item into a +generic function pointer. The compiler inserts a cast +to do this; the trace calls it a "fn-pointer coercion." + + + +# The program + +```rust +fn add(a: i32, b: i32) -> i32 { + a + b +} + +fn apply(f: fn(i32, i32) -> i32, x: i32, y: i32) -> i32 { + f(x, y) +} + +fn main() { + let f: fn(i32, i32) -> i32 = add; + let result = apply(f, 3, 4); + assert_eq!(result, 7); +} +``` + +Three functions. One function-pointer coercion. One indirect call. +What does stable-mir-json make of this? + + + +# Phase 1: Find all the functions + +The compiler walks the crate and finds every concrete function +that would need to be compiled ("mono items"). + + + +From **our** code: + +``` + add, apply, main +``` + + + +From **the standard library** (pulled in transitively): + +``` + lang_start, lang_start closure, __rust_begin_short_backtrace, + FnOnce::call_once (x2), call_once vtable shim, assert_failed, + drop_in_place<&i32>, drop_in_place, Debug::fmt (x2), + Termination::report +``` + + + +**15 concrete functions total** from a 12-line program. +Most are runtime plumbing you never see in your source. + + + +# Phase 2: Walk each function body + +For each function, the pipeline reads through its MIR body +and records what it finds: + + + +| The pipeline sees... | ...and records | +|---|---| +| A function call | Which function is being called | +| A fn-pointer coercion | The function being converted to a pointer | +| A constant value | Any compile-time memory it references | +| A type | The type and its memory layout | +| A source location | The file/line/col span | + + + +Each finding is logged as a **trace event** with a source +location: the exact range in the original `.rs` file. + +Let's watch what happens when the pipeline walks `main`. + + + + + + + +### Source: `main` + +```rust {10} +fn add(a: i32, b: i32) -> i32 { + a + b +} + +fn apply(f: fn(i32, i32) -> i32, x: i32, y: i32) -> i32 { + f(x, y) +} + +fn main() { + let f: fn(i32, i32) -> i32 = add; + let result = apply(f, 3, 4); + assert_eq!(result, 7); +} +``` + +Line 10: the name `add` has a unique zero-sized +type. Assigning it to a `fn(...)` pointer means +the compiler inserts a **coercion** (a cast from +function item to function pointer). + + + +### Output so far + +```json +{ + "functions": [], + "types": [], + "allocs": [] +} +``` + + + +The pipeline sees the coercion and records `add` +as a function that needs to appear in the output: + +``` + Found fn-pointer coercion: + add -> fn(i32, i32) -> i32 + + add also used as a value + (passed around, not just called) +``` + +```json +{ + "functions": [ + { "name": "add", "via": "fn-pointer" } + ] +} +``` + + + + + + + +### Source: `main` + +```rust {11} +fn add(a: i32, b: i32) -> i32 { + a + b +} + +fn apply(f: fn(i32, i32) -> i32, x: i32, y: i32) -> i32 { + f(x, y) +} + +fn main() { + let f: fn(i32, i32) -> i32 = add; + let result = apply(f, 3, 4); + assert_eq!(result, 7); +} +``` + +Line 11: a direct function call. +The pipeline resolves which concrete function +is being called and adds it to the output. + + + +### Output so far + +```json +{ + "functions": [ + { "name": "add", "via": "fn-pointer" } + ] +} +``` + + + +``` + Found function call: + apply (direct call) + + apply also used as a value +``` + +```json +{ + "functions": [ + { "name": "add", "via": "fn-pointer" }, + { "name": "apply", "via": "call" } + ] +} +``` + + + + + + + +### Source: `main` + +```rust {12} +fn add(a: i32, b: i32) -> i32 { + a + b +} + +fn apply(f: fn(i32, i32) -> i32, x: i32, y: i32) -> i32 { + f(x, y) +} + +fn main() { + let f: fn(i32, i32) -> i32 = add; + let result = apply(f, 3, 4); + assert_eq!(result, 7); +} +``` + +Line 12: `assert_eq!` is a macro. The compiler +expands it into a call to a panic function +(`assert_failed`) plus some compile-time memory +for the comparison operands. + + + +### Output so far + +```json +{ + "functions": [ + { "name": "add", "via": "fn-pointer" }, + { "name": "apply", "via": "call" } + ], + "allocs": [] +} +``` + + + +``` + Found function call: + assert_failed + + Found compile-time memory: + &i32 reference (0 -> 1 allocs) +``` + +```json +{ + "functions": [ + { "name": "add", "via": "fn-ptr" }, + { "name": "apply", "via": "call" }, + { "name": "assert_failed", "via": "call" } + ], + "allocs": [ { "ty": "&i32" } ] +} +``` + + + +# Walking `main`: the tally + +After reading through `main`'s body: + +| What | Before | After | +|---|---|---| +| functions | 0 | 3 | +| allocations | 0 | 1 | +| types | 0 | 39 | +| source spans | 0 | 22 | + + + +39 types from a 12-line function? Most come from `assert_eq!`. +The macro pulls in formatting machinery (`fmt::Arguments`, +`fmt::Formatter`, `Option`, `&str`, `&dyn Debug`, ...) +and the pipeline records every type it touches. + + + + + + + +### Walking `add` + +```rust {1-3} +fn add(a: i32, b: i32) -> i32 { + a + b +} + +fn apply(f: fn(i32, i32) -> i32, x: i32, y: i32) -> i32 { + f(x, y) +} + +fn main() { + let f: fn(i32, i32) -> i32 = add; + let result = apply(f, 3, 4); + assert_eq!(result, 7); +} +``` + +No calls, no allocations. Just `a + b`. + + + +### What the pipeline finds + +``` + Started reading: add +``` + + + +``` + Found type: () + (the empty tuple; every function that + might panic has a diverging path that + "returns" this) + + Found 5 source spans + (the function signature, the body, + the closing brace) +``` + + + +``` + Finished reading: add + new types: +1 + new spans: +5 +``` + +A simple function contributes very little. + + + + + + + +### Walking `apply` + +```rust {5-7} +fn add(a: i32, b: i32) -> i32 { + a + b +} + +fn apply(f: fn(i32, i32) -> i32, x: i32, y: i32) -> i32 { + f(x, y) +} + +fn main() { + let f: fn(i32, i32) -> i32 = add; + let result = apply(f, 3, 4); + assert_eq!(result, 7); +} +``` + +`f(x, y)` calls through a function pointer. +The pipeline sees a call instruction, but the +target is a variable (`f`), not a known function. + +It can't resolve which function will be called +at runtime, so: **no new function recorded.** + + + +### What the pipeline finds + +``` + Started reading: apply +``` + + + +``` + Found 6 source spans + (signature, body, closing brace) +``` + + + +``` + Finished reading: apply + new functions: 0 + new types: 0 + new spans: +6 +``` + +No new functions, no new types. +Everything about `fn(i32,i32)->i32` was +already recorded when we walked `main`. + + + +# Phase 3: Assemble the output + +All 15 function bodies have been read. The pipeline +writes everything it found into the `.smir.json` file. + + + +``` + functions: 16 + allocations: 1 + types: 57 + source spans: 115 +``` + + + +Why 16 functions when there are 15 mono items? +Because `add` was discovered two ways: once as a mono +item, and once through its fn-pointer coercion. Both +paths create an entry. + +57 types and 115 spans come mostly from standard library +code that `assert_eq!` and the runtime entry point pull in. + + + +# The trace file + +Every step we just walked through is recorded in a +trace file. To generate it: + +``` +TRACE=1 cargo run -- -Zno-codegen program.rs +``` + +This produces a `*.smir.trace.json` alongside the +normal output. + + + +Each event in the trace carries three things: + +- **What** happened (found a function call, found a type, ...) +- **Which function body** was being read +- **Where in the source** it happened (file, line, column range) + + + +The source range is what makes the side-by-side +visualization possible: highlight the code on the left, +show the growing output on the right. + + + +# Recap + +``` + Source Phase 1 Phase 2 Phase 3 + find all the read each write the + .rs -------> functions -----> body ----------> .smir.json + (15 found) | | | + | | +- types + | +---- allocations + +------- function calls +``` + + + +A 12-line Rust program produces: +**16 functions, 1 allocation, 57 types, 115 spans.** + +Most of the complexity is invisible: standard library +plumbing, macro expansions, trait method copies. + +The trace makes all of it visible. diff --git a/docs/slides/unevaluated-const.md b/docs/slides/unevaluated-const.md new file mode 100644 index 00000000..07634d81 --- /dev/null +++ b/docs/slides/unevaluated-const.md @@ -0,0 +1,611 @@ +--- +title: "Generics and Constants" +author: stable-mir-json +--- + +# Generics and Constants + +How the pipeline handles generic functions, +trait-associated constants, and const generic parameters. + + + +# Quick glossary + + + +**Monomorphization**: the compiler's process of turning generic +code into concrete code. If you write `fn foo` and call it +with `i32` and `String`, the compiler produces two separate +copies: `foo::` and `foo::`. Each copy is a +"mono item" (see the previous deck). + + + +**Associated constant**: a constant defined inside a trait impl. + +```rust +trait Stride { const STEP: usize; } +impl Stride for By2 { const STEP: usize = 2; } +``` + +`By2::STEP` is an associated constant with value `2`. + + + +**Const generic**: a generic parameter that's a value, not a type. + +```rust +fn make_array() -> [u8; N] +``` + +`N` is filled in at compile time: `make_array::<4>()`. + + + +# The program + +```rust +trait Stride { + const STEP: usize; +} + +struct By2; +impl Stride for By2 { + const STEP: usize = 2; +} + +struct By3; +impl Stride for By3 { + const STEP: usize = 3; +} + +fn advance(pos: usize) -> usize { + pos + S::STEP +} + +fn make_array() -> [u8; N] { + [0u8; N] +} + +fn main() { + let a = advance::(0); + let b = advance::(10); + assert_eq!(a, 2); + assert_eq!(b, 13); + + let arr = make_array::<4>(); + assert_eq!(arr.len(), 4); +} +``` + + + +# Phase 1: Find all the functions + +The compiler finds **16 concrete functions**. +The interesting part: generics get split. + + + +From **our** code: + +``` + advance:: one copy for By2 + advance:: another copy for By3 + make_array::<4> N filled in with 4 + main +``` + + + +One generic function `advance` produced two mono items. +The compiler literally duplicated the function body, once +for each concrete type it was called with. + +`make_array` also got its own concrete copy +with `N = 4`. + + + +# What happened to `S::STEP`? + +In the source, `advance` reads a trait constant: + +```rust +fn advance(pos: usize) -> usize { + pos + S::STEP +} +``` + + + +You might expect the pipeline to see "unevaluated constant: +`S::STEP`" and then resolve it. But by the time we see the +MIR, the compiler has **already done the math**. + + + +In the concrete body of `advance::`, `S::STEP` is +just the number `3`: eight bytes of memory holding the +value `[3, 0, 0, 0, 0, 0, 0, 0]`. + +There is nothing left to evaluate. The pipeline never +encounters an "unevaluated constant" event for this +program. + + + + + + + +### Reading `advance::` + +```rust {15-17} +trait Stride { + const STEP: usize; +} + +struct By2; +impl Stride for By2 { + const STEP: usize = 2; +} + +struct By3; +impl Stride for By3 { + const STEP: usize = 3; +} + +fn advance(pos: usize) -> usize { + pos + S::STEP +} + +fn make_array() -> [u8; N] { + [0u8; N] +} + +fn main() { + let a = advance::(0); + let b = advance::(10); + assert_eq!(a, 2); + assert_eq!(b, 13); + + let arr = make_array::<4>(); + assert_eq!(arr.len(), 4); +} +``` + +Line 16: `pos + S::STEP` + +`S::STEP` is already the number `3` +in this concrete copy of the function. + + + +### What the pipeline finds + +``` + Started reading: advance:: + types: 47, allocs: 0 +``` + + + +``` + Found constant value: usize + (this is the "3"; no pointers in it, + so alloc count stays at 0) + + Found constant value: usize + (the overflow check comparison) + + Found type: bool + (the overflow check result) + + Found type: () + (the "return nothing" type for the + panic path if overflow happens) +``` + + + +``` + Finished reading: advance:: + new types: +2 + new allocs: 0 + new spans: +5 +``` + +No function calls here; just arithmetic. + + + + + + + +### Reading `advance::` + +```rust {15-17} +trait Stride { + const STEP: usize; +} + +struct By2; +impl Stride for By2 { + const STEP: usize = 2; +} + +struct By3; +impl Stride for By3 { + const STEP: usize = 3; +} + +fn advance(pos: usize) -> usize { + pos + S::STEP +} + +fn make_array() -> [u8; N] { + [0u8; N] +} + +fn main() { + let a = advance::(0); + let b = advance::(10); + assert_eq!(a, 2); + assert_eq!(b, 13); + + let arr = make_array::<4>(); + assert_eq!(arr.len(), 4); +} +``` + +Same function body, different constant value. +`S::STEP` is `2` instead of `3`. + + + +### What the pipeline finds + +``` + Started reading: advance:: + types: 55, allocs: 0 +``` + + + +``` + Found constant value: usize + Found constant value: usize +``` + + + +``` + Finished reading: advance:: + new types: 0 + new allocs: 0 + new spans: 0 +``` + +**Zero new types, zero new spans.** + +The By3 copy already recorded `bool`, `()`, +`usize`, and all the source locations for this +function body. Since both copies share the same +source code, the second one adds nothing new. + +This is deduplication at work: the pipeline +records each type and span only once. + + + + + + + +### Reading `main`: the calls + +```rust {24-26} +trait Stride { + const STEP: usize; +} + +struct By2; +impl Stride for By2 { + const STEP: usize = 2; +} + +struct By3; +impl Stride for By3 { + const STEP: usize = 3; +} + +fn advance(pos: usize) -> usize { + pos + S::STEP +} + +fn make_array() -> [u8; N] { + [0u8; N] +} + +fn main() { + let a = advance::(0); + let b = advance::(10); + assert_eq!(a, 2); + assert_eq!(b, 13); + + let arr = make_array::<4>(); + assert_eq!(arr.len(), 4); +} +``` + +Two calls to `advance`, each with a different +type argument. By now the compiler has already +resolved each to a separate concrete function. + + + +### What the pipeline finds + +``` + Started reading: main + functions: 13, types: 56 +``` + + + +``` + Found function call: (line 25) + advance:: + + Found constant value: usize + (the argument 0) +``` + + + +``` + Found function call: (line 26) + advance:: + + Found constant value: usize + (the argument 10) +``` + +The two calls look the same in structure +but resolve to different concrete functions. + + + + + + + +### Reading `main`: the const generic + +```rust {30} +trait Stride { + const STEP: usize; +} + +struct By2; +impl Stride for By2 { + const STEP: usize = 2; +} + +struct By3; +impl Stride for By3 { + const STEP: usize = 3; +} + +fn advance(pos: usize) -> usize { + pos + S::STEP +} + +fn make_array() -> [u8; N] { + [0u8; N] +} + +fn main() { + let a = advance::(0); + let b = advance::(10); + assert_eq!(a, 2); + assert_eq!(b, 13); + + let arr = make_array::<4>(); + assert_eq!(arr.len(), 4); +} +``` + +`make_array::<4>()`: the const generic `N = 4` +shows up as an already-computed value in the +function's type information. + + + +### The const generic in the trace + +``` + Found function call: (line 35) + make_array::<4> +``` + +The function's generic arguments show `N` +as an already-evaluated value: + +``` + GenericArgs([ + Const(Value( + type: usize, + bytes: [4, 0, 0, 0, ...] + )) + ]) +``` + +No symbolic "N" left; just the number 4 +stored as eight bytes. + + + +``` + Found type: [u8; 4] + (a concrete array type; + the const generic made it concrete) +``` + + + + + + + +### Reading `make_array::<4>` + +```rust {19-21} +trait Stride { + const STEP: usize; +} + +struct By2; +impl Stride for By2 { + const STEP: usize = 2; +} + +struct By3; +impl Stride for By3 { + const STEP: usize = 3; +} + +fn advance(pos: usize) -> usize { + pos + S::STEP +} + +fn make_array() -> [u8; N] { + [0u8; N] +} + +fn main() { + let a = advance::(0); + let b = advance::(10); + assert_eq!(a, 2); + assert_eq!(b, 13); + + let arr = make_array::<4>(); + assert_eq!(arr.len(), 4); +} +``` + +`[0u8; N]` where `N = 4`. + + + +### What the pipeline finds + +``` + Started reading: make_array::<4> + types: 61, allocs: 3 +``` + + + +``` + Found constant value: u8 (line 26) + (the repeat value 0u8) +``` + + + +``` + Finished reading: make_array::<4> + new types: 0 + new allocs: 0 + new spans: +4 +``` + +Nothing new except source locations. The `u8` +and `[u8; 4]` types were already recorded when +we read `main` (which references the return type). + + + +# Phase 3: Assemble the output + +All 16 function bodies have been read. + +``` + functions: 17 + allocations: 3 + types: 61 + source spans: 145 +``` + + + +3 allocations: all from `assert_eq!` macro expansions, +which create compile-time `&usize` references for +comparing values. + +The trait constants (`S::STEP = 2`, `S::STEP = 3`) +showed up as constant values in the MIR, but they +had no pointer content, so they didn't produce +tracked allocations. + + + +# The constants story + +``` + In your source What the pipeline sees + --------------------- ------------------------- + + S::STEP the literal number 3 + (associated constant) (already evaluated) + + make_array::<4> GenericArgs([Value(4)]) + (const generic param) (already evaluated) + + [0u8; N] [0u8; 4] + (const in expression) (already concrete) +``` + + + +All three patterns are resolved by the compiler **before** +the pipeline ever sees them. The code has a path for +handling "unevaluated constants" (constants the compiler +hasn't computed yet), but it was never triggered here. + + + +The trace confirms this: zero "unevaluated constant +discovered" events in the entire output. + + + +# Recap + +What the compiler does to generic code before the pipeline sees it: + + + +**1. Makes separate copies for each concrete use** +`advance` becomes `advance::` and `advance::`, +each with its own function body. + + + +**2. Evaluates all constants ahead of time** +`S::STEP` becomes a literal number in memory. +`const N: usize` becomes the value `4` in the generic args. + + + +**3. Shares what it can** +The second `advance` copy contributes zero new types or +source spans; only the first copy pays the cost. + + + +The trace makes all of this visible. diff --git a/src/printer/collect.rs b/src/printer/collect.rs index c8089e6e..228e0680 100644 --- a/src/printer/collect.rs +++ b/src/printer/collect.rs @@ -28,6 +28,7 @@ use super::schema::{ AllocInfo, AllocMap, CollectedCrate, DerivedInfo, Item, LinkMap, SmirJson, SmirJsonDebugInfo, SpanMap, }; +use super::tracer::{CollectionSnapshot, TraceEvent, Tracer}; use super::ty_visitor::TyCollector; use super::types::mk_type_metadata; use super::util::take_any; @@ -53,13 +54,19 @@ fn warn_missing_body(mono_item: &MonoItem) { } } -fn collect_items(tcx: TyCtxt<'_>) -> HashMap { +fn collect_items(tcx: TyCtxt<'_>, tracer: &mut Option) -> HashMap { // get initial set of mono_items let items = mono_collect(tcx); items .iter() .map(|item| { let name = mono_item_name(tcx, item); + if let Some(tracer) = tracer { + tracer.push(TraceEvent::ItemDiscovered { + name: name.clone(), + source: "mono_collect", + }); + } let (mono_item, built_item) = mk_item(tcx, item.clone(), name.clone()); (name, (mono_item, built_item)) }) @@ -75,12 +82,19 @@ fn enqueue_unevaluated_consts( known_names: &mut HashSet, pending: &mut HashMap, unevaluated_consts: &mut HashMap, + tracer: &mut Option, ) { for info in discovered { if known_names.contains(&info.item_name) || pending.contains_key(&info.item_name) { continue; } debug_log_println!("Adding unevaluated const body for: {}", info.item_name); + if let Some(tracer) = tracer { + tracer.push(TraceEvent::ItemDiscovered { + name: info.item_name.clone(), + source: "unevaluated_const", + }); + } unevaluated_consts.insert(info.const_def, info.item_name.clone()); let new_entry = mk_item(tcx, info.mono_item, info.item_name.clone()); pending.insert(info.item_name.clone(), new_entry); @@ -88,6 +102,20 @@ fn enqueue_unevaluated_consts( } } +fn snapshot( + calls_map: &LinkMap, + visited_allocs: &AllocMap, + ty_visitor: &TyCollector<'_>, + span_map: &SpanMap, +) -> CollectionSnapshot { + CollectionSnapshot { + link_map_count: calls_map.len(), + alloc_count: visited_allocs.len(), + type_count: ty_visitor.types.len(), + span_count: span_map.len(), + } +} + /// Collect all mono items and analyze their bodies in a single pass per body. /// /// Each body is walked exactly once. The fixpoint loop handles transitive @@ -99,10 +127,12 @@ fn enqueue_unevaluated_consts( fn collect_and_analyze_items( tcx: TyCtxt<'_>, initial_items: HashMap, + tracer: &mut Option, ) -> (CollectedCrate, DerivedInfo) { + let trace = tracer.is_some(); let mut calls_map: LinkMap = HashMap::new(); let mut visited_allocs = AllocMap::new(); - let mut ty_visitor = TyCollector::new(tcx); + let mut ty_visitor = TyCollector::new(tcx, trace); let mut span_map: SpanMap = HashMap::new(); let mut unevaluated_consts: HashMap = HashMap::new(); @@ -119,17 +149,41 @@ fn collect_and_analyze_items( continue; }; + // Emit BodyWalkStarted before creating the BodyAnalyzer (borrow scoping). + if let Some(tracer) = tracer.as_mut() { + let before = snapshot(&calls_map, &visited_allocs, &ty_visitor, &span_map); + tracer.current_item = Some(item.symbol_name.clone()); + tracer.push(TraceEvent::BodyWalkStarted { + item: item.symbol_name.clone(), + before, + }); + } + let mut new_unevaluated = Vec::new(); - BodyAnalyzer { - tcx, - locals, - link_map: &mut calls_map, - visited_allocs: &mut visited_allocs, - ty_visitor: &mut ty_visitor, - spans: &mut span_map, - new_unevaluated: &mut new_unevaluated, + { + let analyzer_tracer = tracer.as_mut(); + BodyAnalyzer { + tcx, + locals, + link_map: &mut calls_map, + visited_allocs: &mut visited_allocs, + ty_visitor: &mut ty_visitor, + spans: &mut span_map, + new_unevaluated: &mut new_unevaluated, + tracer: analyzer_tracer, + } + .visit_body(body); + } + + // Emit BodyWalkFinished after the BodyAnalyzer is dropped. + if let Some(tracer) = tracer.as_mut() { + let after = snapshot(&calls_map, &visited_allocs, &ty_visitor, &span_map); + tracer.push(TraceEvent::BodyWalkFinished { + item: item.symbol_name.clone(), + after, + }); + tracer.current_item = None; } - .visit_body(body); enqueue_unevaluated_consts( tcx, @@ -137,6 +191,7 @@ fn collect_and_analyze_items( &mut known_names, &mut pending, &mut unevaluated_consts, + tracer, ); all_items.push(item); @@ -197,7 +252,12 @@ fn alloc_bytes(info: &AllocInfo) -> &[Option] { /// Phase 3: Assemble the final SmirJson from collected and derived data. /// This is a pure data transformation with no inst.body() calls. -fn assemble_smir(tcx: TyCtxt<'_>, collected: CollectedCrate, derived: DerivedInfo) -> SmirJson { +fn assemble_smir( + tcx: TyCtxt<'_>, + collected: CollectedCrate, + derived: DerivedInfo, + tracer: &mut Option, +) -> SmirJson { let local_crate = stable_mir::local_crate(); let CollectedCrate { mut items, @@ -210,6 +270,16 @@ fn assemble_smir(tcx: TyCtxt<'_>, collected: CollectedCrate, derived: DerivedInf spans: span_map, } = derived; + if let Some(tracer) = tracer { + tracer.push(TraceEvent::AssemblyStarted { + total_items: items.len(), + total_functions: calls.len(), + total_allocs: visited_allocs.len(), + total_types: visited_tys.len(), + total_spans: span_map.len(), + }); + } + // Verify alloc coherence: no duplicate AllocIds, and every AllocId // referenced in a stored body was actually collected. #[cfg(debug_assertions)] @@ -291,13 +361,26 @@ fn assemble_smir(tcx: TyCtxt<'_>, collected: CollectedCrate, derived: DerivedInf } } -pub fn collect_smir(tcx: TyCtxt<'_>) -> SmirJson { +/// Internal entry point that returns both the SmirJson and optional trace events. +pub(super) fn collect_smir_traced(tcx: TyCtxt<'_>) -> (SmirJson, Option>) { + let mut tracer = if super::trace_enabled() { + Some(Tracer::new()) + } else { + None + }; + // Phase 1+2: Collect all mono items from rustc and analyze their bodies // in a single pass. Each body is walked exactly once. Transitive item // discovery (unevaluated constants) is handled by a fixpoint loop. - let initial_items = collect_items(tcx); - let (collected, derived) = collect_and_analyze_items(tcx, initial_items); + let initial_items = collect_items(tcx, &mut tracer); + let (collected, derived) = collect_and_analyze_items(tcx, initial_items, &mut tracer); // Phase 3: Assemble the final output (pure data transformation) - assemble_smir(tcx, collected, derived) + let smir = assemble_smir(tcx, collected, derived, &mut tracer); + let trace_events = tracer.map(|t| t.events); + (smir, trace_events) +} + +pub fn collect_smir(tcx: TyCtxt<'_>) -> SmirJson { + collect_smir_traced(tcx).0 } diff --git a/src/printer/mir_visitor.rs b/src/printer/mir_visitor.rs index 2989a084..aff58d7d 100644 --- a/src/printer/mir_visitor.rs +++ b/src/printer/mir_visitor.rs @@ -26,6 +26,7 @@ use stable_mir::CrateDef; use super::link_map::{fn_inst_sym, update_link_map}; use super::schema::{AllocMap, ItemSource, LinkMap, SpanMap, FPTR, ITEM, TERM}; +use super::tracer::{resolve_location, sym_kind_str, sym_name, TraceEvent, Tracer}; use super::ty_visitor::TyCollector; use super::util::fn_inst_for_ty; @@ -45,6 +46,8 @@ pub(super) struct BodyAnalyzer<'tcx, 'local> { /// Unevaluated constants discovered during this body walk. /// The outer fixpoint loop uses these to discover and create new Items. pub new_unevaluated: &'local mut Vec, + /// When tracing is enabled, events are pushed here during body analysis. + pub tracer: Option<&'local mut Tracer>, } /// Information about an unevaluated constant discovered during body analysis. @@ -304,36 +307,68 @@ fn collect_alloc( impl MirVisitor for BodyAnalyzer<'_, '_> { fn visit_span(&mut self, span: &stable_mir::ty::Span) { - self.spans.insert( - span.to_index(), - crate::compat::spans::resolve_span(self.tcx, span), - ); + let is_new = !self.spans.contains_key(&span.to_index()); + let resolved = crate::compat::spans::resolve_span(self.tcx, span); + if is_new { + if let Some(tracer) = &mut self.tracer { + tracer.push(TraceEvent::SpanResolved { + item: tracer.item_name(), + file: resolved.0.clone(), + line: resolved.1, + }); + } + } + self.spans.insert(span.to_index(), resolved); } fn visit_terminator(&mut self, term: &Terminator, loc: stable_mir::mir::visit::Location) { use stable_mir::mir::{ConstOperand, Operand::Constant}; use TerminatorKind::*; - let fn_sym = match &term.kind { + let (fn_sym, is_drop, trace_ty_str) = match &term.kind { Call { func: Constant(ConstOperand { const_: cnst, .. }), args: _, .. } => { if *cnst.kind() != stable_mir::ty::ConstantKind::ZeroSized { - None + (None, false, String::new()) } else { let inst = fn_inst_for_ty(cnst.ty(), true) .expect("Direct calls to functions must resolve to an instance"); - fn_inst_sym(self.tcx, Some(cnst.ty()), Some(&inst)) + let sym = fn_inst_sym(self.tcx, Some(cnst.ty()), Some(&inst)); + let ty_str = format!("{:?}", cnst.ty().kind()); + (sym, false, ty_str) } } Drop { place, .. } => { let drop_ty = place.ty(self.locals).unwrap(); let inst = Instance::resolve_drop_in_place(drop_ty); - fn_inst_sym(self.tcx, None, Some(&inst)) + let sym = fn_inst_sym(self.tcx, None, Some(&inst)); + let ty_str = format!("{:?}", drop_ty.kind()); + (sym, true, ty_str) } - _ => None, + _ => (None, false, String::new()), }; + if let (Some(tracer), Some((_, _, ref sym))) = (&mut self.tracer, &fn_sym) { + let src_loc = resolve_location(self.tcx, &loc); + if is_drop { + tracer.push(TraceEvent::DropGlueResolved { + item: tracer.item_name(), + location: src_loc, + drop_ty: trace_ty_str.clone(), + sym_kind: sym_kind_str(sym), + sym_name: sym_name(sym).to_string(), + }); + } else { + tracer.push(TraceEvent::FunctionCallResolved { + item: tracer.item_name(), + location: src_loc, + callee_ty: trace_ty_str.clone(), + sym_kind: sym_kind_str(sym), + sym_name: sym_name(sym).to_string(), + }); + } + } update_link_map(self.link_map, fn_sym, ItemSource(TERM)); self.super_terminator(term, loc); } @@ -347,6 +382,15 @@ impl MirVisitor for BodyAnalyzer<'_, '_> { let inst = fn_inst_for_ty(op.ty(self.locals).unwrap(), false) .expect("ReifyFnPointer Cast operand type does not resolve to an instance"); let fn_sym = fn_inst_sym(self.tcx, None, Some(&inst)); + if let (Some(tracer), Some((_, _, ref sym))) = (&mut self.tracer, &fn_sym) { + tracer.push(TraceEvent::ReifyFnPointerResolved { + item: tracer.item_name(), + location: resolve_location(self.tcx, &loc), + fn_ty: format!("{:?}", op.ty(self.locals).unwrap().kind()), + sym_kind: sym_kind_str(sym), + sym_name: sym_name(sym).to_string(), + }); + } update_link_map(self.link_map, fn_sym, ItemSource(FPTR)); } _ => {} @@ -367,11 +411,21 @@ impl MirVisitor for BodyAnalyzer<'_, '_> { alloc, constant.ty().kind() ); + let allocs_before = self.visited_allocs.len(); alloc .provenance .ptrs .iter() .for_each(|(offset, prov)| collect_alloc(self, constant.ty(), *offset, prov.0)); + if let Some(tracer) = &mut self.tracer { + tracer.push(TraceEvent::AllocationCollected { + item: tracer.item_name(), + location: resolve_location(self.tcx, &loc), + alloc_ty: format!("{:?}", constant.ty().kind()), + allocs_before, + allocs_after: self.visited_allocs.len(), + }); + } } ConstantKind::Ty(ty_const) => { if let TyConstKind::Value(..) = ty_const.kind() { @@ -384,6 +438,13 @@ impl MirVisitor for BodyAnalyzer<'_, '_> { // Ensure such functions are included in the link map so they appear in the // `functions` array of the SMIR JSON. if constant.ty().kind().fn_def().is_some() { + if let Some(tracer) = &mut self.tracer { + tracer.push(TraceEvent::FnDefAsValue { + item: tracer.item_name(), + location: resolve_location(self.tcx, &loc), + fn_ty: format!("{:?}", constant.ty().kind()), + }); + } if let Some(inst) = fn_inst_for_ty(constant.ty(), false) .or_else(|| fn_inst_for_ty(constant.ty(), true)) { @@ -404,6 +465,13 @@ impl MirVisitor for BodyAnalyzer<'_, '_> { uconst.def.def_id(), uconst.args.clone(), ); + if let Some(tracer) = &mut self.tracer { + tracer.push(TraceEvent::UnevaluatedConstDiscovered { + item: tracer.item_name(), + location: resolve_location(self.tcx, &loc), + const_name: item_name.clone(), + }); + } self.new_unevaluated.push(UnevalConstInfo { const_def: uconst.def, item_name, @@ -415,8 +483,27 @@ impl MirVisitor for BodyAnalyzer<'_, '_> { self.super_mir_const(constant, loc); } - fn visit_ty(&mut self, ty: &stable_mir::ty::Ty, _location: stable_mir::mir::visit::Location) { + fn visit_ty(&mut self, ty: &stable_mir::ty::Ty, location: stable_mir::mir::visit::Location) { ty.visit(self.ty_visitor); + // Drain type trace events from TyCollector into the main tracer, + // stamping each with the current item context and source location. + if let Some(tracer) = &mut self.tracer { + if let Some(buf) = &mut self.ty_visitor.trace_buffer { + let src_loc = resolve_location(self.tcx, &location); + for mut ev in buf.drain(..) { + if let TraceEvent::TypeCollected { + ref mut item, + ref mut location, + .. + } = ev + { + *item = tracer.item_name(); + *location = Some(src_loc.clone()); + } + tracer.push(ev); + } + } + } self.super_ty(ty); } } diff --git a/src/printer/mod.rs b/src/printer/mod.rs index f251e27f..acba06f2 100644 --- a/src/printer/mod.rs +++ b/src/printer/mod.rs @@ -37,6 +37,7 @@ macro_rules! def_env_var { def_env_var!(debug_enabled, DEBUG); def_env_var!(link_items_enabled, LINK_ITEMS); def_env_var!(link_instance_enabled, LINK_INST); +def_env_var!(trace_enabled, TRACE); macro_rules! debug_log_println { ($($args:tt)*) => { @@ -50,6 +51,7 @@ mod items; mod link_map; mod mir_visitor; mod schema; +mod tracer; mod ty_visitor; mod types; mod util; @@ -61,12 +63,13 @@ pub use schema::{AllocInfo, FnSymType, Item, LinkMapKey, SmirJson, TypeMetadata} pub(crate) use util::hash; pub fn emit_smir(tcx: TyCtxt<'_>) { - let smir_json = - serde_json::to_string(&collect_smir(tcx)).expect("serde_json failed to write result"); + let (smir, trace_events) = collect::collect_smir_traced(tcx); + let smir_json = serde_json::to_string(&smir).expect("serde_json failed to write result"); match crate::compat::output::mir_output_path(tcx, "smir.json") { crate::compat::output::OutputDest::Stdout => { write!(&io::stdout(), "{}", smir_json).expect("Failed to write smir.json"); + // Skip trace output when destination is stdout. } crate::compat::output::OutputDest::File(path) => { let mut b = io::BufWriter::new( @@ -74,6 +77,17 @@ pub fn emit_smir(tcx: TyCtxt<'_>) { .unwrap_or_else(|e| panic!("Failed to create {}: {}", path.display(), e)), ); write!(b, "{}", smir_json).expect("Failed to write smir.json"); + + // Write trace file alongside the main output when TRACE is enabled. + if let Some(events) = trace_events { + let trace_path = path.with_extension("trace.json"); + let trace_json = serde_json::to_string_pretty(&events) + .expect("serde_json failed to write trace"); + let mut tb = io::BufWriter::new(File::create(&trace_path).unwrap_or_else(|e| { + panic!("Failed to create {}: {}", trace_path.display(), e) + })); + write!(tb, "{}", trace_json).expect("Failed to write smir.trace.json"); + } } } } diff --git a/src/printer/schema.rs b/src/printer/schema.rs index d75da9ba..9db64bb2 100644 --- a/src/printer/schema.rs +++ b/src/printer/schema.rs @@ -76,6 +76,10 @@ impl AllocMap { self.inner.insert(key, value); } + pub fn len(&self) -> usize { + self.inner.len() + } + pub fn into_entries( self, ) -> impl Iterator< diff --git a/src/printer/tracer.rs b/src/printer/tracer.rs new file mode 100644 index 00000000..e2bb5dd3 --- /dev/null +++ b/src/printer/tracer.rs @@ -0,0 +1,230 @@ +//! Pipeline trace instrumentation. +//! +//! When `TRACE=1` is set, the pipeline emits a `*.smir.trace.json` file +//! capturing the complete story of how each entry ended up in the output: +//! which item's body was being analyzed, which callback fired, what it +//! received, and what it produced. +//! +//! The trace is a flat, chronological list of [`TraceEvent`] values, one per +//! observable pipeline step. Events carry domain-language payloads (item +//! names, type tags, symbol kinds) rather than raw compiler ids, so they're +//! readable without knowing stable MIR internals. + +use crate::compat::middle::ty::TyCtxt; +use crate::compat::serde; +use crate::compat::stable_mir; + +use serde::Serialize; + +use stable_mir::ty::TyKind; + +use super::schema::FnSymType; + +/// Source range of the MIR statement that triggered a trace event. +/// +/// Carries both endpoints so a visualization tool (e.g. presenterm) can +/// highlight the exact source region associated with each event. +#[derive(Serialize, Clone)] +pub(super) struct SourceLocation { + pub file: String, + pub line: usize, + pub col: usize, + pub end_line: usize, + pub end_col: usize, +} + +/// Resolve a MIR visitor `Location` to a `SourceLocation` via the compiler's source map. +pub(super) fn resolve_location( + tcx: TyCtxt<'_>, + loc: &stable_mir::mir::visit::Location, +) -> SourceLocation { + let (file, line, col, end_line, end_col) = crate::compat::spans::resolve_span(tcx, &loc.span()); + SourceLocation { + file, + line, + col, + end_line, + end_col, + } +} + +/// Snapshot of collection sizes, used for before/after deltas. +#[derive(Clone, Serialize)] +pub(super) struct CollectionSnapshot { + pub link_map_count: usize, + pub alloc_count: usize, + pub type_count: usize, + pub span_count: usize, +} + +/// A single observable pipeline step. +#[derive(Serialize)] +#[serde(tag = "event")] +pub(super) enum TraceEvent { + /// Phase 1: a monomorphized item was discovered. + ItemDiscovered { name: String, source: &'static str }, + + /// Phase 2 bookend: beginning body analysis for an item. + BodyWalkStarted { + item: String, + before: CollectionSnapshot, + }, + + /// Phase 2 bookend: finished body analysis for an item. + BodyWalkFinished { + item: String, + after: CollectionSnapshot, + }, + + /// visit_terminator: resolved a Call terminator to a function instance. + FunctionCallResolved { + item: String, + location: SourceLocation, + callee_ty: String, + sym_kind: &'static str, + sym_name: String, + }, + + /// visit_terminator: resolved a Drop terminator to drop glue. + DropGlueResolved { + item: String, + location: SourceLocation, + drop_ty: String, + sym_kind: &'static str, + sym_name: String, + }, + + /// visit_rvalue: detected a ReifyFnPointer cast. + ReifyFnPointerResolved { + item: String, + location: SourceLocation, + fn_ty: String, + sym_kind: &'static str, + sym_name: String, + }, + + /// visit_mir_const: walked an Allocated constant's provenance. + AllocationCollected { + item: String, + location: SourceLocation, + alloc_ty: String, + allocs_before: usize, + allocs_after: usize, + }, + + /// visit_mir_const: a ZeroSized FnDef used as a value. + FnDefAsValue { + item: String, + location: SourceLocation, + fn_ty: String, + }, + + /// visit_mir_const: an unevaluated constant was discovered. + UnevaluatedConstDiscovered { + item: String, + location: SourceLocation, + const_name: String, + }, + + /// visit_ty (via TyCollector): a type was collected. + TypeCollected { + item: String, + location: Option, + ty_kind: String, + }, + + /// visit_span: a new span was resolved. + SpanResolved { + item: String, + file: String, + line: usize, + }, + + /// Phase 3: assembly started (summary). + AssemblyStarted { + total_items: usize, + total_functions: usize, + total_allocs: usize, + total_types: usize, + total_spans: usize, + }, +} + +/// Accumulates trace events during the pipeline. +pub(super) struct Tracer { + pub events: Vec, + pub current_item: Option, +} + +impl Tracer { + pub fn new() -> Self { + Tracer { + events: Vec::new(), + current_item: None, + } + } + + pub fn push(&mut self, event: TraceEvent) { + self.events.push(event); + } + + /// The current item name, or a fallback for events outside a body walk. + pub fn item_name(&self) -> String { + self.current_item + .clone() + .unwrap_or_else(|| "".to_string()) + } +} + +/// Short tag for a TyKind (e.g. "Adt", "FnDef", "Ref"). +pub(super) fn ty_kind_tag(kind: &TyKind) -> &'static str { + match kind { + TyKind::RigidTy(rigid) => rigid_ty_tag(rigid), + TyKind::Alias(..) => "Alias", + TyKind::Param(..) => "Param", + TyKind::Bound(..) => "Bound", + } +} + +fn rigid_ty_tag(ty: &stable_mir::ty::RigidTy) -> &'static str { + use stable_mir::ty::RigidTy::*; + match ty { + Bool => "Bool", + Char => "Char", + Int(_) => "Int", + Uint(_) => "Uint", + Float(_) => "Float", + Adt(..) => "Adt", + Foreign(_) => "Foreign", + Str => "Str", + Array(..) => "Array", + Slice(_) => "Slice", + RawPtr(..) => "RawPtr", + Ref(..) => "Ref", + FnDef(..) => "FnDef", + FnPtr(..) => "FnPtr", + Closure(..) => "Closure", + Coroutine(..) => "Coroutine", + Dynamic(..) => "Dynamic", + Never => "Never", + Tuple(_) => "Tuple", + CoroutineWitness(..) => "CoroutineWitness", + Pat(..) => "Pat", + } +} + +/// Classify a FnSymType into a short tag. +pub(super) fn sym_kind_str(sym: &FnSymType) -> &'static str { + match sym { + FnSymType::NoOpSym(_) => "no_op", + FnSymType::IntrinsicSym(_) => "intrinsic", + FnSymType::NormalSym(_) => "normal", + } +} + +/// Extract the name string from a FnSymType. +pub(super) fn sym_name(sym: &FnSymType) -> &str { + match sym { + FnSymType::NoOpSym(s) | FnSymType::IntrinsicSym(s) | FnSymType::NormalSym(s) => s, + } +} diff --git a/src/printer/ty_visitor.rs b/src/printer/ty_visitor.rs index bb375871..632f6241 100644 --- a/src/printer/ty_visitor.rs +++ b/src/printer/ty_visitor.rs @@ -19,19 +19,26 @@ use stable_mir::ty::{RigidTy, TyKind}; use stable_mir::visitor::{Visitable, Visitor}; use super::schema::TyMap; +use super::tracer::{ty_kind_tag, TraceEvent}; pub(super) struct TyCollector<'tcx> { tcx: TyCtxt<'tcx>, pub types: TyMap, resolved: HashSet, + /// When tracing is enabled, newly collected types are buffered here. + /// The caller (BodyAnalyzer::visit_ty) drains this buffer after each + /// ty.visit() call and copies events into the main Tracer with the + /// correct item context. This sidesteps the double-&mut problem. + pub trace_buffer: Option>, } impl TyCollector<'_> { - pub fn new(tcx: TyCtxt<'_>) -> TyCollector { + pub fn new(tcx: TyCtxt<'_>, trace: bool) -> TyCollector { TyCollector { tcx, types: HashMap::new(), resolved: HashSet::new(), + trace_buffer: if trace { Some(Vec::new()) } else { None }, } } } @@ -97,8 +104,16 @@ impl Visitor for TyCollector<'_> { let control = ty.super_visit(self); if matches!(control, ControlFlow::Continue(_)) { + let kind = ty.kind(); let maybe_layout_shape = ty.layout().ok().map(|layout| layout.shape()); - self.types.insert(*ty, (ty.kind(), maybe_layout_shape)); + if let Some(buf) = &mut self.trace_buffer { + buf.push(TraceEvent::TypeCollected { + item: String::new(), // filled by caller + location: None, // filled by caller + ty_kind: ty_kind_tag(&kind).to_string(), + }); + } + self.types.insert(*ty, (kind, maybe_layout_shape)); fields.super_visit(self) } else { control @@ -108,8 +123,16 @@ impl Visitor for TyCollector<'_> { let control = ty.super_visit(self); match control { ControlFlow::Continue(_) => { + let kind = ty.kind(); let maybe_layout_shape = ty.layout().ok().map(|layout| layout.shape()); - self.types.insert(*ty, (ty.kind(), maybe_layout_shape)); + if let Some(buf) = &mut self.trace_buffer { + buf.push(TraceEvent::TypeCollected { + item: String::new(), // filled by caller + location: None, // filled by caller + ty_kind: ty_kind_tag(&kind).to_string(), + }); + } + self.types.insert(*ty, (kind, maybe_layout_shape)); control } _ => control, diff --git a/tests/integration/programs/reify-fn-pointer.rs b/tests/integration/programs/reify-fn-pointer.rs new file mode 100644 index 00000000..9373db74 --- /dev/null +++ b/tests/integration/programs/reify-fn-pointer.rs @@ -0,0 +1,17 @@ +/// Exercises ReifyFnPointer casts: coercing a function item +/// (which has a unique zero-sized type) into a function pointer. +fn add(a: i32, b: i32) -> i32 { + a + b +} + +fn apply(f: fn(i32, i32) -> i32, x: i32, y: i32) -> i32 { + f(x, y) +} + +fn main() { + // This assignment coerces the fn item `add` into a `fn(i32, i32) -> i32` + // pointer, producing a ReifyFnPointer cast in MIR. + let f: fn(i32, i32) -> i32 = add; + let result = apply(f, 3, 4); + assert_eq!(result, 7); +} diff --git a/tests/integration/programs/reify-fn-pointer.smir.json.expected b/tests/integration/programs/reify-fn-pointer.smir.json.expected new file mode 100644 index 00000000..50b68fa1 --- /dev/null +++ b/tests/integration/programs/reify-fn-pointer.smir.json.expected @@ -0,0 +1,5980 @@ +{ + "allocs": [ + { + "global_alloc": { + "Memory": { + "align": 4, + "bytes": [ + 7, + 0, + 0, + 0 + ], + "mutability": "Not", + "provenance": { + "ptrs": [] + } + } + } + } + ], + "functions": [ + [ + { + "IntrinsicSym": "black_box" + } + ], + [ + { + "NoOpSym": "" + } + ], + [ + { + "NormalSym": "_ZN16reify_fn_pointer3add17h" + } + ], + [ + { + "NormalSym": "_ZN16reify_fn_pointer5apply17h" + } + ], + [ + { + "NormalSym": "_ZN3std2rt10lang_start28_$u7b$$u7b$closure$u7d$$u7d$17h" + } + ], + [ + { + "NormalSym": "_ZN3std2rt19lang_start_internal17h" + } + ], + [ + { + "NormalSym": "_ZN3std3sys9backtrace28__rust_begin_short_backtrace17h" + } + ], + [ + { + "NormalSym": "_ZN4core3fmt3num3imp52_$LT$impl$u20$core..fmt..Display$u20$for$u20$i32$GT$3fmt17h" + } + ], + [ + { + "NormalSym": "_ZN4core3fmt3num50_$LT$impl$u20$core..fmt..Debug$u20$for$u20$i32$GT$3fmt17h" + } + ], + [ + { + "NormalSym": "_ZN4core3fmt3num53_$LT$impl$u20$core..fmt..LowerHex$u20$for$u20$i32$GT$3fmt17h" + } + ], + [ + { + "NormalSym": "_ZN4core3fmt3num53_$LT$impl$u20$core..fmt..UpperHex$u20$for$u20$i32$GT$3fmt17h" + } + ], + [ + { + "NormalSym": "_ZN4core3ops8function6FnOnce9call_once17h" + } + ], + [ + { + "NormalSym": "_ZN4core3ops8function6FnOnce9call_once17h" + } + ], + [ + { + "NormalSym": "_ZN4core9panicking13assert_failed17h" + } + ], + [ + { + "NormalSym": "_ZN4core9panicking19assert_failed_inner17h" + } + ], + [ + { + "NormalSym": "_ZN54_$LT$$LP$$RP$$u20$as$u20$std..process..Termination$GT$6report17h" + } + ] + ], + "items": [ + { + "details": null, + "mono_item_kind": { + "MonoItemFn": { + "body": { + "arg_count": 0, + "blocks": [ + { + "statements": [ + { + "kind": { + "Assign": [ + { + "local": 1, + "projection": [] + }, + { + "Cast": [ + { + "PointerCoercion": "ReifyFnPointer" + }, + { + "Constant": { + "const_": { + "id": 19, + "kind": "ZeroSized" + }, + "span": 107, + "user_ty": null + } + }, + 42 + ] + } + ] + }, + "span": 107 + } + ], + "terminator": { + "kind": { + "Call": { + "args": [ + { + "Copy": { + "local": 1, + "projection": [] + } + }, + { + "Constant": { + "const_": { + "id": 17, + "kind": { + "Allocated": { + "align": 4, + "bytes": [ + 3, + 0, + 0, + 0 + ], + "mutability": "Mut", + "provenance": { + "ptrs": [] + } + } + } + }, + "span": 104, + "user_ty": null + } + }, + { + "Constant": { + "const_": { + "id": 18, + "kind": { + "Allocated": { + "align": 4, + "bytes": [ + 4, + 0, + 0, + 0 + ], + "mutability": "Mut", + "provenance": { + "ptrs": [] + } + } + } + }, + "span": 105, + "user_ty": null + } + } + ], + "destination": { + "local": 2, + "projection": [] + }, + "func": { + "Constant": { + "const_": { + "id": 16, + "kind": "ZeroSized" + }, + "span": 103, + "user_ty": null + } + }, + "target": 1, + "unwind": "Continue" + } + }, + "span": 106 + } + }, + { + "statements": [ + { + "kind": { + "Assign": [ + { + "local": 4, + "projection": [] + }, + { + "Ref": [ + { + "kind": "ReErased" + }, + "Shared", + { + "local": 2, + "projection": [] + } + ] + } + ] + }, + "span": 109 + }, + { + "kind": { + "Assign": [ + { + "local": 5, + "projection": [] + }, + { + "Use": { + "Constant": { + "const_": { + "id": 20, + "kind": { + "Allocated": { + "align": 8, + "bytes": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "mutability": "Mut", + "provenance": { + "ptrs": [ + [ + 0, + 0 + ] + ] + } + } + } + }, + "span": 110, + "user_ty": null + } + } + } + ] + }, + "span": 110 + }, + { + "kind": { + "Assign": [ + { + "local": 3, + "projection": [] + }, + { + "Aggregate": [ + "Tuple", + [ + { + "Move": { + "local": 4, + "projection": [] + } + }, + { + "Move": { + "local": 5, + "projection": [] + } + } + ] + ] + } + ] + }, + "span": 111 + }, + { + "kind": { + "Assign": [ + { + "local": 6, + "projection": [] + }, + { + "Use": { + "Copy": { + "local": 3, + "projection": [ + { + "Field": [ + 0, + 25 + ] + } + ] + } + } + } + ] + }, + "span": 112 + }, + { + "kind": { + "Assign": [ + { + "local": 7, + "projection": [] + }, + { + "Use": { + "Copy": { + "local": 3, + "projection": [ + { + "Field": [ + 1, + 25 + ] + } + ] + } + } + } + ] + }, + "span": 113 + }, + { + "kind": { + "Assign": [ + { + "local": 9, + "projection": [] + }, + { + "Use": { + "Copy": { + "local": 6, + "projection": [ + "Deref" + ] + } + } + } + ] + }, + "span": 114 + }, + { + "kind": { + "Assign": [ + { + "local": 10, + "projection": [] + }, + { + "Use": { + "Copy": { + "local": 7, + "projection": [ + "Deref" + ] + } + } + } + ] + }, + "span": 115 + }, + { + "kind": { + "Assign": [ + { + "local": 8, + "projection": [] + }, + { + "BinaryOp": [ + "Eq", + { + "Move": { + "local": 9, + "projection": [] + } + }, + { + "Move": { + "local": 10, + "projection": [] + } + } + ] + } + ] + }, + "span": 108 + } + ], + "terminator": { + "kind": { + "SwitchInt": { + "discr": { + "Move": { + "local": 8, + "projection": [] + } + }, + "targets": { + "branches": [ + [ + 0, + 3 + ] + ], + "otherwise": 2 + } + } + }, + "span": 108 + } + }, + { + "statements": [], + "terminator": { + "kind": "Return", + "span": 116 + } + }, + { + "statements": [ + { + "kind": { + "Assign": [ + { + "local": 11, + "projection": [] + }, + { + "Aggregate": [ + { + "Adt": [ + 12, + 0, + [], + null, + null + ] + }, + [] + ] + } + ] + }, + "span": 119 + }, + { + "kind": { + "Assign": [ + { + "local": 13, + "projection": [] + }, + { + "Aggregate": [ + { + "Adt": [ + 13, + 0, + [ + { + "Type": 46 + } + ], + null, + null + ] + }, + [] + ] + } + ] + }, + "span": 120 + } + ], + "terminator": { + "kind": { + "Call": { + "args": [ + { + "Move": { + "local": 11, + "projection": [] + } + }, + { + "Copy": { + "local": 6, + "projection": [] + } + }, + { + "Copy": { + "local": 7, + "projection": [] + } + }, + { + "Move": { + "local": 13, + "projection": [] + } + } + ], + "destination": { + "local": 12, + "projection": [] + }, + "func": { + "Constant": { + "const_": { + "id": 21, + "kind": "ZeroSized" + }, + "span": 117, + "user_ty": null + } + }, + "target": null, + "unwind": "Continue" + } + }, + "span": 118 + } + } + ], + "locals": [ + { + "mutability": "Mut", + "span": 121 + }, + { + "mutability": "Not", + "span": 122 + }, + { + "mutability": "Not", + "span": 123 + }, + { + "mutability": "Mut", + "span": 111 + }, + { + "mutability": "Mut", + "span": 109 + }, + { + "mutability": "Mut", + "span": 110 + }, + { + "mutability": "Not", + "span": 112 + }, + { + "mutability": "Not", + "span": 113 + }, + { + "mutability": "Mut", + "span": 108 + }, + { + "mutability": "Mut", + "span": 114 + }, + { + "mutability": "Mut", + "span": 115 + }, + { + "mutability": "Not", + "span": 124 + }, + { + "mutability": "Not", + "span": 118 + }, + { + "mutability": "Mut", + "span": 120 + } + ], + "span": 125, + "spread_arg": null, + "var_debug_info": [ + { + "argument_index": null, + "composite": null, + "name": "f", + "source_info": { + "scope": 1, + "span": 122 + }, + "value": { + "Place": { + "local": 1, + "projection": [] + } + } + }, + { + "argument_index": null, + "composite": null, + "name": "result", + "source_info": { + "scope": 2, + "span": 123 + }, + "value": { + "Place": { + "local": 2, + "projection": [] + } + } + }, + { + "argument_index": null, + "composite": null, + "name": "left_val", + "source_info": { + "scope": 3, + "span": 112 + }, + "value": { + "Place": { + "local": 6, + "projection": [] + } + } + }, + { + "argument_index": null, + "composite": null, + "name": "right_val", + "source_info": { + "scope": 3, + "span": 113 + }, + "value": { + "Place": { + "local": 7, + "projection": [] + } + } + }, + { + "argument_index": null, + "composite": null, + "name": "kind", + "source_info": { + "scope": 4, + "span": 124 + }, + "value": { + "Place": { + "local": 11, + "projection": [] + } + } + } + ] + }, + "id": 11, + "name": "main" + } + }, + "symbol_name": "_ZN16reify_fn_pointer4main17h" + }, + { + "details": null, + "mono_item_kind": { + "MonoItemFn": { + "body": { + "arg_count": 1, + "blocks": [ + { + "statements": [], + "terminator": { + "kind": "Return", + "span": 74 + } + } + ], + "locals": [ + { + "mutability": "Mut", + "span": 74 + }, + { + "mutability": "Not", + "span": 74 + } + ], + "span": 74, + "spread_arg": null, + "var_debug_info": [] + }, + "id": 6, + "name": "std::ptr::drop_in_place::<&i32>" + } + }, + "symbol_name": "_ZN4core3ptr28drop_in_place$LT$$RF$i32$GT$17h" + }, + { + "details": null, + "mono_item_kind": { + "MonoItemFn": { + "body": { + "arg_count": 1, + "blocks": [ + { + "statements": [], + "terminator": { + "kind": "Return", + "span": 74 + } + } + ], + "locals": [ + { + "mutability": "Mut", + "span": 74 + }, + { + "mutability": "Not", + "span": 74 + } + ], + "span": 74, + "spread_arg": null, + "var_debug_info": [] + }, + "id": 6, + "name": "std::ptr::drop_in_place::<{closure@std::rt::lang_start<()>::{closure#0}}>" + } + }, + "symbol_name": "_ZN4core3ptr85drop_in_place$LT$std..rt..lang_start$LT$$LP$$RP$$GT$..$u7b$$u7b$closure$u7d$$u7d$$GT$17h" + }, + { + "details": null, + "mono_item_kind": { + "MonoItemFn": { + "body": { + "arg_count": 1, + "blocks": [ + { + "statements": [], + "terminator": { + "kind": { + "Call": { + "args": [ + { + "Move": { + "local": 1, + "projection": [] + } + }, + { + "Constant": { + "const_": { + "id": 4, + "kind": "ZeroSized" + }, + "span": 32, + "user_ty": null + } + } + ], + "destination": { + "local": 0, + "projection": [] + }, + "func": { + "Constant": { + "const_": { + "id": 3, + "kind": "ZeroSized" + }, + "span": 31, + "user_ty": null + } + }, + "target": 1, + "unwind": "Continue" + } + }, + "span": 33 + } + }, + { + "statements": [], + "terminator": { + "kind": { + "Call": { + "args": [ + { + "Constant": { + "const_": { + "id": 4, + "kind": "ZeroSized" + }, + "span": 32, + "user_ty": null + } + } + ], + "destination": { + "local": 2, + "projection": [] + }, + "func": { + "Constant": { + "const_": { + "id": 5, + "kind": "ZeroSized" + }, + "span": 34, + "user_ty": null + } + }, + "target": 2, + "unwind": "Unreachable" + } + }, + "span": 35 + } + }, + { + "statements": [], + "terminator": { + "kind": "Return", + "span": 36 + } + } + ], + "locals": [ + { + "mutability": "Mut", + "span": 37 + }, + { + "mutability": "Not", + "span": 38 + }, + { + "mutability": "Not", + "span": 39 + } + ], + "span": 42, + "spread_arg": null, + "var_debug_info": [ + { + "argument_index": 1, + "composite": null, + "name": "f", + "source_info": { + "scope": 0, + "span": 38 + }, + "value": { + "Place": { + "local": 1, + "projection": [] + } + } + }, + { + "argument_index": null, + "composite": null, + "name": "result", + "source_info": { + "scope": 1, + "span": 40 + }, + "value": { + "Place": { + "local": 0, + "projection": [] + } + } + }, + { + "argument_index": 1, + "composite": null, + "name": "dummy", + "source_info": { + "scope": 2, + "span": 41 + }, + "value": { + "Const": { + "const_": { + "id": 4, + "kind": "ZeroSized" + }, + "span": 32, + "user_ty": null + } + } + } + ] + }, + "id": 2, + "name": "std::sys::backtrace::__rust_begin_short_backtrace::" + } + }, + "symbol_name": "_ZN3std3sys9backtrace28__rust_begin_short_backtrace17h" + }, + { + "details": null, + "mono_item_kind": { + "MonoItemFn": { + "body": { + "arg_count": 1, + "blocks": [ + { + "statements": [ + { + "kind": { + "Assign": [ + { + "local": 0, + "projection": [] + }, + { + "Use": { + "Constant": { + "const_": { + "id": 15, + "kind": { + "Allocated": { + "align": 1, + "bytes": [ + 0 + ], + "mutability": "Mut", + "provenance": { + "ptrs": [] + } + } + } + }, + "span": 86, + "user_ty": null + } + } + } + ] + }, + "span": 86 + } + ], + "terminator": { + "kind": "Return", + "span": 85 + } + } + ], + "locals": [ + { + "mutability": "Mut", + "span": 87 + }, + { + "mutability": "Not", + "span": 88 + } + ], + "span": 89, + "spread_arg": null, + "var_debug_info": [ + { + "argument_index": 1, + "composite": null, + "name": "self", + "source_info": { + "scope": 0, + "span": 88 + }, + "value": { + "Const": { + "const_": { + "id": 4, + "kind": "ZeroSized" + }, + "span": 32, + "user_ty": null + } + } + } + ] + }, + "id": 8, + "name": "<() as std::process::Termination>::report" + } + }, + "symbol_name": "_ZN54_$LT$$LP$$RP$$u20$as$u20$std..process..Termination$GT$6report17h" + }, + { + "details": null, + "mono_item_kind": { + "MonoItemFn": { + "body": { + "arg_count": 1, + "blocks": [ + { + "statements": [ + { + "kind": { + "StorageLive": 2 + }, + "span": 16 + }, + { + "kind": { + "StorageLive": 3 + }, + "span": 15 + }, + { + "kind": { + "StorageLive": 4 + }, + "span": 17 + }, + { + "kind": { + "Assign": [ + { + "local": 4, + "projection": [] + }, + { + "Use": { + "Copy": { + "local": 1, + "projection": [ + "Deref", + { + "Field": [ + 0, + 7 + ] + } + ] + } + } + } + ] + }, + "span": 17 + } + ], + "terminator": { + "kind": { + "Call": { + "args": [ + { + "Move": { + "local": 4, + "projection": [] + } + } + ], + "destination": { + "local": 3, + "projection": [] + }, + "func": { + "Constant": { + "const_": { + "id": 1, + "kind": "ZeroSized" + }, + "span": 14, + "user_ty": null + } + }, + "target": 1, + "unwind": "Continue" + } + }, + "span": 15 + } + }, + { + "statements": [ + { + "kind": { + "StorageDead": 4 + }, + "span": 19 + } + ], + "terminator": { + "kind": { + "Call": { + "args": [ + { + "Move": { + "local": 3, + "projection": [] + } + } + ], + "destination": { + "local": 2, + "projection": [] + }, + "func": { + "Constant": { + "const_": { + "id": 2, + "kind": "ZeroSized" + }, + "span": 18, + "user_ty": null + } + }, + "target": 2, + "unwind": "Continue" + } + }, + "span": 16 + } + }, + { + "statements": [ + { + "kind": { + "StorageDead": 3 + }, + "span": 21 + }, + { + "kind": { + "StorageLive": 5 + }, + "span": 22 + }, + { + "kind": { + "Assign": [ + { + "local": 5, + "projection": [] + }, + { + "Ref": [ + { + "kind": "ReErased" + }, + "Shared", + { + "local": 2, + "projection": [ + { + "Field": [ + 0, + 15 + ] + } + ] + } + ] + } + ] + }, + "span": 22 + }, + { + "kind": { + "StorageLive": 6 + }, + "span": 23 + }, + { + "kind": { + "Assign": [ + { + "local": 6, + "projection": [] + }, + { + "Use": { + "Copy": { + "local": 2, + "projection": [ + { + "Field": [ + 0, + 15 + ] + }, + { + "Field": [ + 0, + 9 + ] + } + ] + } + } + } + ] + }, + "span": 23 + }, + { + "kind": { + "Assign": [ + { + "local": 0, + "projection": [] + }, + { + "Cast": [ + "IntToInt", + { + "Move": { + "local": 6, + "projection": [] + } + }, + 16 + ] + } + ] + }, + "span": 24 + }, + { + "kind": { + "StorageDead": 6 + }, + "span": 25 + }, + { + "kind": { + "StorageDead": 5 + }, + "span": 26 + }, + { + "kind": { + "StorageDead": 2 + }, + "span": 27 + } + ], + "terminator": { + "kind": "Return", + "span": 20 + } + } + ], + "locals": [ + { + "mutability": "Mut", + "span": 28 + }, + { + "mutability": "Mut", + "span": 3 + }, + { + "mutability": "Mut", + "span": 16 + }, + { + "mutability": "Mut", + "span": 15 + }, + { + "mutability": "Mut", + "span": 17 + }, + { + "mutability": "Mut", + "span": 22 + }, + { + "mutability": "Mut", + "span": 23 + } + ], + "span": 3, + "spread_arg": null, + "var_debug_info": [ + { + "argument_index": null, + "composite": null, + "name": "main", + "source_info": { + "scope": 0, + "span": 9 + }, + "value": { + "Place": { + "local": 1, + "projection": [ + "Deref", + { + "Field": [ + 0, + 7 + ] + } + ] + } + } + }, + { + "argument_index": 1, + "composite": null, + "name": "self", + "source_info": { + "scope": 1, + "span": 29 + }, + "value": { + "Place": { + "local": 2, + "projection": [] + } + } + }, + { + "argument_index": 1, + "composite": null, + "name": "self", + "source_info": { + "scope": 2, + "span": 30 + }, + "value": { + "Place": { + "local": 5, + "projection": [] + } + } + } + ] + }, + "id": 1, + "name": "std::rt::lang_start::<()>::{closure#0}" + } + }, + "symbol_name": "_ZN3std2rt10lang_start28_$u7b$$u7b$closure$u7d$$u7d$17h" + }, + { + "details": null, + "mono_item_kind": { + "MonoItemFn": { + "body": { + "arg_count": 2, + "blocks": [ + { + "statements": [], + "terminator": { + "kind": { + "Call": { + "args": [], + "destination": { + "local": 0, + "projection": [] + }, + "func": { + "Move": { + "local": 1, + "projection": [] + } + }, + "target": 1, + "unwind": "Continue" + } + }, + "span": 73 + } + }, + { + "statements": [], + "terminator": { + "kind": "Return", + "span": 73 + } + } + ], + "locals": [ + { + "mutability": "Mut", + "span": 73 + }, + { + "mutability": "Not", + "span": 73 + }, + { + "mutability": "Not", + "span": 73 + } + ], + "span": 73, + "spread_arg": 2, + "var_debug_info": [] + }, + "id": 5, + "name": ">::call_once" + } + }, + "symbol_name": "_ZN4core3ops8function6FnOnce9call_once17h" + }, + { + "details": null, + "mono_item_kind": { + "MonoItemFn": { + "body": { + "arg_count": 2, + "blocks": [ + { + "statements": [], + "terminator": { + "kind": { + "Call": { + "args": [ + { + "Move": { + "local": 1, + "projection": [ + "Deref" + ] + } + }, + { + "Move": { + "local": 2, + "projection": [] + } + } + ], + "destination": { + "local": 0, + "projection": [] + }, + "func": { + "Constant": { + "const_": { + "id": 12, + "kind": "ZeroSized" + }, + "span": 73, + "user_ty": null + } + }, + "target": 1, + "unwind": "Continue" + } + }, + "span": 73 + } + }, + { + "statements": [], + "terminator": { + "kind": "Return", + "span": 73 + } + } + ], + "locals": [ + { + "mutability": "Mut", + "span": 73 + }, + { + "mutability": "Not", + "span": 73 + }, + { + "mutability": "Not", + "span": 73 + } + ], + "span": 73, + "spread_arg": 2, + "var_debug_info": [] + }, + "id": 5, + "name": "<{closure@std::rt::lang_start<()>::{closure#0}} as std::ops::FnOnce<()>>::call_once" + } + }, + "symbol_name": "_ZN4core3ops8function6FnOnce40call_once$u7b$$u7b$vtable.shim$u7d$$u7d$17h" + }, + { + "details": null, + "mono_item_kind": { + "MonoItemFn": { + "body": { + "arg_count": 2, + "blocks": [ + { + "statements": [ + { + "kind": { + "Assign": [ + { + "local": 3, + "projection": [] + }, + { + "CheckedBinaryOp": [ + "Add", + { + "Copy": { + "local": 1, + "projection": [] + } + }, + { + "Copy": { + "local": 2, + "projection": [] + } + } + ] + } + ] + }, + "span": 90 + } + ], + "terminator": { + "kind": { + "Assert": { + "cond": { + "Move": { + "local": 3, + "projection": [ + { + "Field": [ + 1, + 40 + ] + } + ] + } + }, + "expected": false, + "msg": { + "Overflow": [ + "Add", + { + "Copy": { + "local": 1, + "projection": [] + } + }, + { + "Copy": { + "local": 2, + "projection": [] + } + } + ] + }, + "target": 1, + "unwind": "Continue" + } + }, + "span": 90 + } + }, + { + "statements": [ + { + "kind": { + "Assign": [ + { + "local": 0, + "projection": [] + }, + { + "Use": { + "Move": { + "local": 3, + "projection": [ + { + "Field": [ + 0, + 16 + ] + } + ] + } + } + } + ] + }, + "span": 90 + } + ], + "terminator": { + "kind": "Return", + "span": 91 + } + } + ], + "locals": [ + { + "mutability": "Mut", + "span": 92 + }, + { + "mutability": "Not", + "span": 93 + }, + { + "mutability": "Not", + "span": 94 + }, + { + "mutability": "Mut", + "span": 90 + } + ], + "span": 95, + "spread_arg": null, + "var_debug_info": [ + { + "argument_index": 1, + "composite": null, + "name": "a", + "source_info": { + "scope": 0, + "span": 93 + }, + "value": { + "Place": { + "local": 1, + "projection": [] + } + } + }, + { + "argument_index": 2, + "composite": null, + "name": "b", + "source_info": { + "scope": 0, + "span": 94 + }, + "value": { + "Place": { + "local": 2, + "projection": [] + } + } + } + ] + }, + "id": 9, + "name": "add" + } + }, + "symbol_name": "_ZN16reify_fn_pointer3add17h" + }, + { + "details": null, + "mono_item_kind": { + "MonoItemFn": { + "body": { + "arg_count": 2, + "blocks": [ + { + "statements": [ + { + "kind": { + "Assign": [ + { + "local": 3, + "projection": [] + }, + { + "Ref": [ + { + "kind": "ReErased" + }, + { + "Mut": { + "kind": "Default" + } + }, + { + "local": 1, + "projection": [] + } + ] + } + ] + }, + "span": 73 + } + ], + "terminator": { + "kind": { + "Call": { + "args": [ + { + "Move": { + "local": 3, + "projection": [] + } + }, + { + "Move": { + "local": 2, + "projection": [] + } + } + ], + "destination": { + "local": 0, + "projection": [] + }, + "func": { + "Constant": { + "const_": { + "id": 13, + "kind": "ZeroSized" + }, + "span": 73, + "user_ty": null + } + }, + "target": 1, + "unwind": { + "Cleanup": 3 + } + } + }, + "span": 73 + } + }, + { + "statements": [], + "terminator": { + "kind": { + "Drop": { + "place": { + "local": 1, + "projection": [] + }, + "target": 2, + "unwind": "Continue" + } + }, + "span": 73 + } + }, + { + "statements": [], + "terminator": { + "kind": "Return", + "span": 73 + } + }, + { + "statements": [], + "terminator": { + "kind": { + "Drop": { + "place": { + "local": 1, + "projection": [] + }, + "target": 4, + "unwind": "Terminate" + } + }, + "span": 73 + } + }, + { + "statements": [], + "terminator": { + "kind": "Resume", + "span": 73 + } + } + ], + "locals": [ + { + "mutability": "Mut", + "span": 73 + }, + { + "mutability": "Not", + "span": 73 + }, + { + "mutability": "Not", + "span": 73 + }, + { + "mutability": "Not", + "span": 73 + } + ], + "span": 73, + "spread_arg": 2, + "var_debug_info": [] + }, + "id": 5, + "name": "<{closure@std::rt::lang_start<()>::{closure#0}} as std::ops::FnOnce<()>>::call_once" + } + }, + "symbol_name": "_ZN4core3ops8function6FnOnce9call_once17h" + }, + { + "details": null, + "mono_item_kind": { + "MonoItemFn": { + "body": { + "arg_count": 2, + "blocks": [ + { + "statements": [ + { + "kind": { + "Assign": [ + { + "local": 3, + "projection": [] + }, + { + "Use": { + "Copy": { + "local": 1, + "projection": [ + "Deref" + ] + } + } + } + ] + }, + "span": 45 + } + ], + "terminator": { + "kind": { + "Call": { + "args": [ + { + "Move": { + "local": 3, + "projection": [] + } + }, + { + "Move": { + "local": 2, + "projection": [] + } + } + ], + "destination": { + "local": 0, + "projection": [] + }, + "func": { + "Constant": { + "const_": { + "id": 6, + "kind": "ZeroSized" + }, + "span": 43, + "user_ty": null + } + }, + "target": 1, + "unwind": "Continue" + } + }, + "span": 44 + } + }, + { + "statements": [], + "terminator": { + "kind": "Return", + "span": 46 + } + } + ], + "locals": [ + { + "mutability": "Mut", + "span": 47 + }, + { + "mutability": "Not", + "span": 48 + }, + { + "mutability": "Not", + "span": 49 + }, + { + "mutability": "Mut", + "span": 48 + } + ], + "span": 50, + "spread_arg": null, + "var_debug_info": [ + { + "argument_index": 1, + "composite": null, + "name": "self", + "source_info": { + "scope": 0, + "span": 48 + }, + "value": { + "Place": { + "local": 1, + "projection": [] + } + } + }, + { + "argument_index": 2, + "composite": null, + "name": "f", + "source_info": { + "scope": 0, + "span": 49 + }, + "value": { + "Place": { + "local": 2, + "projection": [] + } + } + } + ] + }, + "id": 3, + "name": "<&i32 as std::fmt::Debug>::fmt" + } + }, + "symbol_name": "_ZN42_$LT$$RF$T$u20$as$u20$core..fmt..Debug$GT$3fmt17h" + }, + { + "details": null, + "mono_item_kind": { + "MonoItemFn": { + "body": { + "arg_count": 2, + "blocks": [ + { + "statements": [ + { + "kind": { + "StorageLive": 3 + }, + "span": 52 + }, + { + "kind": { + "StorageLive": 4 + }, + "span": 53 + }, + { + "kind": { + "Assign": [ + { + "local": 4, + "projection": [] + }, + { + "Use": { + "Copy": { + "local": 2, + "projection": [ + "Deref", + { + "Field": [ + 0, + 26 + ] + } + ] + } + } + } + ] + }, + "span": 53 + }, + { + "kind": { + "Assign": [ + { + "local": 3, + "projection": [] + }, + { + "BinaryOp": [ + "BitAnd", + { + "Move": { + "local": 4, + "projection": [] + } + }, + { + "Constant": { + "const_": { + "id": 7, + "kind": { + "Allocated": { + "align": 4, + "bytes": [ + 16, + 0, + 0, + 0 + ], + "mutability": "Mut", + "provenance": { + "ptrs": [] + } + } + } + }, + "span": 32, + "user_ty": null + } + } + ] + } + ] + }, + "span": 52 + }, + { + "kind": { + "StorageDead": 4 + }, + "span": 54 + } + ], + "terminator": { + "kind": { + "SwitchInt": { + "discr": { + "Move": { + "local": 3, + "projection": [] + } + }, + "targets": { + "branches": [ + [ + 0, + 2 + ] + ], + "otherwise": 1 + } + } + }, + "span": 51 + } + }, + { + "statements": [ + { + "kind": { + "StorageDead": 3 + }, + "span": 51 + } + ], + "terminator": { + "kind": { + "Call": { + "args": [ + { + "Move": { + "local": 1, + "projection": [] + } + }, + { + "Move": { + "local": 2, + "projection": [] + } + } + ], + "destination": { + "local": 0, + "projection": [] + }, + "func": { + "Constant": { + "const_": { + "id": 8, + "kind": "ZeroSized" + }, + "span": 55, + "user_ty": null + } + }, + "target": 6, + "unwind": "Continue" + } + }, + "span": 56 + } + }, + { + "statements": [ + { + "kind": { + "StorageDead": 3 + }, + "span": 51 + }, + { + "kind": { + "StorageLive": 5 + }, + "span": 58 + }, + { + "kind": { + "StorageLive": 6 + }, + "span": 59 + }, + { + "kind": { + "Assign": [ + { + "local": 6, + "projection": [] + }, + { + "Use": { + "Copy": { + "local": 2, + "projection": [ + "Deref", + { + "Field": [ + 0, + 26 + ] + } + ] + } + } + } + ] + }, + "span": 59 + }, + { + "kind": { + "Assign": [ + { + "local": 5, + "projection": [] + }, + { + "BinaryOp": [ + "BitAnd", + { + "Move": { + "local": 6, + "projection": [] + } + }, + { + "Constant": { + "const_": { + "id": 9, + "kind": { + "Allocated": { + "align": 4, + "bytes": [ + 32, + 0, + 0, + 0 + ], + "mutability": "Mut", + "provenance": { + "ptrs": [] + } + } + } + }, + "span": 32, + "user_ty": null + } + } + ] + } + ] + }, + "span": 58 + }, + { + "kind": { + "StorageDead": 6 + }, + "span": 60 + } + ], + "terminator": { + "kind": { + "SwitchInt": { + "discr": { + "Move": { + "local": 5, + "projection": [] + } + }, + "targets": { + "branches": [ + [ + 0, + 4 + ] + ], + "otherwise": 3 + } + } + }, + "span": 57 + } + }, + { + "statements": [ + { + "kind": { + "StorageDead": 5 + }, + "span": 57 + } + ], + "terminator": { + "kind": { + "Call": { + "args": [ + { + "Move": { + "local": 1, + "projection": [] + } + }, + { + "Move": { + "local": 2, + "projection": [] + } + } + ], + "destination": { + "local": 0, + "projection": [] + }, + "func": { + "Constant": { + "const_": { + "id": 10, + "kind": "ZeroSized" + }, + "span": 61, + "user_ty": null + } + }, + "target": 5, + "unwind": "Continue" + } + }, + "span": 62 + } + }, + { + "statements": [ + { + "kind": { + "StorageDead": 5 + }, + "span": 57 + } + ], + "terminator": { + "kind": { + "Call": { + "args": [ + { + "Move": { + "local": 1, + "projection": [] + } + }, + { + "Move": { + "local": 2, + "projection": [] + } + } + ], + "destination": { + "local": 0, + "projection": [] + }, + "func": { + "Constant": { + "const_": { + "id": 11, + "kind": "ZeroSized" + }, + "span": 63, + "user_ty": null + } + }, + "target": 5, + "unwind": "Continue" + } + }, + "span": 64 + } + }, + { + "statements": [], + "terminator": { + "kind": { + "Goto": { + "target": 6 + } + }, + "span": 65 + } + }, + { + "statements": [], + "terminator": { + "kind": "Return", + "span": 66 + } + } + ], + "locals": [ + { + "mutability": "Mut", + "span": 67 + }, + { + "mutability": "Not", + "span": 68 + }, + { + "mutability": "Not", + "span": 69 + }, + { + "mutability": "Mut", + "span": 52 + }, + { + "mutability": "Mut", + "span": 53 + }, + { + "mutability": "Mut", + "span": 58 + }, + { + "mutability": "Mut", + "span": 59 + } + ], + "span": 72, + "spread_arg": null, + "var_debug_info": [ + { + "argument_index": 1, + "composite": null, + "name": "self", + "source_info": { + "scope": 0, + "span": 68 + }, + "value": { + "Place": { + "local": 1, + "projection": [] + } + } + }, + { + "argument_index": 2, + "composite": null, + "name": "f", + "source_info": { + "scope": 0, + "span": 69 + }, + "value": { + "Place": { + "local": 2, + "projection": [] + } + } + }, + { + "argument_index": 1, + "composite": null, + "name": "self", + "source_info": { + "scope": 1, + "span": 70 + }, + "value": { + "Place": { + "local": 2, + "projection": [] + } + } + }, + { + "argument_index": 1, + "composite": null, + "name": "self", + "source_info": { + "scope": 2, + "span": 71 + }, + "value": { + "Place": { + "local": 2, + "projection": [] + } + } + } + ] + }, + "id": 4, + "name": "core::fmt::num::::fmt" + } + }, + "symbol_name": "_ZN4core3fmt3num50_$LT$impl$u20$core..fmt..Debug$u20$for$u20$i32$GT$3fmt17h" + }, + { + "details": null, + "mono_item_kind": { + "MonoItemFn": { + "body": { + "arg_count": 3, + "blocks": [ + { + "statements": [], + "terminator": { + "kind": { + "Call": { + "args": [ + { + "Copy": { + "local": 2, + "projection": [] + } + }, + { + "Copy": { + "local": 3, + "projection": [] + } + } + ], + "destination": { + "local": 0, + "projection": [] + }, + "func": { + "Copy": { + "local": 1, + "projection": [] + } + }, + "target": 1, + "unwind": "Continue" + } + }, + "span": 96 + } + }, + { + "statements": [], + "terminator": { + "kind": "Return", + "span": 97 + } + } + ], + "locals": [ + { + "mutability": "Mut", + "span": 98 + }, + { + "mutability": "Not", + "span": 99 + }, + { + "mutability": "Not", + "span": 100 + }, + { + "mutability": "Not", + "span": 101 + } + ], + "span": 102, + "spread_arg": null, + "var_debug_info": [ + { + "argument_index": 1, + "composite": null, + "name": "f", + "source_info": { + "scope": 0, + "span": 99 + }, + "value": { + "Place": { + "local": 1, + "projection": [] + } + } + }, + { + "argument_index": 2, + "composite": null, + "name": "x", + "source_info": { + "scope": 0, + "span": 100 + }, + "value": { + "Place": { + "local": 2, + "projection": [] + } + } + }, + { + "argument_index": 3, + "composite": null, + "name": "y", + "source_info": { + "scope": 0, + "span": 101 + }, + "value": { + "Place": { + "local": 3, + "projection": [] + } + } + } + ] + }, + "id": 10, + "name": "apply" + } + }, + "symbol_name": "_ZN16reify_fn_pointer5apply17h" + }, + { + "details": null, + "mono_item_kind": { + "MonoItemFn": { + "body": { + "arg_count": 4, + "blocks": [ + { + "statements": [ + { + "kind": { + "StorageLive": 5 + }, + "span": 1 + }, + { + "kind": { + "StorageLive": 6 + }, + "span": 2 + }, + { + "kind": { + "StorageLive": 8 + }, + "span": 3 + }, + { + "kind": { + "Assign": [ + { + "local": 8, + "projection": [] + }, + { + "Aggregate": [ + { + "Closure": [ + 1, + [ + { + "Type": 1 + }, + { + "Type": 2 + }, + { + "Type": 3 + }, + { + "Type": 4 + } + ] + ] + }, + [ + { + "Copy": { + "local": 1, + "projection": [] + } + } + ] + ] + } + ] + }, + "span": 3 + }, + { + "kind": { + "Assign": [ + { + "local": 7, + "projection": [] + }, + { + "Ref": [ + { + "kind": "ReErased" + }, + "Shared", + { + "local": 8, + "projection": [] + } + ] + } + ] + }, + "span": 2 + }, + { + "kind": { + "Assign": [ + { + "local": 6, + "projection": [] + }, + { + "Cast": [ + { + "PointerCoercion": "Unsize" + }, + { + "Copy": { + "local": 7, + "projection": [] + } + }, + 5 + ] + } + ] + }, + "span": 2 + } + ], + "terminator": { + "kind": { + "Call": { + "args": [ + { + "Move": { + "local": 6, + "projection": [] + } + }, + { + "Move": { + "local": 2, + "projection": [] + } + }, + { + "Move": { + "local": 3, + "projection": [] + } + }, + { + "Move": { + "local": 4, + "projection": [] + } + } + ], + "destination": { + "local": 5, + "projection": [] + }, + "func": { + "Constant": { + "const_": { + "id": 0, + "kind": "ZeroSized" + }, + "span": 0, + "user_ty": null + } + }, + "target": 1, + "unwind": "Continue" + } + }, + "span": 1 + } + }, + { + "statements": [ + { + "kind": { + "StorageDead": 6 + }, + "span": 5 + }, + { + "kind": { + "Assign": [ + { + "local": 0, + "projection": [] + }, + { + "Use": { + "Copy": { + "local": 5, + "projection": [ + { + "Downcast": 0 + }, + { + "Field": [ + 0, + 6 + ] + } + ] + } + } + } + ] + }, + "span": 6 + }, + { + "kind": { + "StorageDead": 8 + }, + "span": 7 + }, + { + "kind": { + "StorageDead": 5 + }, + "span": 7 + } + ], + "terminator": { + "kind": "Return", + "span": 4 + } + } + ], + "locals": [ + { + "mutability": "Mut", + "span": 8 + }, + { + "mutability": "Not", + "span": 9 + }, + { + "mutability": "Not", + "span": 10 + }, + { + "mutability": "Not", + "span": 11 + }, + { + "mutability": "Not", + "span": 12 + }, + { + "mutability": "Mut", + "span": 1 + }, + { + "mutability": "Mut", + "span": 2 + }, + { + "mutability": "Not", + "span": 2 + }, + { + "mutability": "Not", + "span": 3 + } + ], + "span": 13, + "spread_arg": null, + "var_debug_info": [ + { + "argument_index": 1, + "composite": null, + "name": "main", + "source_info": { + "scope": 0, + "span": 9 + }, + "value": { + "Place": { + "local": 1, + "projection": [] + } + } + }, + { + "argument_index": 2, + "composite": null, + "name": "argc", + "source_info": { + "scope": 0, + "span": 10 + }, + "value": { + "Place": { + "local": 2, + "projection": [] + } + } + }, + { + "argument_index": 3, + "composite": null, + "name": "argv", + "source_info": { + "scope": 0, + "span": 11 + }, + "value": { + "Place": { + "local": 3, + "projection": [] + } + } + }, + { + "argument_index": 4, + "composite": null, + "name": "sigpipe", + "source_info": { + "scope": 0, + "span": 12 + }, + "value": { + "Place": { + "local": 4, + "projection": [] + } + } + }, + { + "argument_index": null, + "composite": null, + "name": "v", + "source_info": { + "scope": 1, + "span": 6 + }, + "value": { + "Place": { + "local": 0, + "projection": [] + } + } + } + ] + }, + "id": 0, + "name": "std::rt::lang_start::<()>" + } + }, + "symbol_name": "_ZN3std2rt10lang_start17h" + }, + { + "details": null, + "mono_item_kind": { + "MonoItemFn": { + "body": { + "arg_count": 4, + "blocks": [ + { + "statements": [ + { + "kind": { + "StorageLive": 5 + }, + "span": 77 + }, + { + "kind": { + "Assign": [ + { + "local": 6, + "projection": [] + }, + { + "Ref": [ + { + "kind": "ReErased" + }, + "Shared", + { + "local": 2, + "projection": [] + } + ] + } + ] + }, + "span": 77 + }, + { + "kind": { + "Assign": [ + { + "local": 5, + "projection": [] + }, + { + "Cast": [ + { + "PointerCoercion": "Unsize" + }, + { + "Copy": { + "local": 6, + "projection": [] + } + }, + 36 + ] + } + ] + }, + "span": 77 + }, + { + "kind": { + "StorageLive": 7 + }, + "span": 78 + }, + { + "kind": { + "Assign": [ + { + "local": 8, + "projection": [] + }, + { + "Ref": [ + { + "kind": "ReErased" + }, + "Shared", + { + "local": 3, + "projection": [] + } + ] + } + ] + }, + "span": 78 + }, + { + "kind": { + "Assign": [ + { + "local": 7, + "projection": [] + }, + { + "Cast": [ + { + "PointerCoercion": "Unsize" + }, + { + "Copy": { + "local": 8, + "projection": [] + } + }, + 36 + ] + } + ] + }, + "span": 78 + } + ], + "terminator": { + "kind": { + "Call": { + "args": [ + { + "Move": { + "local": 1, + "projection": [] + } + }, + { + "Move": { + "local": 5, + "projection": [] + } + }, + { + "Move": { + "local": 7, + "projection": [] + } + }, + { + "Move": { + "local": 4, + "projection": [] + } + } + ], + "destination": { + "local": 0, + "projection": [] + }, + "func": { + "Constant": { + "const_": { + "id": 14, + "kind": "ZeroSized" + }, + "span": 75, + "user_ty": null + } + }, + "target": null, + "unwind": "Continue" + } + }, + "span": 76 + } + } + ], + "locals": [ + { + "mutability": "Mut", + "span": 79 + }, + { + "mutability": "Not", + "span": 80 + }, + { + "mutability": "Not", + "span": 81 + }, + { + "mutability": "Not", + "span": 82 + }, + { + "mutability": "Not", + "span": 83 + }, + { + "mutability": "Mut", + "span": 77 + }, + { + "mutability": "Not", + "span": 77 + }, + { + "mutability": "Mut", + "span": 78 + }, + { + "mutability": "Not", + "span": 78 + } + ], + "span": 84, + "spread_arg": null, + "var_debug_info": [ + { + "argument_index": 1, + "composite": null, + "name": "kind", + "source_info": { + "scope": 0, + "span": 80 + }, + "value": { + "Place": { + "local": 1, + "projection": [] + } + } + }, + { + "argument_index": 2, + "composite": null, + "name": "left", + "source_info": { + "scope": 0, + "span": 81 + }, + "value": { + "Place": { + "local": 2, + "projection": [] + } + } + }, + { + "argument_index": 3, + "composite": null, + "name": "right", + "source_info": { + "scope": 0, + "span": 82 + }, + "value": { + "Place": { + "local": 3, + "projection": [] + } + } + }, + { + "argument_index": 4, + "composite": null, + "name": "args", + "source_info": { + "scope": 0, + "span": 83 + }, + "value": { + "Place": { + "local": 4, + "projection": [] + } + } + } + ] + }, + "id": 7, + "name": "core::panicking::assert_failed::" + } + }, + "symbol_name": "_ZN4core9panicking13assert_failed17h" + } + ], + "types": [ + [ + { + "PrimitiveType": "Bool" + } + ], + [ + { + "PrimitiveType": "Char" + } + ], + [ + { + "PrimitiveType": "Str" + } + ], + [ + { + "PrimitiveType": { + "Int": "I32" + } + } + ], + [ + { + "PrimitiveType": { + "Int": "Isize" + } + } + ], + [ + { + "PrimitiveType": { + "Uint": "U32" + } + } + ], + [ + { + "PrimitiveType": { + "Uint": "U8" + } + } + ], + [ + { + "PrimitiveType": { + "Uint": "Usize" + } + } + ], + [ + { + "EnumType": { + "discriminants": [ + 0, + 1, + 2, + 3 + ], + "fields": "elided", + "layout": { + "abi": { + "Scalar": { + "Initialized": { + "valid_range": { + "end": 3, + "start": 0 + }, + "value": { + "Int": { + "length": "I8", + "signed": false + } + } + } + } + }, + "abi_align": 1, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 0 + } + ] + } + }, + "size": { + "num_bits": 8 + }, + "variants": { + "Multiple": { + "tag": { + "Initialized": { + "valid_range": { + "end": 3, + "start": 0 + }, + "value": { + "Int": { + "length": "I8", + "signed": false + } + } + } + }, + "tag_encoding": "Direct", + "tag_field": 0, + "variants": [ + { + "abi": { + "Aggregate": { + "sized": true + } + }, + "abi_align": 1, + "fields": { + "Arbitrary": { + "offsets": [] + } + }, + "size": { + "num_bits": 8 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + { + "abi": { + "Aggregate": { + "sized": true + } + }, + "abi_align": 1, + "fields": { + "Arbitrary": { + "offsets": [] + } + }, + "size": { + "num_bits": 8 + }, + "variants": { + "Single": { + "index": 1 + } + } + }, + { + "abi": { + "Aggregate": { + "sized": true + } + }, + "abi_align": 1, + "fields": { + "Arbitrary": { + "offsets": [] + } + }, + "size": { + "num_bits": 8 + }, + "variants": { + "Single": { + "index": 2 + } + } + }, + { + "abi": { + "Aggregate": { + "sized": true + } + }, + "abi_align": 1, + "fields": { + "Arbitrary": { + "offsets": [] + } + }, + "size": { + "num_bits": 8 + }, + "variants": { + "Single": { + "index": 3 + } + } + } + ] + } + } + }, + "name": "core::fmt::rt::Alignment" + } + } + ], + [ + { + "EnumType": { + "discriminants": [ + 0, + 1 + ], + "fields": "elided", + "layout": { + "abi": { + "Aggregate": { + "sized": true + } + }, + "abi_align": 8, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 0 + } + ] + } + }, + "size": { + "num_bits": 128 + }, + "variants": { + "Multiple": { + "tag": { + "Initialized": { + "valid_range": { + "end": 0, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + }, + "tag_encoding": { + "Niche": { + "niche_start": 0, + "niche_variants": { + "end": 1, + "start": 1 + }, + "untagged_variant": 0 + } + }, + "tag_field": 0, + "variants": [ + { + "abi": { + "ScalarPair": [ + { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + }, + { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + } + ] + }, + "abi_align": 8, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 0 + }, + { + "num_bits": 64 + }, + { + "num_bits": 128 + } + ] + } + }, + "size": { + "num_bits": 128 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + { + "abi": { + "Aggregate": { + "sized": true + } + }, + "abi_align": 8, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 64 + } + ] + } + }, + "size": { + "num_bits": 128 + }, + "variants": { + "Single": { + "index": 1 + } + } + } + ] + } + } + }, + "name": "core::fmt::rt::ArgumentType<'_>" + } + } + ], + [ + { + "EnumType": { + "discriminants": [ + 0, + 1, + 2 + ], + "fields": "elided", + "layout": { + "abi": { + "ScalarPair": [ + { + "Initialized": { + "valid_range": { + "end": 2, + "start": 0 + }, + "value": { + "Int": { + "length": "I64", + "signed": false + } + } + } + }, + { + "Union": { + "value": { + "Int": { + "length": "I64", + "signed": false + } + } + } + } + ] + }, + "abi_align": 8, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 0 + } + ] + } + }, + "size": { + "num_bits": 128 + }, + "variants": { + "Multiple": { + "tag": { + "Initialized": { + "valid_range": { + "end": 2, + "start": 0 + }, + "value": { + "Int": { + "length": "I64", + "signed": false + } + } + } + }, + "tag_encoding": "Direct", + "tag_field": 0, + "variants": [ + { + "abi": { + "ScalarPair": [ + { + "Initialized": { + "valid_range": { + "end": 2, + "start": 0 + }, + "value": { + "Int": { + "length": "I64", + "signed": false + } + } + } + }, + { + "Union": { + "value": { + "Int": { + "length": "I64", + "signed": false + } + } + } + } + ] + }, + "abi_align": 8, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 64 + } + ] + } + }, + "size": { + "num_bits": 128 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + { + "abi": { + "ScalarPair": [ + { + "Initialized": { + "valid_range": { + "end": 2, + "start": 0 + }, + "value": { + "Int": { + "length": "I64", + "signed": false + } + } + } + }, + { + "Union": { + "value": { + "Int": { + "length": "I64", + "signed": false + } + } + } + } + ] + }, + "abi_align": 8, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 64 + } + ] + } + }, + "size": { + "num_bits": 128 + }, + "variants": { + "Single": { + "index": 1 + } + } + }, + { + "abi": { + "Aggregate": { + "sized": true + } + }, + "abi_align": 1, + "fields": { + "Arbitrary": { + "offsets": [] + } + }, + "size": { + "num_bits": 64 + }, + "variants": { + "Single": { + "index": 2 + } + } + } + ] + } + } + }, + "name": "core::fmt::rt::Count" + } + } + ], + [ + { + "EnumType": { + "discriminants": [ + 0, + 1, + 2 + ], + "fields": "elided", + "layout": { + "abi": { + "Scalar": { + "Initialized": { + "valid_range": { + "end": 2, + "start": 0 + }, + "value": { + "Int": { + "length": "I8", + "signed": false + } + } + } + } + }, + "abi_align": 1, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 0 + } + ] + } + }, + "size": { + "num_bits": 8 + }, + "variants": { + "Multiple": { + "tag": { + "Initialized": { + "valid_range": { + "end": 2, + "start": 0 + }, + "value": { + "Int": { + "length": "I8", + "signed": false + } + } + } + }, + "tag_encoding": "Direct", + "tag_field": 0, + "variants": [ + { + "abi": { + "Aggregate": { + "sized": true + } + }, + "abi_align": 1, + "fields": { + "Arbitrary": { + "offsets": [] + } + }, + "size": { + "num_bits": 8 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + { + "abi": { + "Aggregate": { + "sized": true + } + }, + "abi_align": 1, + "fields": { + "Arbitrary": { + "offsets": [] + } + }, + "size": { + "num_bits": 8 + }, + "variants": { + "Single": { + "index": 1 + } + } + }, + { + "abi": { + "Aggregate": { + "sized": true + } + }, + "abi_align": 1, + "fields": { + "Arbitrary": { + "offsets": [] + } + }, + "size": { + "num_bits": 8 + }, + "variants": { + "Single": { + "index": 2 + } + } + } + ] + } + } + }, + "name": "core::panicking::AssertKind" + } + } + ], + [ + { + "EnumType": { + "discriminants": [ + 0, + 1 + ], + "fields": "elided", + "layout": { + "abi": { + "ScalarPair": [ + { + "Initialized": { + "valid_range": { + "end": 0, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + }, + { + "Union": { + "value": { + "Int": { + "length": "I64", + "signed": false + } + } + } + } + ] + }, + "abi_align": 8, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 0 + } + ] + } + }, + "size": { + "num_bits": 128 + }, + "variants": { + "Multiple": { + "tag": { + "Initialized": { + "valid_range": { + "end": 0, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + }, + "tag_encoding": { + "Niche": { + "niche_start": 0, + "niche_variants": { + "end": 0, + "start": 0 + }, + "untagged_variant": 1 + } + }, + "tag_field": 0, + "variants": [ + { + "abi": { + "Aggregate": { + "sized": true + } + }, + "abi_align": 1, + "fields": { + "Arbitrary": { + "offsets": [] + } + }, + "size": { + "num_bits": 0 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + { + "abi": { + "ScalarPair": [ + { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + }, + { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 0 + }, + "value": { + "Int": { + "length": "I64", + "signed": false + } + } + } + } + ] + }, + "abi_align": 8, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 0 + } + ] + } + }, + "size": { + "num_bits": 128 + }, + "variants": { + "Single": { + "index": 1 + } + } + } + ] + } + } + }, + "name": "std::option::Option<&[core::fmt::rt::Placeholder]>" + } + } + ], + [ + { + "EnumType": { + "discriminants": [ + 0, + 1 + ], + "fields": "elided", + "layout": { + "abi": { + "Aggregate": { + "sized": true + } + }, + "abi_align": 8, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 0 + } + ] + } + }, + "size": { + "num_bits": 384 + }, + "variants": { + "Multiple": { + "tag": { + "Initialized": { + "valid_range": { + "end": 0, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + }, + "tag_encoding": { + "Niche": { + "niche_start": 0, + "niche_variants": { + "end": 0, + "start": 0 + }, + "untagged_variant": 1 + } + }, + "tag_field": 0, + "variants": [ + { + "abi": { + "Aggregate": { + "sized": true + } + }, + "abi_align": 1, + "fields": { + "Arbitrary": { + "offsets": [] + } + }, + "size": { + "num_bits": 0 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + { + "abi": { + "Aggregate": { + "sized": true + } + }, + "abi_align": 8, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 0 + } + ] + } + }, + "size": { + "num_bits": 384 + }, + "variants": { + "Single": { + "index": 1 + } + } + } + ] + } + } + }, + "name": "std::option::Option>" + } + } + ], + [ + { + "EnumType": { + "discriminants": [ + 0, + 1 + ], + "fields": "elided", + "layout": { + "abi": { + "ScalarPair": [ + { + "Initialized": { + "valid_range": { + "end": 1, + "start": 0 + }, + "value": { + "Int": { + "length": "I64", + "signed": false + } + } + } + }, + { + "Union": { + "value": { + "Int": { + "length": "I64", + "signed": false + } + } + } + } + ] + }, + "abi_align": 8, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 0 + } + ] + } + }, + "size": { + "num_bits": 128 + }, + "variants": { + "Multiple": { + "tag": { + "Initialized": { + "valid_range": { + "end": 1, + "start": 0 + }, + "value": { + "Int": { + "length": "I64", + "signed": false + } + } + } + }, + "tag_encoding": "Direct", + "tag_field": 0, + "variants": [ + { + "abi": { + "Aggregate": { + "sized": true + } + }, + "abi_align": 1, + "fields": { + "Arbitrary": { + "offsets": [] + } + }, + "size": { + "num_bits": 64 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + { + "abi": { + "ScalarPair": [ + { + "Initialized": { + "valid_range": { + "end": 1, + "start": 0 + }, + "value": { + "Int": { + "length": "I64", + "signed": false + } + } + } + }, + { + "Union": { + "value": { + "Int": { + "length": "I64", + "signed": false + } + } + } + } + ] + }, + "abi_align": 8, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 64 + } + ] + } + }, + "size": { + "num_bits": 128 + }, + "variants": { + "Single": { + "index": 1 + } + } + } + ] + } + } + }, + "name": "std::option::Option" + } + } + ], + [ + { + "EnumType": { + "discriminants": [ + 0, + 1 + ], + "fields": "elided", + "layout": { + "abi": { + "Scalar": { + "Initialized": { + "valid_range": { + "end": 1, + "start": 0 + }, + "value": { + "Int": { + "length": "I8", + "signed": false + } + } + } + } + }, + "abi_align": 1, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 0 + } + ] + } + }, + "size": { + "num_bits": 8 + }, + "variants": { + "Multiple": { + "tag": { + "Initialized": { + "valid_range": { + "end": 1, + "start": 0 + }, + "value": { + "Int": { + "length": "I8", + "signed": false + } + } + } + }, + "tag_encoding": "Direct", + "tag_field": 0, + "variants": [ + { + "abi": { + "Scalar": { + "Initialized": { + "valid_range": { + "end": 1, + "start": 0 + }, + "value": { + "Int": { + "length": "I8", + "signed": false + } + } + } + } + }, + "abi_align": 1, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 8 + } + ] + } + }, + "size": { + "num_bits": 8 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + { + "abi": { + "Scalar": { + "Initialized": { + "valid_range": { + "end": 1, + "start": 0 + }, + "value": { + "Int": { + "length": "I8", + "signed": false + } + } + } + } + }, + "abi_align": 1, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 8 + } + ] + } + }, + "size": { + "num_bits": 8 + }, + "variants": { + "Single": { + "index": 1 + } + } + } + ] + } + } + }, + "name": "std::result::Result<(), std::fmt::Error>" + } + } + ], + [ + { + "EnumType": { + "discriminants": [ + 0, + 1 + ], + "fields": "elided", + "layout": { + "abi": { + "Scalar": { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 0 + }, + "value": { + "Int": { + "length": "I64", + "signed": true + } + } + } + } + }, + "abi_align": 8, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 0 + } + ] + } + }, + "size": { + "num_bits": 64 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "name": "std::result::Result" + } + } + ], + [ + { + "StructType": { + "fields": "elided", + "layout": { + "abi": { + "Aggregate": { + "sized": true + } + }, + "abi_align": 8, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 0 + } + ] + } + }, + "size": { + "num_bits": 128 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "name": "core::fmt::rt::Argument<'_>" + } + } + ], + [ + { + "StructType": { + "fields": "elided", + "layout": { + "abi": { + "Aggregate": { + "sized": true + } + }, + "abi_align": 8, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 256 + }, + { + "num_bits": 320 + }, + { + "num_bits": 384 + }, + { + "num_bits": 352 + }, + { + "num_bits": 0 + }, + { + "num_bits": 128 + } + ] + } + }, + "size": { + "num_bits": 448 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "name": "core::fmt::rt::Placeholder" + } + } + ], + [ + { + "StructType": { + "fields": "elided", + "layout": { + "abi": { + "Aggregate": { + "sized": true + } + }, + "abi_align": 8, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 0 + }, + { + "num_bits": 256 + }, + { + "num_bits": 128 + } + ] + } + }, + "size": { + "num_bits": 384 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "name": "std::fmt::Arguments<'_>" + } + } + ], + [ + { + "StructType": { + "fields": "elided", + "layout": { + "abi": { + "Aggregate": { + "sized": true + } + }, + "abi_align": 1, + "fields": { + "Arbitrary": { + "offsets": [] + } + }, + "size": { + "num_bits": 0 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "name": "std::fmt::Error" + } + } + ], + [ + { + "StructType": { + "fields": "elided", + "layout": { + "abi": { + "Aggregate": { + "sized": true + } + }, + "abi_align": 8, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 416 + }, + { + "num_bits": 384 + }, + { + "num_bits": 448 + }, + { + "num_bits": 0 + }, + { + "num_bits": 128 + }, + { + "num_bits": 256 + } + ] + } + }, + "size": { + "num_bits": 512 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "name": "std::fmt::Formatter<'_>" + } + } + ], + [ + { + "StructType": { + "fields": "elided", + "layout": { + "abi": { + "Aggregate": { + "sized": true + } + }, + "abi_align": 1, + "fields": { + "Arbitrary": { + "offsets": [] + } + }, + "size": { + "num_bits": 0 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "name": "std::marker::PhantomData<&()>" + } + } + ], + [ + { + "StructType": { + "fields": "elided", + "layout": { + "abi": { + "Aggregate": { + "sized": true + } + }, + "abi_align": 8, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 0 + }, + { + "num_bits": 128 + }, + { + "num_bits": 160 + } + ] + } + }, + "size": { + "num_bits": 192 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "name": "std::panic::Location<'_>" + } + } + ], + [ + { + "StructType": { + "fields": "elided", + "layout": { + "abi": { + "Scalar": { + "Initialized": { + "valid_range": { + "end": 255, + "start": 0 + }, + "value": { + "Int": { + "length": "I8", + "signed": false + } + } + } + } + }, + "abi_align": 1, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 0 + } + ] + } + }, + "size": { + "num_bits": 8 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "name": "std::process::ExitCode" + } + } + ], + [ + { + "StructType": { + "fields": "elided", + "layout": { + "abi": { + "Scalar": { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + } + }, + "abi_align": 8, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 0 + } + ] + } + }, + "size": { + "num_bits": 64 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "name": "std::ptr::NonNull<()>" + } + } + ], + [ + { + "StructType": { + "fields": "elided", + "layout": { + "abi": { + "Scalar": { + "Initialized": { + "valid_range": { + "end": 255, + "start": 0 + }, + "value": { + "Int": { + "length": "I8", + "signed": false + } + } + } + } + }, + "abi_align": 1, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 0 + } + ] + } + }, + "size": { + "num_bits": 8 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "name": "std::sys::pal::unix::process::process_common::ExitCode" + } + } + ], + [ + { + "ArrayType": { + "layout": { + "abi": { + "Aggregate": { + "sized": false + } + }, + "abi_align": 8, + "fields": { + "Array": { + "count": 0, + "stride": { + "num_bits": 128 + } + } + }, + "size": { + "num_bits": 0 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "size": null + } + } + ], + [ + { + "ArrayType": { + "layout": { + "abi": { + "Aggregate": { + "sized": false + } + }, + "abi_align": 8, + "fields": { + "Array": { + "count": 0, + "stride": { + "num_bits": 128 + } + } + }, + "size": { + "num_bits": 0 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "size": null + } + } + ], + [ + { + "ArrayType": { + "layout": { + "abi": { + "Aggregate": { + "sized": false + } + }, + "abi_align": 8, + "fields": { + "Array": { + "count": 0, + "stride": { + "num_bits": 448 + } + } + }, + "size": { + "num_bits": 0 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "size": null + } + } + ], + [ + { + "TupleType": { + "layout": { + "abi": { + "Aggregate": { + "sized": true + } + }, + "abi_align": 1, + "fields": { + "Arbitrary": { + "offsets": [] + } + }, + "size": { + "num_bits": 0 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "types": "elided" + } + } + ], + [ + { + "TupleType": { + "layout": { + "abi": { + "ScalarPair": [ + { + "Initialized": { + "valid_range": { + "end": 4294967295, + "start": 0 + }, + "value": { + "Int": { + "length": "I32", + "signed": true + } + } + } + }, + { + "Initialized": { + "valid_range": { + "end": 1, + "start": 0 + }, + "value": { + "Int": { + "length": "I8", + "signed": false + } + } + } + } + ] + }, + "abi_align": 4, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 0 + }, + { + "num_bits": 32 + } + ] + } + }, + "size": { + "num_bits": 64 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "types": "elided" + } + } + ], + [ + { + "TupleType": { + "layout": { + "abi": { + "ScalarPair": [ + { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + }, + { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + } + ] + }, + "abi_align": 8, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 0 + }, + { + "num_bits": 64 + } + ] + } + }, + "size": { + "num_bits": 128 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "types": "elided" + } + } + ], + [ + { + "PtrType": { + "layout": { + "abi": { + "Scalar": { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 0 + }, + "value": { + "Pointer": 0 + } + } + } + }, + "abi_align": 8, + "fields": "Primitive", + "size": { + "num_bits": 64 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "pointee_type": "elided" + } + } + ], + [ + { + "PtrType": { + "layout": { + "abi": { + "Scalar": { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 0 + }, + "value": { + "Pointer": 0 + } + } + } + }, + "abi_align": 8, + "fields": "Primitive", + "size": { + "num_bits": 64 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "pointee_type": "elided" + } + } + ], + [ + { + "PtrType": { + "layout": { + "abi": { + "Scalar": { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 0 + }, + "value": { + "Pointer": 0 + } + } + } + }, + "abi_align": 8, + "fields": "Primitive", + "size": { + "num_bits": 64 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "pointee_type": "elided" + } + } + ], + [ + { + "PtrType": { + "layout": { + "abi": { + "Scalar": { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 0 + }, + "value": { + "Pointer": 0 + } + } + } + }, + "abi_align": 8, + "fields": "Primitive", + "size": { + "num_bits": 64 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "pointee_type": "elided" + } + } + ], + [ + { + "PtrType": { + "layout": { + "abi": { + "Scalar": { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 0 + }, + "value": { + "Pointer": 0 + } + } + } + }, + "abi_align": 8, + "fields": "Primitive", + "size": { + "num_bits": 64 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "pointee_type": "elided" + } + } + ], + [ + { + "RefType": { + "layout": { + "abi": { + "Scalar": { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + } + }, + "abi_align": 8, + "fields": "Primitive", + "size": { + "num_bits": 64 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "pointee_type": "elided" + } + } + ], + [ + { + "RefType": { + "layout": { + "abi": { + "Scalar": { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + } + }, + "abi_align": 8, + "fields": "Primitive", + "size": { + "num_bits": 64 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "pointee_type": "elided" + } + } + ], + [ + { + "RefType": { + "layout": { + "abi": { + "Scalar": { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + } + }, + "abi_align": 8, + "fields": "Primitive", + "size": { + "num_bits": 64 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "pointee_type": "elided" + } + } + ], + [ + { + "RefType": { + "layout": { + "abi": { + "Scalar": { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + } + }, + "abi_align": 8, + "fields": "Primitive", + "size": { + "num_bits": 64 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "pointee_type": "elided" + } + } + ], + [ + { + "RefType": { + "layout": { + "abi": { + "Scalar": { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + } + }, + "abi_align": 8, + "fields": "Primitive", + "size": { + "num_bits": 64 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "pointee_type": "elided" + } + } + ], + [ + { + "RefType": { + "layout": { + "abi": { + "Scalar": { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + } + }, + "abi_align": 8, + "fields": "Primitive", + "size": { + "num_bits": 64 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "pointee_type": "elided" + } + } + ], + [ + { + "RefType": { + "layout": { + "abi": { + "Scalar": { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + } + }, + "abi_align": 8, + "fields": "Primitive", + "size": { + "num_bits": 64 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "pointee_type": "elided" + } + } + ], + [ + { + "RefType": { + "layout": { + "abi": { + "Scalar": { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + } + }, + "abi_align": 8, + "fields": "Primitive", + "size": { + "num_bits": 64 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "pointee_type": "elided" + } + } + ], + [ + { + "RefType": { + "layout": { + "abi": { + "ScalarPair": [ + { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + }, + { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 0 + }, + "value": { + "Int": { + "length": "I64", + "signed": false + } + } + } + } + ] + }, + "abi_align": 8, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 0 + }, + { + "num_bits": 64 + } + ] + } + }, + "size": { + "num_bits": 128 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "pointee_type": "elided" + } + } + ], + [ + { + "RefType": { + "layout": { + "abi": { + "ScalarPair": [ + { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + }, + { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 0 + }, + "value": { + "Int": { + "length": "I64", + "signed": false + } + } + } + } + ] + }, + "abi_align": 8, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 0 + }, + { + "num_bits": 64 + } + ] + } + }, + "size": { + "num_bits": 128 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "pointee_type": "elided" + } + } + ], + [ + { + "RefType": { + "layout": { + "abi": { + "ScalarPair": [ + { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + }, + { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 0 + }, + "value": { + "Int": { + "length": "I64", + "signed": false + } + } + } + } + ] + }, + "abi_align": 8, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 0 + }, + { + "num_bits": 64 + } + ] + } + }, + "size": { + "num_bits": 128 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "pointee_type": "elided" + } + } + ], + [ + { + "RefType": { + "layout": { + "abi": { + "ScalarPair": [ + { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + }, + { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 0 + }, + "value": { + "Int": { + "length": "I64", + "signed": false + } + } + } + } + ] + }, + "abi_align": 8, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 0 + }, + { + "num_bits": 64 + } + ] + } + }, + "size": { + "num_bits": 128 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "pointee_type": "elided" + } + } + ], + [ + { + "RefType": { + "layout": { + "abi": { + "ScalarPair": [ + { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + }, + { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + } + ] + }, + "abi_align": 8, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 0 + }, + { + "num_bits": 64 + } + ] + } + }, + "size": { + "num_bits": 128 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "pointee_type": "elided" + } + } + ], + [ + { + "RefType": { + "layout": { + "abi": { + "ScalarPair": [ + { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + }, + { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + } + ] + }, + "abi_align": 8, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 0 + }, + { + "num_bits": 64 + } + ] + } + }, + "size": { + "num_bits": 128 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "pointee_type": "elided" + } + } + ], + [ + { + "RefType": { + "layout": { + "abi": { + "ScalarPair": [ + { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + }, + { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + } + ] + }, + "abi_align": 8, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 0 + }, + { + "num_bits": 64 + } + ] + } + }, + "size": { + "num_bits": 128 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "pointee_type": "elided" + } + } + ] + ] +} diff --git a/tests/integration/programs/unevaluated-const.rs b/tests/integration/programs/unevaluated-const.rs new file mode 100644 index 00000000..953d8e57 --- /dev/null +++ b/tests/integration/programs/unevaluated-const.rs @@ -0,0 +1,37 @@ +/// Exercises const evaluation patterns: associated constants in generic +/// contexts and const generic parameters. On the current nightly, all +/// constants are eagerly evaluated during monomorphization (appearing as +/// Allocated or Ty(Value(...)) in stable MIR), so the +/// ConstantKind::Unevaluated path in visit_mir_const is not triggered. +/// This test still exercises the const-adjacent pipeline paths. +trait Stride { + const STEP: usize; +} + +struct By2; +impl Stride for By2 { + const STEP: usize = 2; +} + +struct By3; +impl Stride for By3 { + const STEP: usize = 3; +} + +fn advance(pos: usize) -> usize { + pos + S::STEP +} + +fn make_array() -> [u8; N] { + [0u8; N] +} + +fn main() { + let a = advance::(0); + let b = advance::(10); + assert_eq!(a, 2); + assert_eq!(b, 13); + + let arr = make_array::<4>(); + assert_eq!(arr.len(), 4); +} diff --git a/tests/integration/programs/unevaluated-const.smir.json.expected b/tests/integration/programs/unevaluated-const.smir.json.expected new file mode 100644 index 00000000..2192e190 --- /dev/null +++ b/tests/integration/programs/unevaluated-const.smir.json.expected @@ -0,0 +1,7411 @@ +{ + "allocs": [ + { + "global_alloc": { + "Memory": { + "align": 8, + "bytes": [ + 2, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "mutability": "Not", + "provenance": { + "ptrs": [] + } + } + } + }, + { + "global_alloc": { + "Memory": { + "align": 8, + "bytes": [ + 4, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "mutability": "Not", + "provenance": { + "ptrs": [] + } + } + } + }, + { + "global_alloc": { + "Memory": { + "align": 8, + "bytes": [ + 13, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "mutability": "Not", + "provenance": { + "ptrs": [] + } + } + } + } + ], + "functions": [ + [ + { + "IntrinsicSym": "black_box" + } + ], + [ + { + "NoOpSym": "" + } + ], + [ + { + "NormalSym": "_ZN17unevaluated_const10make_array17h" + } + ], + [ + { + "NormalSym": "_ZN17unevaluated_const7advance17h" + } + ], + [ + { + "NormalSym": "_ZN17unevaluated_const7advance17h" + } + ], + [ + { + "NormalSym": "_ZN3std2rt10lang_start28_$u7b$$u7b$closure$u7d$$u7d$17h" + } + ], + [ + { + "NormalSym": "_ZN3std2rt19lang_start_internal17h" + } + ], + [ + { + "NormalSym": "_ZN3std3sys9backtrace28__rust_begin_short_backtrace17h" + } + ], + [ + { + "NormalSym": "_ZN4core3fmt3num3imp54_$LT$impl$u20$core..fmt..Display$u20$for$u20$usize$GT$3fmt17h" + } + ], + [ + { + "NormalSym": "_ZN4core3fmt3num52_$LT$impl$u20$core..fmt..Debug$u20$for$u20$usize$GT$3fmt17h" + } + ], + [ + { + "NormalSym": "_ZN4core3fmt3num55_$LT$impl$u20$core..fmt..LowerHex$u20$for$u20$usize$GT$3fmt17h" + } + ], + [ + { + "NormalSym": "_ZN4core3fmt3num55_$LT$impl$u20$core..fmt..UpperHex$u20$for$u20$usize$GT$3fmt17h" + } + ], + [ + { + "NormalSym": "_ZN4core3ops8function6FnOnce9call_once17h" + } + ], + [ + { + "NormalSym": "_ZN4core3ops8function6FnOnce9call_once17h" + } + ], + [ + { + "NormalSym": "_ZN4core9panicking13assert_failed17h" + } + ], + [ + { + "NormalSym": "_ZN4core9panicking19assert_failed_inner17h" + } + ], + [ + { + "NormalSym": "_ZN54_$LT$$LP$$RP$$u20$as$u20$std..process..Termination$GT$6report17h" + } + ] + ], + "items": [ + { + "details": null, + "mono_item_kind": { + "MonoItemFn": { + "body": { + "arg_count": 0, + "blocks": [ + { + "statements": [], + "terminator": { + "kind": { + "Call": { + "args": [ + { + "Constant": { + "const_": { + "id": 20, + "kind": { + "Allocated": { + "align": 8, + "bytes": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "mutability": "Mut", + "provenance": { + "ptrs": [] + } + } + } + }, + "span": 102, + "user_ty": null + } + } + ], + "destination": { + "local": 1, + "projection": [] + }, + "func": { + "Constant": { + "const_": { + "id": 19, + "kind": "ZeroSized" + }, + "span": 101, + "user_ty": null + } + }, + "target": 1, + "unwind": "Continue" + } + }, + "span": 103 + } + }, + { + "statements": [], + "terminator": { + "kind": { + "Call": { + "args": [ + { + "Constant": { + "const_": { + "id": 22, + "kind": { + "Allocated": { + "align": 8, + "bytes": [ + 10, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "mutability": "Mut", + "provenance": { + "ptrs": [] + } + } + } + }, + "span": 105, + "user_ty": null + } + } + ], + "destination": { + "local": 2, + "projection": [] + }, + "func": { + "Constant": { + "const_": { + "id": 21, + "kind": "ZeroSized" + }, + "span": 104, + "user_ty": null + } + }, + "target": 2, + "unwind": "Continue" + } + }, + "span": 106 + } + }, + { + "statements": [ + { + "kind": { + "Assign": [ + { + "local": 4, + "projection": [] + }, + { + "Ref": [ + { + "kind": "ReErased" + }, + "Shared", + { + "local": 1, + "projection": [] + } + ] + } + ] + }, + "span": 108 + }, + { + "kind": { + "Assign": [ + { + "local": 5, + "projection": [] + }, + { + "Use": { + "Constant": { + "const_": { + "id": 23, + "kind": { + "Allocated": { + "align": 8, + "bytes": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "mutability": "Mut", + "provenance": { + "ptrs": [ + [ + 0, + 0 + ] + ] + } + } + } + }, + "span": 109, + "user_ty": null + } + } + } + ] + }, + "span": 109 + }, + { + "kind": { + "Assign": [ + { + "local": 3, + "projection": [] + }, + { + "Aggregate": [ + "Tuple", + [ + { + "Move": { + "local": 4, + "projection": [] + } + }, + { + "Move": { + "local": 5, + "projection": [] + } + } + ] + ] + } + ] + }, + "span": 110 + }, + { + "kind": { + "Assign": [ + { + "local": 6, + "projection": [] + }, + { + "Use": { + "Copy": { + "local": 3, + "projection": [ + { + "Field": [ + 0, + 25 + ] + } + ] + } + } + } + ] + }, + "span": 111 + }, + { + "kind": { + "Assign": [ + { + "local": 7, + "projection": [] + }, + { + "Use": { + "Copy": { + "local": 3, + "projection": [ + { + "Field": [ + 1, + 25 + ] + } + ] + } + } + } + ] + }, + "span": 112 + }, + { + "kind": { + "Assign": [ + { + "local": 9, + "projection": [] + }, + { + "Use": { + "Copy": { + "local": 6, + "projection": [ + "Deref" + ] + } + } + } + ] + }, + "span": 113 + }, + { + "kind": { + "Assign": [ + { + "local": 10, + "projection": [] + }, + { + "Use": { + "Copy": { + "local": 7, + "projection": [ + "Deref" + ] + } + } + } + ] + }, + "span": 114 + }, + { + "kind": { + "Assign": [ + { + "local": 8, + "projection": [] + }, + { + "BinaryOp": [ + "Eq", + { + "Move": { + "local": 9, + "projection": [] + } + }, + { + "Move": { + "local": 10, + "projection": [] + } + } + ] + } + ] + }, + "span": 107 + } + ], + "terminator": { + "kind": { + "SwitchInt": { + "discr": { + "Move": { + "local": 8, + "projection": [] + } + }, + "targets": { + "branches": [ + [ + 0, + 4 + ] + ], + "otherwise": 3 + } + } + }, + "span": 107 + } + }, + { + "statements": [ + { + "kind": { + "Assign": [ + { + "local": 15, + "projection": [] + }, + { + "Ref": [ + { + "kind": "ReErased" + }, + "Shared", + { + "local": 2, + "projection": [] + } + ] + } + ] + }, + "span": 116 + }, + { + "kind": { + "Assign": [ + { + "local": 16, + "projection": [] + }, + { + "Use": { + "Constant": { + "const_": { + "id": 24, + "kind": { + "Allocated": { + "align": 8, + "bytes": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "mutability": "Mut", + "provenance": { + "ptrs": [ + [ + 0, + 1 + ] + ] + } + } + } + }, + "span": 117, + "user_ty": null + } + } + } + ] + }, + "span": 117 + }, + { + "kind": { + "Assign": [ + { + "local": 14, + "projection": [] + }, + { + "Aggregate": [ + "Tuple", + [ + { + "Move": { + "local": 15, + "projection": [] + } + }, + { + "Move": { + "local": 16, + "projection": [] + } + } + ] + ] + } + ] + }, + "span": 118 + }, + { + "kind": { + "Assign": [ + { + "local": 17, + "projection": [] + }, + { + "Use": { + "Copy": { + "local": 14, + "projection": [ + { + "Field": [ + 0, + 25 + ] + } + ] + } + } + } + ] + }, + "span": 119 + }, + { + "kind": { + "Assign": [ + { + "local": 18, + "projection": [] + }, + { + "Use": { + "Copy": { + "local": 14, + "projection": [ + { + "Field": [ + 1, + 25 + ] + } + ] + } + } + } + ] + }, + "span": 120 + }, + { + "kind": { + "Assign": [ + { + "local": 20, + "projection": [] + }, + { + "Use": { + "Copy": { + "local": 17, + "projection": [ + "Deref" + ] + } + } + } + ] + }, + "span": 121 + }, + { + "kind": { + "Assign": [ + { + "local": 21, + "projection": [] + }, + { + "Use": { + "Copy": { + "local": 18, + "projection": [ + "Deref" + ] + } + } + } + ] + }, + "span": 122 + }, + { + "kind": { + "Assign": [ + { + "local": 19, + "projection": [] + }, + { + "BinaryOp": [ + "Eq", + { + "Move": { + "local": 20, + "projection": [] + } + }, + { + "Move": { + "local": 21, + "projection": [] + } + } + ] + } + ] + }, + "span": 115 + } + ], + "terminator": { + "kind": { + "SwitchInt": { + "discr": { + "Move": { + "local": 19, + "projection": [] + } + }, + "targets": { + "branches": [ + [ + 0, + 6 + ] + ], + "otherwise": 5 + } + } + }, + "span": 115 + } + }, + { + "statements": [ + { + "kind": { + "Assign": [ + { + "local": 11, + "projection": [] + }, + { + "Aggregate": [ + { + "Adt": [ + 12, + 0, + [], + null, + null + ] + }, + [] + ] + } + ] + }, + "span": 125 + }, + { + "kind": { + "Assign": [ + { + "local": 13, + "projection": [] + }, + { + "Aggregate": [ + { + "Adt": [ + 13, + 0, + [ + { + "Type": 47 + } + ], + null, + null + ] + }, + [] + ] + } + ] + }, + "span": 126 + } + ], + "terminator": { + "kind": { + "Call": { + "args": [ + { + "Move": { + "local": 11, + "projection": [] + } + }, + { + "Copy": { + "local": 6, + "projection": [] + } + }, + { + "Copy": { + "local": 7, + "projection": [] + } + }, + { + "Move": { + "local": 13, + "projection": [] + } + } + ], + "destination": { + "local": 12, + "projection": [] + }, + "func": { + "Constant": { + "const_": { + "id": 25, + "kind": "ZeroSized" + }, + "span": 123, + "user_ty": null + } + }, + "target": null, + "unwind": "Continue" + } + }, + "span": 124 + } + }, + { + "statements": [], + "terminator": { + "kind": { + "Call": { + "args": [], + "destination": { + "local": 25, + "projection": [] + }, + "func": { + "Constant": { + "const_": { + "id": 26, + "kind": "ZeroSized" + }, + "span": 127, + "user_ty": null + } + }, + "target": 7, + "unwind": "Continue" + } + }, + "span": 128 + } + }, + { + "statements": [ + { + "kind": { + "Assign": [ + { + "local": 22, + "projection": [] + }, + { + "Aggregate": [ + { + "Adt": [ + 12, + 0, + [], + null, + null + ] + }, + [] + ] + } + ] + }, + "span": 131 + }, + { + "kind": { + "Assign": [ + { + "local": 24, + "projection": [] + }, + { + "Aggregate": [ + { + "Adt": [ + 13, + 0, + [ + { + "Type": 47 + } + ], + null, + null + ] + }, + [] + ] + } + ] + }, + "span": 132 + } + ], + "terminator": { + "kind": { + "Call": { + "args": [ + { + "Move": { + "local": 22, + "projection": [] + } + }, + { + "Copy": { + "local": 17, + "projection": [] + } + }, + { + "Copy": { + "local": 18, + "projection": [] + } + }, + { + "Move": { + "local": 24, + "projection": [] + } + } + ], + "destination": { + "local": 23, + "projection": [] + }, + "func": { + "Constant": { + "const_": { + "id": 25, + "kind": "ZeroSized" + }, + "span": 129, + "user_ty": null + } + }, + "target": null, + "unwind": "Continue" + } + }, + "span": 130 + } + }, + { + "statements": [ + { + "kind": { + "Assign": [ + { + "local": 30, + "projection": [] + }, + { + "Ref": [ + { + "kind": "ReErased" + }, + "Shared", + { + "local": 25, + "projection": [] + } + ] + } + ] + }, + "span": 134 + }, + { + "kind": { + "Assign": [ + { + "local": 29, + "projection": [] + }, + { + "Cast": [ + { + "PointerCoercion": "Unsize" + }, + { + "Move": { + "local": 30, + "projection": [] + } + }, + 49 + ] + } + ] + }, + "span": 134 + }, + { + "kind": { + "Assign": [ + { + "local": 28, + "projection": [] + }, + { + "UnaryOp": [ + "PtrMetadata", + { + "Move": { + "local": 29, + "projection": [] + } + } + ] + } + ] + }, + "span": 135 + }, + { + "kind": { + "Assign": [ + { + "local": 27, + "projection": [] + }, + { + "Ref": [ + { + "kind": "ReErased" + }, + "Shared", + { + "local": 28, + "projection": [] + } + ] + } + ] + }, + "span": 136 + }, + { + "kind": { + "Assign": [ + { + "local": 31, + "projection": [] + }, + { + "Use": { + "Constant": { + "const_": { + "id": 27, + "kind": { + "Allocated": { + "align": 8, + "bytes": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "mutability": "Mut", + "provenance": { + "ptrs": [ + [ + 0, + 2 + ] + ] + } + } + } + }, + "span": 137, + "user_ty": null + } + } + } + ] + }, + "span": 137 + }, + { + "kind": { + "Assign": [ + { + "local": 26, + "projection": [] + }, + { + "Aggregate": [ + "Tuple", + [ + { + "Move": { + "local": 27, + "projection": [] + } + }, + { + "Move": { + "local": 31, + "projection": [] + } + } + ] + ] + } + ] + }, + "span": 138 + }, + { + "kind": { + "Assign": [ + { + "local": 32, + "projection": [] + }, + { + "Use": { + "Copy": { + "local": 26, + "projection": [ + { + "Field": [ + 0, + 25 + ] + } + ] + } + } + } + ] + }, + "span": 139 + }, + { + "kind": { + "Assign": [ + { + "local": 33, + "projection": [] + }, + { + "Use": { + "Copy": { + "local": 26, + "projection": [ + { + "Field": [ + 1, + 25 + ] + } + ] + } + } + } + ] + }, + "span": 140 + }, + { + "kind": { + "Assign": [ + { + "local": 35, + "projection": [] + }, + { + "Use": { + "Copy": { + "local": 32, + "projection": [ + "Deref" + ] + } + } + } + ] + }, + "span": 141 + }, + { + "kind": { + "Assign": [ + { + "local": 36, + "projection": [] + }, + { + "Use": { + "Copy": { + "local": 33, + "projection": [ + "Deref" + ] + } + } + } + ] + }, + "span": 142 + }, + { + "kind": { + "Assign": [ + { + "local": 34, + "projection": [] + }, + { + "BinaryOp": [ + "Eq", + { + "Move": { + "local": 35, + "projection": [] + } + }, + { + "Move": { + "local": 36, + "projection": [] + } + } + ] + } + ] + }, + "span": 133 + } + ], + "terminator": { + "kind": { + "SwitchInt": { + "discr": { + "Move": { + "local": 34, + "projection": [] + } + }, + "targets": { + "branches": [ + [ + 0, + 9 + ] + ], + "otherwise": 8 + } + } + }, + "span": 133 + } + }, + { + "statements": [], + "terminator": { + "kind": "Return", + "span": 143 + } + }, + { + "statements": [ + { + "kind": { + "Assign": [ + { + "local": 37, + "projection": [] + }, + { + "Aggregate": [ + { + "Adt": [ + 12, + 0, + [], + null, + null + ] + }, + [] + ] + } + ] + }, + "span": 146 + }, + { + "kind": { + "Assign": [ + { + "local": 39, + "projection": [] + }, + { + "Aggregate": [ + { + "Adt": [ + 13, + 0, + [ + { + "Type": 47 + } + ], + null, + null + ] + }, + [] + ] + } + ] + }, + "span": 147 + } + ], + "terminator": { + "kind": { + "Call": { + "args": [ + { + "Move": { + "local": 37, + "projection": [] + } + }, + { + "Copy": { + "local": 32, + "projection": [] + } + }, + { + "Copy": { + "local": 33, + "projection": [] + } + }, + { + "Move": { + "local": 39, + "projection": [] + } + } + ], + "destination": { + "local": 38, + "projection": [] + }, + "func": { + "Constant": { + "const_": { + "id": 25, + "kind": "ZeroSized" + }, + "span": 144, + "user_ty": null + } + }, + "target": null, + "unwind": "Continue" + } + }, + "span": 145 + } + } + ], + "locals": [ + { + "mutability": "Mut", + "span": 148 + }, + { + "mutability": "Not", + "span": 149 + }, + { + "mutability": "Not", + "span": 150 + }, + { + "mutability": "Mut", + "span": 110 + }, + { + "mutability": "Mut", + "span": 108 + }, + { + "mutability": "Mut", + "span": 109 + }, + { + "mutability": "Not", + "span": 111 + }, + { + "mutability": "Not", + "span": 112 + }, + { + "mutability": "Mut", + "span": 107 + }, + { + "mutability": "Mut", + "span": 113 + }, + { + "mutability": "Mut", + "span": 114 + }, + { + "mutability": "Not", + "span": 151 + }, + { + "mutability": "Not", + "span": 124 + }, + { + "mutability": "Mut", + "span": 126 + }, + { + "mutability": "Mut", + "span": 118 + }, + { + "mutability": "Mut", + "span": 116 + }, + { + "mutability": "Mut", + "span": 117 + }, + { + "mutability": "Not", + "span": 119 + }, + { + "mutability": "Not", + "span": 120 + }, + { + "mutability": "Mut", + "span": 115 + }, + { + "mutability": "Mut", + "span": 121 + }, + { + "mutability": "Mut", + "span": 122 + }, + { + "mutability": "Not", + "span": 152 + }, + { + "mutability": "Not", + "span": 130 + }, + { + "mutability": "Mut", + "span": 132 + }, + { + "mutability": "Not", + "span": 153 + }, + { + "mutability": "Mut", + "span": 138 + }, + { + "mutability": "Mut", + "span": 136 + }, + { + "mutability": "Not", + "span": 135 + }, + { + "mutability": "Mut", + "span": 134 + }, + { + "mutability": "Mut", + "span": 134 + }, + { + "mutability": "Mut", + "span": 137 + }, + { + "mutability": "Not", + "span": 139 + }, + { + "mutability": "Not", + "span": 140 + }, + { + "mutability": "Mut", + "span": 133 + }, + { + "mutability": "Mut", + "span": 141 + }, + { + "mutability": "Mut", + "span": 142 + }, + { + "mutability": "Not", + "span": 154 + }, + { + "mutability": "Not", + "span": 145 + }, + { + "mutability": "Mut", + "span": 147 + } + ], + "span": 155, + "spread_arg": null, + "var_debug_info": [ + { + "argument_index": null, + "composite": null, + "name": "a", + "source_info": { + "scope": 1, + "span": 149 + }, + "value": { + "Place": { + "local": 1, + "projection": [] + } + } + }, + { + "argument_index": null, + "composite": null, + "name": "b", + "source_info": { + "scope": 2, + "span": 150 + }, + "value": { + "Place": { + "local": 2, + "projection": [] + } + } + }, + { + "argument_index": null, + "composite": null, + "name": "left_val", + "source_info": { + "scope": 3, + "span": 111 + }, + "value": { + "Place": { + "local": 6, + "projection": [] + } + } + }, + { + "argument_index": null, + "composite": null, + "name": "right_val", + "source_info": { + "scope": 3, + "span": 112 + }, + "value": { + "Place": { + "local": 7, + "projection": [] + } + } + }, + { + "argument_index": null, + "composite": null, + "name": "kind", + "source_info": { + "scope": 4, + "span": 151 + }, + "value": { + "Place": { + "local": 11, + "projection": [] + } + } + }, + { + "argument_index": null, + "composite": null, + "name": "left_val", + "source_info": { + "scope": 5, + "span": 119 + }, + "value": { + "Place": { + "local": 17, + "projection": [] + } + } + }, + { + "argument_index": null, + "composite": null, + "name": "right_val", + "source_info": { + "scope": 5, + "span": 120 + }, + "value": { + "Place": { + "local": 18, + "projection": [] + } + } + }, + { + "argument_index": null, + "composite": null, + "name": "kind", + "source_info": { + "scope": 6, + "span": 152 + }, + "value": { + "Place": { + "local": 22, + "projection": [] + } + } + }, + { + "argument_index": null, + "composite": null, + "name": "arr", + "source_info": { + "scope": 7, + "span": 153 + }, + "value": { + "Place": { + "local": 25, + "projection": [] + } + } + }, + { + "argument_index": null, + "composite": null, + "name": "left_val", + "source_info": { + "scope": 8, + "span": 139 + }, + "value": { + "Place": { + "local": 32, + "projection": [] + } + } + }, + { + "argument_index": null, + "composite": null, + "name": "right_val", + "source_info": { + "scope": 8, + "span": 140 + }, + "value": { + "Place": { + "local": 33, + "projection": [] + } + } + }, + { + "argument_index": null, + "composite": null, + "name": "kind", + "source_info": { + "scope": 9, + "span": 154 + }, + "value": { + "Place": { + "local": 37, + "projection": [] + } + } + } + ] + }, + "id": 11, + "name": "main" + } + }, + "symbol_name": "_ZN17unevaluated_const4main17h" + }, + { + "details": null, + "mono_item_kind": { + "MonoItemFn": { + "body": { + "arg_count": 0, + "blocks": [ + { + "statements": [ + { + "kind": { + "Assign": [ + { + "local": 0, + "projection": [] + }, + { + "Repeat": [ + { + "Constant": { + "const_": { + "id": 18, + "kind": { + "Allocated": { + "align": 1, + "bytes": [ + 0 + ], + "mutability": "Mut", + "provenance": { + "ptrs": [] + } + } + } + }, + "span": 97, + "user_ty": null + } + }, + { + "id": 0, + "kind": { + "Value": [ + 41, + { + "align": 8, + "bytes": [ + 4, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "mutability": "Mut", + "provenance": { + "ptrs": [] + } + } + ] + } + } + ] + } + ] + }, + "span": 98 + } + ], + "terminator": { + "kind": "Return", + "span": 96 + } + } + ], + "locals": [ + { + "mutability": "Mut", + "span": 99 + } + ], + "span": 100, + "spread_arg": null, + "var_debug_info": [] + }, + "id": 10, + "name": "make_array::<4>" + } + }, + "symbol_name": "_ZN17unevaluated_const10make_array17h" + }, + { + "details": null, + "mono_item_kind": { + "MonoItemFn": { + "body": { + "arg_count": 1, + "blocks": [ + { + "statements": [], + "terminator": { + "kind": "Return", + "span": 74 + } + } + ], + "locals": [ + { + "mutability": "Mut", + "span": 74 + }, + { + "mutability": "Not", + "span": 74 + } + ], + "span": 74, + "spread_arg": null, + "var_debug_info": [] + }, + "id": 6, + "name": "std::ptr::drop_in_place::<&usize>" + } + }, + "symbol_name": "_ZN4core3ptr30drop_in_place$LT$$RF$usize$GT$17h" + }, + { + "details": null, + "mono_item_kind": { + "MonoItemFn": { + "body": { + "arg_count": 1, + "blocks": [ + { + "statements": [], + "terminator": { + "kind": "Return", + "span": 74 + } + } + ], + "locals": [ + { + "mutability": "Mut", + "span": 74 + }, + { + "mutability": "Not", + "span": 74 + } + ], + "span": 74, + "spread_arg": null, + "var_debug_info": [] + }, + "id": 6, + "name": "std::ptr::drop_in_place::<{closure@std::rt::lang_start<()>::{closure#0}}>" + } + }, + "symbol_name": "_ZN4core3ptr85drop_in_place$LT$std..rt..lang_start$LT$$LP$$RP$$GT$..$u7b$$u7b$closure$u7d$$u7d$$GT$17h" + }, + { + "details": null, + "mono_item_kind": { + "MonoItemFn": { + "body": { + "arg_count": 1, + "blocks": [ + { + "statements": [], + "terminator": { + "kind": { + "Call": { + "args": [ + { + "Move": { + "local": 1, + "projection": [] + } + }, + { + "Constant": { + "const_": { + "id": 4, + "kind": "ZeroSized" + }, + "span": 32, + "user_ty": null + } + } + ], + "destination": { + "local": 0, + "projection": [] + }, + "func": { + "Constant": { + "const_": { + "id": 3, + "kind": "ZeroSized" + }, + "span": 31, + "user_ty": null + } + }, + "target": 1, + "unwind": "Continue" + } + }, + "span": 33 + } + }, + { + "statements": [], + "terminator": { + "kind": { + "Call": { + "args": [ + { + "Constant": { + "const_": { + "id": 4, + "kind": "ZeroSized" + }, + "span": 32, + "user_ty": null + } + } + ], + "destination": { + "local": 2, + "projection": [] + }, + "func": { + "Constant": { + "const_": { + "id": 5, + "kind": "ZeroSized" + }, + "span": 34, + "user_ty": null + } + }, + "target": 2, + "unwind": "Unreachable" + } + }, + "span": 35 + } + }, + { + "statements": [], + "terminator": { + "kind": "Return", + "span": 36 + } + } + ], + "locals": [ + { + "mutability": "Mut", + "span": 37 + }, + { + "mutability": "Not", + "span": 38 + }, + { + "mutability": "Not", + "span": 39 + } + ], + "span": 42, + "spread_arg": null, + "var_debug_info": [ + { + "argument_index": 1, + "composite": null, + "name": "f", + "source_info": { + "scope": 0, + "span": 38 + }, + "value": { + "Place": { + "local": 1, + "projection": [] + } + } + }, + { + "argument_index": null, + "composite": null, + "name": "result", + "source_info": { + "scope": 1, + "span": 40 + }, + "value": { + "Place": { + "local": 0, + "projection": [] + } + } + }, + { + "argument_index": 1, + "composite": null, + "name": "dummy", + "source_info": { + "scope": 2, + "span": 41 + }, + "value": { + "Const": { + "const_": { + "id": 4, + "kind": "ZeroSized" + }, + "span": 32, + "user_ty": null + } + } + } + ] + }, + "id": 2, + "name": "std::sys::backtrace::__rust_begin_short_backtrace::" + } + }, + "symbol_name": "_ZN3std3sys9backtrace28__rust_begin_short_backtrace17h" + }, + { + "details": null, + "mono_item_kind": { + "MonoItemFn": { + "body": { + "arg_count": 1, + "blocks": [ + { + "statements": [ + { + "kind": { + "Assign": [ + { + "local": 0, + "projection": [] + }, + { + "Use": { + "Constant": { + "const_": { + "id": 15, + "kind": { + "Allocated": { + "align": 1, + "bytes": [ + 0 + ], + "mutability": "Mut", + "provenance": { + "ptrs": [] + } + } + } + }, + "span": 86, + "user_ty": null + } + } + } + ] + }, + "span": 86 + } + ], + "terminator": { + "kind": "Return", + "span": 85 + } + } + ], + "locals": [ + { + "mutability": "Mut", + "span": 87 + }, + { + "mutability": "Not", + "span": 88 + } + ], + "span": 89, + "spread_arg": null, + "var_debug_info": [ + { + "argument_index": 1, + "composite": null, + "name": "self", + "source_info": { + "scope": 0, + "span": 88 + }, + "value": { + "Const": { + "const_": { + "id": 4, + "kind": "ZeroSized" + }, + "span": 32, + "user_ty": null + } + } + } + ] + }, + "id": 8, + "name": "<() as std::process::Termination>::report" + } + }, + "symbol_name": "_ZN54_$LT$$LP$$RP$$u20$as$u20$std..process..Termination$GT$6report17h" + }, + { + "details": null, + "mono_item_kind": { + "MonoItemFn": { + "body": { + "arg_count": 1, + "blocks": [ + { + "statements": [ + { + "kind": { + "Assign": [ + { + "local": 2, + "projection": [] + }, + { + "CheckedBinaryOp": [ + "Add", + { + "Copy": { + "local": 1, + "projection": [] + } + }, + { + "Constant": { + "const_": { + "id": 16, + "kind": { + "Allocated": { + "align": 8, + "bytes": [ + 3, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "mutability": "Mut", + "provenance": { + "ptrs": [] + } + } + } + }, + "span": 90, + "user_ty": null + } + } + ] + } + ] + }, + "span": 91 + } + ], + "terminator": { + "kind": { + "Assert": { + "cond": { + "Move": { + "local": 2, + "projection": [ + { + "Field": [ + 1, + 40 + ] + } + ] + } + }, + "expected": false, + "msg": { + "Overflow": [ + "Add", + { + "Copy": { + "local": 1, + "projection": [] + } + }, + { + "Constant": { + "const_": { + "id": 16, + "kind": { + "Allocated": { + "align": 8, + "bytes": [ + 3, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "mutability": "Mut", + "provenance": { + "ptrs": [] + } + } + } + }, + "span": 90, + "user_ty": null + } + } + ] + }, + "target": 1, + "unwind": "Continue" + } + }, + "span": 91 + } + }, + { + "statements": [ + { + "kind": { + "Assign": [ + { + "local": 0, + "projection": [] + }, + { + "Use": { + "Move": { + "local": 2, + "projection": [ + { + "Field": [ + 0, + 41 + ] + } + ] + } + } + } + ] + }, + "span": 91 + } + ], + "terminator": { + "kind": "Return", + "span": 92 + } + } + ], + "locals": [ + { + "mutability": "Mut", + "span": 93 + }, + { + "mutability": "Not", + "span": 94 + }, + { + "mutability": "Mut", + "span": 91 + } + ], + "span": 95, + "spread_arg": null, + "var_debug_info": [ + { + "argument_index": 1, + "composite": null, + "name": "pos", + "source_info": { + "scope": 0, + "span": 94 + }, + "value": { + "Place": { + "local": 1, + "projection": [] + } + } + } + ] + }, + "id": 9, + "name": "advance::" + } + }, + "symbol_name": "_ZN17unevaluated_const7advance17h" + }, + { + "details": null, + "mono_item_kind": { + "MonoItemFn": { + "body": { + "arg_count": 1, + "blocks": [ + { + "statements": [ + { + "kind": { + "Assign": [ + { + "local": 2, + "projection": [] + }, + { + "CheckedBinaryOp": [ + "Add", + { + "Copy": { + "local": 1, + "projection": [] + } + }, + { + "Constant": { + "const_": { + "id": 17, + "kind": { + "Allocated": { + "align": 8, + "bytes": [ + 2, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "mutability": "Mut", + "provenance": { + "ptrs": [] + } + } + } + }, + "span": 90, + "user_ty": null + } + } + ] + } + ] + }, + "span": 91 + } + ], + "terminator": { + "kind": { + "Assert": { + "cond": { + "Move": { + "local": 2, + "projection": [ + { + "Field": [ + 1, + 40 + ] + } + ] + } + }, + "expected": false, + "msg": { + "Overflow": [ + "Add", + { + "Copy": { + "local": 1, + "projection": [] + } + }, + { + "Constant": { + "const_": { + "id": 17, + "kind": { + "Allocated": { + "align": 8, + "bytes": [ + 2, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "mutability": "Mut", + "provenance": { + "ptrs": [] + } + } + } + }, + "span": 90, + "user_ty": null + } + } + ] + }, + "target": 1, + "unwind": "Continue" + } + }, + "span": 91 + } + }, + { + "statements": [ + { + "kind": { + "Assign": [ + { + "local": 0, + "projection": [] + }, + { + "Use": { + "Move": { + "local": 2, + "projection": [ + { + "Field": [ + 0, + 41 + ] + } + ] + } + } + } + ] + }, + "span": 91 + } + ], + "terminator": { + "kind": "Return", + "span": 92 + } + } + ], + "locals": [ + { + "mutability": "Mut", + "span": 93 + }, + { + "mutability": "Not", + "span": 94 + }, + { + "mutability": "Mut", + "span": 91 + } + ], + "span": 95, + "spread_arg": null, + "var_debug_info": [ + { + "argument_index": 1, + "composite": null, + "name": "pos", + "source_info": { + "scope": 0, + "span": 94 + }, + "value": { + "Place": { + "local": 1, + "projection": [] + } + } + } + ] + }, + "id": 9, + "name": "advance::" + } + }, + "symbol_name": "_ZN17unevaluated_const7advance17h" + }, + { + "details": null, + "mono_item_kind": { + "MonoItemFn": { + "body": { + "arg_count": 1, + "blocks": [ + { + "statements": [ + { + "kind": { + "StorageLive": 2 + }, + "span": 16 + }, + { + "kind": { + "StorageLive": 3 + }, + "span": 15 + }, + { + "kind": { + "StorageLive": 4 + }, + "span": 17 + }, + { + "kind": { + "Assign": [ + { + "local": 4, + "projection": [] + }, + { + "Use": { + "Copy": { + "local": 1, + "projection": [ + "Deref", + { + "Field": [ + 0, + 7 + ] + } + ] + } + } + } + ] + }, + "span": 17 + } + ], + "terminator": { + "kind": { + "Call": { + "args": [ + { + "Move": { + "local": 4, + "projection": [] + } + } + ], + "destination": { + "local": 3, + "projection": [] + }, + "func": { + "Constant": { + "const_": { + "id": 1, + "kind": "ZeroSized" + }, + "span": 14, + "user_ty": null + } + }, + "target": 1, + "unwind": "Continue" + } + }, + "span": 15 + } + }, + { + "statements": [ + { + "kind": { + "StorageDead": 4 + }, + "span": 19 + } + ], + "terminator": { + "kind": { + "Call": { + "args": [ + { + "Move": { + "local": 3, + "projection": [] + } + } + ], + "destination": { + "local": 2, + "projection": [] + }, + "func": { + "Constant": { + "const_": { + "id": 2, + "kind": "ZeroSized" + }, + "span": 18, + "user_ty": null + } + }, + "target": 2, + "unwind": "Continue" + } + }, + "span": 16 + } + }, + { + "statements": [ + { + "kind": { + "StorageDead": 3 + }, + "span": 21 + }, + { + "kind": { + "StorageLive": 5 + }, + "span": 22 + }, + { + "kind": { + "Assign": [ + { + "local": 5, + "projection": [] + }, + { + "Ref": [ + { + "kind": "ReErased" + }, + "Shared", + { + "local": 2, + "projection": [ + { + "Field": [ + 0, + 15 + ] + } + ] + } + ] + } + ] + }, + "span": 22 + }, + { + "kind": { + "StorageLive": 6 + }, + "span": 23 + }, + { + "kind": { + "Assign": [ + { + "local": 6, + "projection": [] + }, + { + "Use": { + "Copy": { + "local": 2, + "projection": [ + { + "Field": [ + 0, + 15 + ] + }, + { + "Field": [ + 0, + 9 + ] + } + ] + } + } + } + ] + }, + "span": 23 + }, + { + "kind": { + "Assign": [ + { + "local": 0, + "projection": [] + }, + { + "Cast": [ + "IntToInt", + { + "Move": { + "local": 6, + "projection": [] + } + }, + 16 + ] + } + ] + }, + "span": 24 + }, + { + "kind": { + "StorageDead": 6 + }, + "span": 25 + }, + { + "kind": { + "StorageDead": 5 + }, + "span": 26 + }, + { + "kind": { + "StorageDead": 2 + }, + "span": 27 + } + ], + "terminator": { + "kind": "Return", + "span": 20 + } + } + ], + "locals": [ + { + "mutability": "Mut", + "span": 28 + }, + { + "mutability": "Mut", + "span": 3 + }, + { + "mutability": "Mut", + "span": 16 + }, + { + "mutability": "Mut", + "span": 15 + }, + { + "mutability": "Mut", + "span": 17 + }, + { + "mutability": "Mut", + "span": 22 + }, + { + "mutability": "Mut", + "span": 23 + } + ], + "span": 3, + "spread_arg": null, + "var_debug_info": [ + { + "argument_index": null, + "composite": null, + "name": "main", + "source_info": { + "scope": 0, + "span": 9 + }, + "value": { + "Place": { + "local": 1, + "projection": [ + "Deref", + { + "Field": [ + 0, + 7 + ] + } + ] + } + } + }, + { + "argument_index": 1, + "composite": null, + "name": "self", + "source_info": { + "scope": 1, + "span": 29 + }, + "value": { + "Place": { + "local": 2, + "projection": [] + } + } + }, + { + "argument_index": 1, + "composite": null, + "name": "self", + "source_info": { + "scope": 2, + "span": 30 + }, + "value": { + "Place": { + "local": 5, + "projection": [] + } + } + } + ] + }, + "id": 1, + "name": "std::rt::lang_start::<()>::{closure#0}" + } + }, + "symbol_name": "_ZN3std2rt10lang_start28_$u7b$$u7b$closure$u7d$$u7d$17h" + }, + { + "details": null, + "mono_item_kind": { + "MonoItemFn": { + "body": { + "arg_count": 2, + "blocks": [ + { + "statements": [], + "terminator": { + "kind": { + "Call": { + "args": [], + "destination": { + "local": 0, + "projection": [] + }, + "func": { + "Move": { + "local": 1, + "projection": [] + } + }, + "target": 1, + "unwind": "Continue" + } + }, + "span": 73 + } + }, + { + "statements": [], + "terminator": { + "kind": "Return", + "span": 73 + } + } + ], + "locals": [ + { + "mutability": "Mut", + "span": 73 + }, + { + "mutability": "Not", + "span": 73 + }, + { + "mutability": "Not", + "span": 73 + } + ], + "span": 73, + "spread_arg": 2, + "var_debug_info": [] + }, + "id": 5, + "name": ">::call_once" + } + }, + "symbol_name": "_ZN4core3ops8function6FnOnce9call_once17h" + }, + { + "details": null, + "mono_item_kind": { + "MonoItemFn": { + "body": { + "arg_count": 2, + "blocks": [ + { + "statements": [], + "terminator": { + "kind": { + "Call": { + "args": [ + { + "Move": { + "local": 1, + "projection": [ + "Deref" + ] + } + }, + { + "Move": { + "local": 2, + "projection": [] + } + } + ], + "destination": { + "local": 0, + "projection": [] + }, + "func": { + "Constant": { + "const_": { + "id": 12, + "kind": "ZeroSized" + }, + "span": 73, + "user_ty": null + } + }, + "target": 1, + "unwind": "Continue" + } + }, + "span": 73 + } + }, + { + "statements": [], + "terminator": { + "kind": "Return", + "span": 73 + } + } + ], + "locals": [ + { + "mutability": "Mut", + "span": 73 + }, + { + "mutability": "Not", + "span": 73 + }, + { + "mutability": "Not", + "span": 73 + } + ], + "span": 73, + "spread_arg": 2, + "var_debug_info": [] + }, + "id": 5, + "name": "<{closure@std::rt::lang_start<()>::{closure#0}} as std::ops::FnOnce<()>>::call_once" + } + }, + "symbol_name": "_ZN4core3ops8function6FnOnce40call_once$u7b$$u7b$vtable.shim$u7d$$u7d$17h" + }, + { + "details": null, + "mono_item_kind": { + "MonoItemFn": { + "body": { + "arg_count": 2, + "blocks": [ + { + "statements": [ + { + "kind": { + "Assign": [ + { + "local": 3, + "projection": [] + }, + { + "Ref": [ + { + "kind": "ReErased" + }, + { + "Mut": { + "kind": "Default" + } + }, + { + "local": 1, + "projection": [] + } + ] + } + ] + }, + "span": 73 + } + ], + "terminator": { + "kind": { + "Call": { + "args": [ + { + "Move": { + "local": 3, + "projection": [] + } + }, + { + "Move": { + "local": 2, + "projection": [] + } + } + ], + "destination": { + "local": 0, + "projection": [] + }, + "func": { + "Constant": { + "const_": { + "id": 13, + "kind": "ZeroSized" + }, + "span": 73, + "user_ty": null + } + }, + "target": 1, + "unwind": { + "Cleanup": 3 + } + } + }, + "span": 73 + } + }, + { + "statements": [], + "terminator": { + "kind": { + "Drop": { + "place": { + "local": 1, + "projection": [] + }, + "target": 2, + "unwind": "Continue" + } + }, + "span": 73 + } + }, + { + "statements": [], + "terminator": { + "kind": "Return", + "span": 73 + } + }, + { + "statements": [], + "terminator": { + "kind": { + "Drop": { + "place": { + "local": 1, + "projection": [] + }, + "target": 4, + "unwind": "Terminate" + } + }, + "span": 73 + } + }, + { + "statements": [], + "terminator": { + "kind": "Resume", + "span": 73 + } + } + ], + "locals": [ + { + "mutability": "Mut", + "span": 73 + }, + { + "mutability": "Not", + "span": 73 + }, + { + "mutability": "Not", + "span": 73 + }, + { + "mutability": "Not", + "span": 73 + } + ], + "span": 73, + "spread_arg": 2, + "var_debug_info": [] + }, + "id": 5, + "name": "<{closure@std::rt::lang_start<()>::{closure#0}} as std::ops::FnOnce<()>>::call_once" + } + }, + "symbol_name": "_ZN4core3ops8function6FnOnce9call_once17h" + }, + { + "details": null, + "mono_item_kind": { + "MonoItemFn": { + "body": { + "arg_count": 2, + "blocks": [ + { + "statements": [ + { + "kind": { + "Assign": [ + { + "local": 3, + "projection": [] + }, + { + "Use": { + "Copy": { + "local": 1, + "projection": [ + "Deref" + ] + } + } + } + ] + }, + "span": 45 + } + ], + "terminator": { + "kind": { + "Call": { + "args": [ + { + "Move": { + "local": 3, + "projection": [] + } + }, + { + "Move": { + "local": 2, + "projection": [] + } + } + ], + "destination": { + "local": 0, + "projection": [] + }, + "func": { + "Constant": { + "const_": { + "id": 6, + "kind": "ZeroSized" + }, + "span": 43, + "user_ty": null + } + }, + "target": 1, + "unwind": "Continue" + } + }, + "span": 44 + } + }, + { + "statements": [], + "terminator": { + "kind": "Return", + "span": 46 + } + } + ], + "locals": [ + { + "mutability": "Mut", + "span": 47 + }, + { + "mutability": "Not", + "span": 48 + }, + { + "mutability": "Not", + "span": 49 + }, + { + "mutability": "Mut", + "span": 48 + } + ], + "span": 50, + "spread_arg": null, + "var_debug_info": [ + { + "argument_index": 1, + "composite": null, + "name": "self", + "source_info": { + "scope": 0, + "span": 48 + }, + "value": { + "Place": { + "local": 1, + "projection": [] + } + } + }, + { + "argument_index": 2, + "composite": null, + "name": "f", + "source_info": { + "scope": 0, + "span": 49 + }, + "value": { + "Place": { + "local": 2, + "projection": [] + } + } + } + ] + }, + "id": 3, + "name": "<&usize as std::fmt::Debug>::fmt" + } + }, + "symbol_name": "_ZN42_$LT$$RF$T$u20$as$u20$core..fmt..Debug$GT$3fmt17h" + }, + { + "details": null, + "mono_item_kind": { + "MonoItemFn": { + "body": { + "arg_count": 2, + "blocks": [ + { + "statements": [ + { + "kind": { + "StorageLive": 3 + }, + "span": 52 + }, + { + "kind": { + "StorageLive": 4 + }, + "span": 53 + }, + { + "kind": { + "Assign": [ + { + "local": 4, + "projection": [] + }, + { + "Use": { + "Copy": { + "local": 2, + "projection": [ + "Deref", + { + "Field": [ + 0, + 26 + ] + } + ] + } + } + } + ] + }, + "span": 53 + }, + { + "kind": { + "Assign": [ + { + "local": 3, + "projection": [] + }, + { + "BinaryOp": [ + "BitAnd", + { + "Move": { + "local": 4, + "projection": [] + } + }, + { + "Constant": { + "const_": { + "id": 7, + "kind": { + "Allocated": { + "align": 4, + "bytes": [ + 16, + 0, + 0, + 0 + ], + "mutability": "Mut", + "provenance": { + "ptrs": [] + } + } + } + }, + "span": 32, + "user_ty": null + } + } + ] + } + ] + }, + "span": 52 + }, + { + "kind": { + "StorageDead": 4 + }, + "span": 54 + } + ], + "terminator": { + "kind": { + "SwitchInt": { + "discr": { + "Move": { + "local": 3, + "projection": [] + } + }, + "targets": { + "branches": [ + [ + 0, + 2 + ] + ], + "otherwise": 1 + } + } + }, + "span": 51 + } + }, + { + "statements": [ + { + "kind": { + "StorageDead": 3 + }, + "span": 51 + } + ], + "terminator": { + "kind": { + "Call": { + "args": [ + { + "Move": { + "local": 1, + "projection": [] + } + }, + { + "Move": { + "local": 2, + "projection": [] + } + } + ], + "destination": { + "local": 0, + "projection": [] + }, + "func": { + "Constant": { + "const_": { + "id": 8, + "kind": "ZeroSized" + }, + "span": 55, + "user_ty": null + } + }, + "target": 6, + "unwind": "Continue" + } + }, + "span": 56 + } + }, + { + "statements": [ + { + "kind": { + "StorageDead": 3 + }, + "span": 51 + }, + { + "kind": { + "StorageLive": 5 + }, + "span": 58 + }, + { + "kind": { + "StorageLive": 6 + }, + "span": 59 + }, + { + "kind": { + "Assign": [ + { + "local": 6, + "projection": [] + }, + { + "Use": { + "Copy": { + "local": 2, + "projection": [ + "Deref", + { + "Field": [ + 0, + 26 + ] + } + ] + } + } + } + ] + }, + "span": 59 + }, + { + "kind": { + "Assign": [ + { + "local": 5, + "projection": [] + }, + { + "BinaryOp": [ + "BitAnd", + { + "Move": { + "local": 6, + "projection": [] + } + }, + { + "Constant": { + "const_": { + "id": 9, + "kind": { + "Allocated": { + "align": 4, + "bytes": [ + 32, + 0, + 0, + 0 + ], + "mutability": "Mut", + "provenance": { + "ptrs": [] + } + } + } + }, + "span": 32, + "user_ty": null + } + } + ] + } + ] + }, + "span": 58 + }, + { + "kind": { + "StorageDead": 6 + }, + "span": 60 + } + ], + "terminator": { + "kind": { + "SwitchInt": { + "discr": { + "Move": { + "local": 5, + "projection": [] + } + }, + "targets": { + "branches": [ + [ + 0, + 4 + ] + ], + "otherwise": 3 + } + } + }, + "span": 57 + } + }, + { + "statements": [ + { + "kind": { + "StorageDead": 5 + }, + "span": 57 + } + ], + "terminator": { + "kind": { + "Call": { + "args": [ + { + "Move": { + "local": 1, + "projection": [] + } + }, + { + "Move": { + "local": 2, + "projection": [] + } + } + ], + "destination": { + "local": 0, + "projection": [] + }, + "func": { + "Constant": { + "const_": { + "id": 10, + "kind": "ZeroSized" + }, + "span": 61, + "user_ty": null + } + }, + "target": 5, + "unwind": "Continue" + } + }, + "span": 62 + } + }, + { + "statements": [ + { + "kind": { + "StorageDead": 5 + }, + "span": 57 + } + ], + "terminator": { + "kind": { + "Call": { + "args": [ + { + "Move": { + "local": 1, + "projection": [] + } + }, + { + "Move": { + "local": 2, + "projection": [] + } + } + ], + "destination": { + "local": 0, + "projection": [] + }, + "func": { + "Constant": { + "const_": { + "id": 11, + "kind": "ZeroSized" + }, + "span": 63, + "user_ty": null + } + }, + "target": 5, + "unwind": "Continue" + } + }, + "span": 64 + } + }, + { + "statements": [], + "terminator": { + "kind": { + "Goto": { + "target": 6 + } + }, + "span": 65 + } + }, + { + "statements": [], + "terminator": { + "kind": "Return", + "span": 66 + } + } + ], + "locals": [ + { + "mutability": "Mut", + "span": 67 + }, + { + "mutability": "Not", + "span": 68 + }, + { + "mutability": "Not", + "span": 69 + }, + { + "mutability": "Mut", + "span": 52 + }, + { + "mutability": "Mut", + "span": 53 + }, + { + "mutability": "Mut", + "span": 58 + }, + { + "mutability": "Mut", + "span": 59 + } + ], + "span": 72, + "spread_arg": null, + "var_debug_info": [ + { + "argument_index": 1, + "composite": null, + "name": "self", + "source_info": { + "scope": 0, + "span": 68 + }, + "value": { + "Place": { + "local": 1, + "projection": [] + } + } + }, + { + "argument_index": 2, + "composite": null, + "name": "f", + "source_info": { + "scope": 0, + "span": 69 + }, + "value": { + "Place": { + "local": 2, + "projection": [] + } + } + }, + { + "argument_index": 1, + "composite": null, + "name": "self", + "source_info": { + "scope": 1, + "span": 70 + }, + "value": { + "Place": { + "local": 2, + "projection": [] + } + } + }, + { + "argument_index": 1, + "composite": null, + "name": "self", + "source_info": { + "scope": 2, + "span": 71 + }, + "value": { + "Place": { + "local": 2, + "projection": [] + } + } + } + ] + }, + "id": 4, + "name": "core::fmt::num::::fmt" + } + }, + "symbol_name": "_ZN4core3fmt3num52_$LT$impl$u20$core..fmt..Debug$u20$for$u20$usize$GT$3fmt17h" + }, + { + "details": null, + "mono_item_kind": { + "MonoItemFn": { + "body": { + "arg_count": 4, + "blocks": [ + { + "statements": [ + { + "kind": { + "StorageLive": 5 + }, + "span": 1 + }, + { + "kind": { + "StorageLive": 6 + }, + "span": 2 + }, + { + "kind": { + "StorageLive": 8 + }, + "span": 3 + }, + { + "kind": { + "Assign": [ + { + "local": 8, + "projection": [] + }, + { + "Aggregate": [ + { + "Closure": [ + 1, + [ + { + "Type": 1 + }, + { + "Type": 2 + }, + { + "Type": 3 + }, + { + "Type": 4 + } + ] + ] + }, + [ + { + "Copy": { + "local": 1, + "projection": [] + } + } + ] + ] + } + ] + }, + "span": 3 + }, + { + "kind": { + "Assign": [ + { + "local": 7, + "projection": [] + }, + { + "Ref": [ + { + "kind": "ReErased" + }, + "Shared", + { + "local": 8, + "projection": [] + } + ] + } + ] + }, + "span": 2 + }, + { + "kind": { + "Assign": [ + { + "local": 6, + "projection": [] + }, + { + "Cast": [ + { + "PointerCoercion": "Unsize" + }, + { + "Copy": { + "local": 7, + "projection": [] + } + }, + 5 + ] + } + ] + }, + "span": 2 + } + ], + "terminator": { + "kind": { + "Call": { + "args": [ + { + "Move": { + "local": 6, + "projection": [] + } + }, + { + "Move": { + "local": 2, + "projection": [] + } + }, + { + "Move": { + "local": 3, + "projection": [] + } + }, + { + "Move": { + "local": 4, + "projection": [] + } + } + ], + "destination": { + "local": 5, + "projection": [] + }, + "func": { + "Constant": { + "const_": { + "id": 0, + "kind": "ZeroSized" + }, + "span": 0, + "user_ty": null + } + }, + "target": 1, + "unwind": "Continue" + } + }, + "span": 1 + } + }, + { + "statements": [ + { + "kind": { + "StorageDead": 6 + }, + "span": 5 + }, + { + "kind": { + "Assign": [ + { + "local": 0, + "projection": [] + }, + { + "Use": { + "Copy": { + "local": 5, + "projection": [ + { + "Downcast": 0 + }, + { + "Field": [ + 0, + 6 + ] + } + ] + } + } + } + ] + }, + "span": 6 + }, + { + "kind": { + "StorageDead": 8 + }, + "span": 7 + }, + { + "kind": { + "StorageDead": 5 + }, + "span": 7 + } + ], + "terminator": { + "kind": "Return", + "span": 4 + } + } + ], + "locals": [ + { + "mutability": "Mut", + "span": 8 + }, + { + "mutability": "Not", + "span": 9 + }, + { + "mutability": "Not", + "span": 10 + }, + { + "mutability": "Not", + "span": 11 + }, + { + "mutability": "Not", + "span": 12 + }, + { + "mutability": "Mut", + "span": 1 + }, + { + "mutability": "Mut", + "span": 2 + }, + { + "mutability": "Not", + "span": 2 + }, + { + "mutability": "Not", + "span": 3 + } + ], + "span": 13, + "spread_arg": null, + "var_debug_info": [ + { + "argument_index": 1, + "composite": null, + "name": "main", + "source_info": { + "scope": 0, + "span": 9 + }, + "value": { + "Place": { + "local": 1, + "projection": [] + } + } + }, + { + "argument_index": 2, + "composite": null, + "name": "argc", + "source_info": { + "scope": 0, + "span": 10 + }, + "value": { + "Place": { + "local": 2, + "projection": [] + } + } + }, + { + "argument_index": 3, + "composite": null, + "name": "argv", + "source_info": { + "scope": 0, + "span": 11 + }, + "value": { + "Place": { + "local": 3, + "projection": [] + } + } + }, + { + "argument_index": 4, + "composite": null, + "name": "sigpipe", + "source_info": { + "scope": 0, + "span": 12 + }, + "value": { + "Place": { + "local": 4, + "projection": [] + } + } + }, + { + "argument_index": null, + "composite": null, + "name": "v", + "source_info": { + "scope": 1, + "span": 6 + }, + "value": { + "Place": { + "local": 0, + "projection": [] + } + } + } + ] + }, + "id": 0, + "name": "std::rt::lang_start::<()>" + } + }, + "symbol_name": "_ZN3std2rt10lang_start17h" + }, + { + "details": null, + "mono_item_kind": { + "MonoItemFn": { + "body": { + "arg_count": 4, + "blocks": [ + { + "statements": [ + { + "kind": { + "StorageLive": 5 + }, + "span": 77 + }, + { + "kind": { + "Assign": [ + { + "local": 6, + "projection": [] + }, + { + "Ref": [ + { + "kind": "ReErased" + }, + "Shared", + { + "local": 2, + "projection": [] + } + ] + } + ] + }, + "span": 77 + }, + { + "kind": { + "Assign": [ + { + "local": 5, + "projection": [] + }, + { + "Cast": [ + { + "PointerCoercion": "Unsize" + }, + { + "Copy": { + "local": 6, + "projection": [] + } + }, + 36 + ] + } + ] + }, + "span": 77 + }, + { + "kind": { + "StorageLive": 7 + }, + "span": 78 + }, + { + "kind": { + "Assign": [ + { + "local": 8, + "projection": [] + }, + { + "Ref": [ + { + "kind": "ReErased" + }, + "Shared", + { + "local": 3, + "projection": [] + } + ] + } + ] + }, + "span": 78 + }, + { + "kind": { + "Assign": [ + { + "local": 7, + "projection": [] + }, + { + "Cast": [ + { + "PointerCoercion": "Unsize" + }, + { + "Copy": { + "local": 8, + "projection": [] + } + }, + 36 + ] + } + ] + }, + "span": 78 + } + ], + "terminator": { + "kind": { + "Call": { + "args": [ + { + "Move": { + "local": 1, + "projection": [] + } + }, + { + "Move": { + "local": 5, + "projection": [] + } + }, + { + "Move": { + "local": 7, + "projection": [] + } + }, + { + "Move": { + "local": 4, + "projection": [] + } + } + ], + "destination": { + "local": 0, + "projection": [] + }, + "func": { + "Constant": { + "const_": { + "id": 14, + "kind": "ZeroSized" + }, + "span": 75, + "user_ty": null + } + }, + "target": null, + "unwind": "Continue" + } + }, + "span": 76 + } + } + ], + "locals": [ + { + "mutability": "Mut", + "span": 79 + }, + { + "mutability": "Not", + "span": 80 + }, + { + "mutability": "Not", + "span": 81 + }, + { + "mutability": "Not", + "span": 82 + }, + { + "mutability": "Not", + "span": 83 + }, + { + "mutability": "Mut", + "span": 77 + }, + { + "mutability": "Not", + "span": 77 + }, + { + "mutability": "Mut", + "span": 78 + }, + { + "mutability": "Not", + "span": 78 + } + ], + "span": 84, + "spread_arg": null, + "var_debug_info": [ + { + "argument_index": 1, + "composite": null, + "name": "kind", + "source_info": { + "scope": 0, + "span": 80 + }, + "value": { + "Place": { + "local": 1, + "projection": [] + } + } + }, + { + "argument_index": 2, + "composite": null, + "name": "left", + "source_info": { + "scope": 0, + "span": 81 + }, + "value": { + "Place": { + "local": 2, + "projection": [] + } + } + }, + { + "argument_index": 3, + "composite": null, + "name": "right", + "source_info": { + "scope": 0, + "span": 82 + }, + "value": { + "Place": { + "local": 3, + "projection": [] + } + } + }, + { + "argument_index": 4, + "composite": null, + "name": "args", + "source_info": { + "scope": 0, + "span": 83 + }, + "value": { + "Place": { + "local": 4, + "projection": [] + } + } + } + ] + }, + "id": 7, + "name": "core::panicking::assert_failed::" + } + }, + "symbol_name": "_ZN4core9panicking13assert_failed17h" + } + ], + "types": [ + [ + { + "PrimitiveType": "Bool" + } + ], + [ + { + "PrimitiveType": "Char" + } + ], + [ + { + "PrimitiveType": "Str" + } + ], + [ + { + "PrimitiveType": { + "Int": "I32" + } + } + ], + [ + { + "PrimitiveType": { + "Int": "Isize" + } + } + ], + [ + { + "PrimitiveType": { + "Uint": "U32" + } + } + ], + [ + { + "PrimitiveType": { + "Uint": "U8" + } + } + ], + [ + { + "PrimitiveType": { + "Uint": "Usize" + } + } + ], + [ + { + "EnumType": { + "discriminants": [ + 0, + 1, + 2, + 3 + ], + "fields": "elided", + "layout": { + "abi": { + "Scalar": { + "Initialized": { + "valid_range": { + "end": 3, + "start": 0 + }, + "value": { + "Int": { + "length": "I8", + "signed": false + } + } + } + } + }, + "abi_align": 1, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 0 + } + ] + } + }, + "size": { + "num_bits": 8 + }, + "variants": { + "Multiple": { + "tag": { + "Initialized": { + "valid_range": { + "end": 3, + "start": 0 + }, + "value": { + "Int": { + "length": "I8", + "signed": false + } + } + } + }, + "tag_encoding": "Direct", + "tag_field": 0, + "variants": [ + { + "abi": { + "Aggregate": { + "sized": true + } + }, + "abi_align": 1, + "fields": { + "Arbitrary": { + "offsets": [] + } + }, + "size": { + "num_bits": 8 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + { + "abi": { + "Aggregate": { + "sized": true + } + }, + "abi_align": 1, + "fields": { + "Arbitrary": { + "offsets": [] + } + }, + "size": { + "num_bits": 8 + }, + "variants": { + "Single": { + "index": 1 + } + } + }, + { + "abi": { + "Aggregate": { + "sized": true + } + }, + "abi_align": 1, + "fields": { + "Arbitrary": { + "offsets": [] + } + }, + "size": { + "num_bits": 8 + }, + "variants": { + "Single": { + "index": 2 + } + } + }, + { + "abi": { + "Aggregate": { + "sized": true + } + }, + "abi_align": 1, + "fields": { + "Arbitrary": { + "offsets": [] + } + }, + "size": { + "num_bits": 8 + }, + "variants": { + "Single": { + "index": 3 + } + } + } + ] + } + } + }, + "name": "core::fmt::rt::Alignment" + } + } + ], + [ + { + "EnumType": { + "discriminants": [ + 0, + 1 + ], + "fields": "elided", + "layout": { + "abi": { + "Aggregate": { + "sized": true + } + }, + "abi_align": 8, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 0 + } + ] + } + }, + "size": { + "num_bits": 128 + }, + "variants": { + "Multiple": { + "tag": { + "Initialized": { + "valid_range": { + "end": 0, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + }, + "tag_encoding": { + "Niche": { + "niche_start": 0, + "niche_variants": { + "end": 1, + "start": 1 + }, + "untagged_variant": 0 + } + }, + "tag_field": 0, + "variants": [ + { + "abi": { + "ScalarPair": [ + { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + }, + { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + } + ] + }, + "abi_align": 8, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 0 + }, + { + "num_bits": 64 + }, + { + "num_bits": 128 + } + ] + } + }, + "size": { + "num_bits": 128 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + { + "abi": { + "Aggregate": { + "sized": true + } + }, + "abi_align": 8, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 64 + } + ] + } + }, + "size": { + "num_bits": 128 + }, + "variants": { + "Single": { + "index": 1 + } + } + } + ] + } + } + }, + "name": "core::fmt::rt::ArgumentType<'_>" + } + } + ], + [ + { + "EnumType": { + "discriminants": [ + 0, + 1, + 2 + ], + "fields": "elided", + "layout": { + "abi": { + "ScalarPair": [ + { + "Initialized": { + "valid_range": { + "end": 2, + "start": 0 + }, + "value": { + "Int": { + "length": "I64", + "signed": false + } + } + } + }, + { + "Union": { + "value": { + "Int": { + "length": "I64", + "signed": false + } + } + } + } + ] + }, + "abi_align": 8, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 0 + } + ] + } + }, + "size": { + "num_bits": 128 + }, + "variants": { + "Multiple": { + "tag": { + "Initialized": { + "valid_range": { + "end": 2, + "start": 0 + }, + "value": { + "Int": { + "length": "I64", + "signed": false + } + } + } + }, + "tag_encoding": "Direct", + "tag_field": 0, + "variants": [ + { + "abi": { + "ScalarPair": [ + { + "Initialized": { + "valid_range": { + "end": 2, + "start": 0 + }, + "value": { + "Int": { + "length": "I64", + "signed": false + } + } + } + }, + { + "Union": { + "value": { + "Int": { + "length": "I64", + "signed": false + } + } + } + } + ] + }, + "abi_align": 8, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 64 + } + ] + } + }, + "size": { + "num_bits": 128 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + { + "abi": { + "ScalarPair": [ + { + "Initialized": { + "valid_range": { + "end": 2, + "start": 0 + }, + "value": { + "Int": { + "length": "I64", + "signed": false + } + } + } + }, + { + "Union": { + "value": { + "Int": { + "length": "I64", + "signed": false + } + } + } + } + ] + }, + "abi_align": 8, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 64 + } + ] + } + }, + "size": { + "num_bits": 128 + }, + "variants": { + "Single": { + "index": 1 + } + } + }, + { + "abi": { + "Aggregate": { + "sized": true + } + }, + "abi_align": 1, + "fields": { + "Arbitrary": { + "offsets": [] + } + }, + "size": { + "num_bits": 64 + }, + "variants": { + "Single": { + "index": 2 + } + } + } + ] + } + } + }, + "name": "core::fmt::rt::Count" + } + } + ], + [ + { + "EnumType": { + "discriminants": [ + 0, + 1, + 2 + ], + "fields": "elided", + "layout": { + "abi": { + "Scalar": { + "Initialized": { + "valid_range": { + "end": 2, + "start": 0 + }, + "value": { + "Int": { + "length": "I8", + "signed": false + } + } + } + } + }, + "abi_align": 1, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 0 + } + ] + } + }, + "size": { + "num_bits": 8 + }, + "variants": { + "Multiple": { + "tag": { + "Initialized": { + "valid_range": { + "end": 2, + "start": 0 + }, + "value": { + "Int": { + "length": "I8", + "signed": false + } + } + } + }, + "tag_encoding": "Direct", + "tag_field": 0, + "variants": [ + { + "abi": { + "Aggregate": { + "sized": true + } + }, + "abi_align": 1, + "fields": { + "Arbitrary": { + "offsets": [] + } + }, + "size": { + "num_bits": 8 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + { + "abi": { + "Aggregate": { + "sized": true + } + }, + "abi_align": 1, + "fields": { + "Arbitrary": { + "offsets": [] + } + }, + "size": { + "num_bits": 8 + }, + "variants": { + "Single": { + "index": 1 + } + } + }, + { + "abi": { + "Aggregate": { + "sized": true + } + }, + "abi_align": 1, + "fields": { + "Arbitrary": { + "offsets": [] + } + }, + "size": { + "num_bits": 8 + }, + "variants": { + "Single": { + "index": 2 + } + } + } + ] + } + } + }, + "name": "core::panicking::AssertKind" + } + } + ], + [ + { + "EnumType": { + "discriminants": [ + 0, + 1 + ], + "fields": "elided", + "layout": { + "abi": { + "ScalarPair": [ + { + "Initialized": { + "valid_range": { + "end": 0, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + }, + { + "Union": { + "value": { + "Int": { + "length": "I64", + "signed": false + } + } + } + } + ] + }, + "abi_align": 8, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 0 + } + ] + } + }, + "size": { + "num_bits": 128 + }, + "variants": { + "Multiple": { + "tag": { + "Initialized": { + "valid_range": { + "end": 0, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + }, + "tag_encoding": { + "Niche": { + "niche_start": 0, + "niche_variants": { + "end": 0, + "start": 0 + }, + "untagged_variant": 1 + } + }, + "tag_field": 0, + "variants": [ + { + "abi": { + "Aggregate": { + "sized": true + } + }, + "abi_align": 1, + "fields": { + "Arbitrary": { + "offsets": [] + } + }, + "size": { + "num_bits": 0 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + { + "abi": { + "ScalarPair": [ + { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + }, + { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 0 + }, + "value": { + "Int": { + "length": "I64", + "signed": false + } + } + } + } + ] + }, + "abi_align": 8, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 0 + } + ] + } + }, + "size": { + "num_bits": 128 + }, + "variants": { + "Single": { + "index": 1 + } + } + } + ] + } + } + }, + "name": "std::option::Option<&[core::fmt::rt::Placeholder]>" + } + } + ], + [ + { + "EnumType": { + "discriminants": [ + 0, + 1 + ], + "fields": "elided", + "layout": { + "abi": { + "Aggregate": { + "sized": true + } + }, + "abi_align": 8, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 0 + } + ] + } + }, + "size": { + "num_bits": 384 + }, + "variants": { + "Multiple": { + "tag": { + "Initialized": { + "valid_range": { + "end": 0, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + }, + "tag_encoding": { + "Niche": { + "niche_start": 0, + "niche_variants": { + "end": 0, + "start": 0 + }, + "untagged_variant": 1 + } + }, + "tag_field": 0, + "variants": [ + { + "abi": { + "Aggregate": { + "sized": true + } + }, + "abi_align": 1, + "fields": { + "Arbitrary": { + "offsets": [] + } + }, + "size": { + "num_bits": 0 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + { + "abi": { + "Aggregate": { + "sized": true + } + }, + "abi_align": 8, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 0 + } + ] + } + }, + "size": { + "num_bits": 384 + }, + "variants": { + "Single": { + "index": 1 + } + } + } + ] + } + } + }, + "name": "std::option::Option>" + } + } + ], + [ + { + "EnumType": { + "discriminants": [ + 0, + 1 + ], + "fields": "elided", + "layout": { + "abi": { + "ScalarPair": [ + { + "Initialized": { + "valid_range": { + "end": 1, + "start": 0 + }, + "value": { + "Int": { + "length": "I64", + "signed": false + } + } + } + }, + { + "Union": { + "value": { + "Int": { + "length": "I64", + "signed": false + } + } + } + } + ] + }, + "abi_align": 8, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 0 + } + ] + } + }, + "size": { + "num_bits": 128 + }, + "variants": { + "Multiple": { + "tag": { + "Initialized": { + "valid_range": { + "end": 1, + "start": 0 + }, + "value": { + "Int": { + "length": "I64", + "signed": false + } + } + } + }, + "tag_encoding": "Direct", + "tag_field": 0, + "variants": [ + { + "abi": { + "Aggregate": { + "sized": true + } + }, + "abi_align": 1, + "fields": { + "Arbitrary": { + "offsets": [] + } + }, + "size": { + "num_bits": 64 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + { + "abi": { + "ScalarPair": [ + { + "Initialized": { + "valid_range": { + "end": 1, + "start": 0 + }, + "value": { + "Int": { + "length": "I64", + "signed": false + } + } + } + }, + { + "Union": { + "value": { + "Int": { + "length": "I64", + "signed": false + } + } + } + } + ] + }, + "abi_align": 8, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 64 + } + ] + } + }, + "size": { + "num_bits": 128 + }, + "variants": { + "Single": { + "index": 1 + } + } + } + ] + } + } + }, + "name": "std::option::Option" + } + } + ], + [ + { + "EnumType": { + "discriminants": [ + 0, + 1 + ], + "fields": "elided", + "layout": { + "abi": { + "Scalar": { + "Initialized": { + "valid_range": { + "end": 1, + "start": 0 + }, + "value": { + "Int": { + "length": "I8", + "signed": false + } + } + } + } + }, + "abi_align": 1, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 0 + } + ] + } + }, + "size": { + "num_bits": 8 + }, + "variants": { + "Multiple": { + "tag": { + "Initialized": { + "valid_range": { + "end": 1, + "start": 0 + }, + "value": { + "Int": { + "length": "I8", + "signed": false + } + } + } + }, + "tag_encoding": "Direct", + "tag_field": 0, + "variants": [ + { + "abi": { + "Scalar": { + "Initialized": { + "valid_range": { + "end": 1, + "start": 0 + }, + "value": { + "Int": { + "length": "I8", + "signed": false + } + } + } + } + }, + "abi_align": 1, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 8 + } + ] + } + }, + "size": { + "num_bits": 8 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + { + "abi": { + "Scalar": { + "Initialized": { + "valid_range": { + "end": 1, + "start": 0 + }, + "value": { + "Int": { + "length": "I8", + "signed": false + } + } + } + } + }, + "abi_align": 1, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 8 + } + ] + } + }, + "size": { + "num_bits": 8 + }, + "variants": { + "Single": { + "index": 1 + } + } + } + ] + } + } + }, + "name": "std::result::Result<(), std::fmt::Error>" + } + } + ], + [ + { + "EnumType": { + "discriminants": [ + 0, + 1 + ], + "fields": "elided", + "layout": { + "abi": { + "Scalar": { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 0 + }, + "value": { + "Int": { + "length": "I64", + "signed": true + } + } + } + } + }, + "abi_align": 8, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 0 + } + ] + } + }, + "size": { + "num_bits": 64 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "name": "std::result::Result" + } + } + ], + [ + { + "StructType": { + "fields": "elided", + "layout": { + "abi": { + "Aggregate": { + "sized": true + } + }, + "abi_align": 8, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 0 + } + ] + } + }, + "size": { + "num_bits": 128 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "name": "core::fmt::rt::Argument<'_>" + } + } + ], + [ + { + "StructType": { + "fields": "elided", + "layout": { + "abi": { + "Aggregate": { + "sized": true + } + }, + "abi_align": 8, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 256 + }, + { + "num_bits": 320 + }, + { + "num_bits": 384 + }, + { + "num_bits": 352 + }, + { + "num_bits": 0 + }, + { + "num_bits": 128 + } + ] + } + }, + "size": { + "num_bits": 448 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "name": "core::fmt::rt::Placeholder" + } + } + ], + [ + { + "StructType": { + "fields": "elided", + "layout": { + "abi": { + "Aggregate": { + "sized": true + } + }, + "abi_align": 8, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 0 + }, + { + "num_bits": 256 + }, + { + "num_bits": 128 + } + ] + } + }, + "size": { + "num_bits": 384 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "name": "std::fmt::Arguments<'_>" + } + } + ], + [ + { + "StructType": { + "fields": "elided", + "layout": { + "abi": { + "Aggregate": { + "sized": true + } + }, + "abi_align": 1, + "fields": { + "Arbitrary": { + "offsets": [] + } + }, + "size": { + "num_bits": 0 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "name": "std::fmt::Error" + } + } + ], + [ + { + "StructType": { + "fields": "elided", + "layout": { + "abi": { + "Aggregate": { + "sized": true + } + }, + "abi_align": 8, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 416 + }, + { + "num_bits": 384 + }, + { + "num_bits": 448 + }, + { + "num_bits": 0 + }, + { + "num_bits": 128 + }, + { + "num_bits": 256 + } + ] + } + }, + "size": { + "num_bits": 512 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "name": "std::fmt::Formatter<'_>" + } + } + ], + [ + { + "StructType": { + "fields": "elided", + "layout": { + "abi": { + "Aggregate": { + "sized": true + } + }, + "abi_align": 1, + "fields": { + "Arbitrary": { + "offsets": [] + } + }, + "size": { + "num_bits": 0 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "name": "std::marker::PhantomData<&()>" + } + } + ], + [ + { + "StructType": { + "fields": "elided", + "layout": { + "abi": { + "Aggregate": { + "sized": true + } + }, + "abi_align": 8, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 0 + }, + { + "num_bits": 128 + }, + { + "num_bits": 160 + } + ] + } + }, + "size": { + "num_bits": 192 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "name": "std::panic::Location<'_>" + } + } + ], + [ + { + "StructType": { + "fields": "elided", + "layout": { + "abi": { + "Scalar": { + "Initialized": { + "valid_range": { + "end": 255, + "start": 0 + }, + "value": { + "Int": { + "length": "I8", + "signed": false + } + } + } + } + }, + "abi_align": 1, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 0 + } + ] + } + }, + "size": { + "num_bits": 8 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "name": "std::process::ExitCode" + } + } + ], + [ + { + "StructType": { + "fields": "elided", + "layout": { + "abi": { + "Scalar": { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + } + }, + "abi_align": 8, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 0 + } + ] + } + }, + "size": { + "num_bits": 64 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "name": "std::ptr::NonNull<()>" + } + } + ], + [ + { + "StructType": { + "fields": "elided", + "layout": { + "abi": { + "Scalar": { + "Initialized": { + "valid_range": { + "end": 255, + "start": 0 + }, + "value": { + "Int": { + "length": "I8", + "signed": false + } + } + } + } + }, + "abi_align": 1, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 0 + } + ] + } + }, + "size": { + "num_bits": 8 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "name": "std::sys::pal::unix::process::process_common::ExitCode" + } + } + ], + [ + { + "ArrayType": { + "layout": { + "abi": { + "Aggregate": { + "sized": false + } + }, + "abi_align": 1, + "fields": { + "Array": { + "count": 0, + "stride": { + "num_bits": 8 + } + } + }, + "size": { + "num_bits": 0 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "size": null + } + } + ], + [ + { + "ArrayType": { + "layout": { + "abi": { + "Aggregate": { + "sized": false + } + }, + "abi_align": 8, + "fields": { + "Array": { + "count": 0, + "stride": { + "num_bits": 128 + } + } + }, + "size": { + "num_bits": 0 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "size": null + } + } + ], + [ + { + "ArrayType": { + "layout": { + "abi": { + "Aggregate": { + "sized": false + } + }, + "abi_align": 8, + "fields": { + "Array": { + "count": 0, + "stride": { + "num_bits": 128 + } + } + }, + "size": { + "num_bits": 0 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "size": null + } + } + ], + [ + { + "ArrayType": { + "layout": { + "abi": { + "Aggregate": { + "sized": false + } + }, + "abi_align": 8, + "fields": { + "Array": { + "count": 0, + "stride": { + "num_bits": 448 + } + } + }, + "size": { + "num_bits": 0 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "size": null + } + } + ], + [ + { + "ArrayType": { + "layout": { + "abi": { + "Aggregate": { + "sized": true + } + }, + "abi_align": 1, + "fields": { + "Array": { + "count": 4, + "stride": { + "num_bits": 8 + } + } + }, + "size": { + "num_bits": 32 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "size": { + "kind": { + "Value": [ + { + "align": 8, + "bytes": [ + 4, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "mutability": "Mut", + "provenance": { + "ptrs": [] + } + } + ] + } + } + } + } + ], + [ + { + "TupleType": { + "layout": { + "abi": { + "Aggregate": { + "sized": true + } + }, + "abi_align": 1, + "fields": { + "Arbitrary": { + "offsets": [] + } + }, + "size": { + "num_bits": 0 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "types": "elided" + } + } + ], + [ + { + "TupleType": { + "layout": { + "abi": { + "ScalarPair": [ + { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 0 + }, + "value": { + "Int": { + "length": "I64", + "signed": false + } + } + } + }, + { + "Initialized": { + "valid_range": { + "end": 1, + "start": 0 + }, + "value": { + "Int": { + "length": "I8", + "signed": false + } + } + } + } + ] + }, + "abi_align": 8, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 0 + }, + { + "num_bits": 64 + } + ] + } + }, + "size": { + "num_bits": 128 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "types": "elided" + } + } + ], + [ + { + "TupleType": { + "layout": { + "abi": { + "ScalarPair": [ + { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + }, + { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + } + ] + }, + "abi_align": 8, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 0 + }, + { + "num_bits": 64 + } + ] + } + }, + "size": { + "num_bits": 128 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "types": "elided" + } + } + ], + [ + { + "PtrType": { + "layout": { + "abi": { + "Scalar": { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 0 + }, + "value": { + "Pointer": 0 + } + } + } + }, + "abi_align": 8, + "fields": "Primitive", + "size": { + "num_bits": 64 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "pointee_type": "elided" + } + } + ], + [ + { + "PtrType": { + "layout": { + "abi": { + "Scalar": { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 0 + }, + "value": { + "Pointer": 0 + } + } + } + }, + "abi_align": 8, + "fields": "Primitive", + "size": { + "num_bits": 64 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "pointee_type": "elided" + } + } + ], + [ + { + "PtrType": { + "layout": { + "abi": { + "Scalar": { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 0 + }, + "value": { + "Pointer": 0 + } + } + } + }, + "abi_align": 8, + "fields": "Primitive", + "size": { + "num_bits": 64 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "pointee_type": "elided" + } + } + ], + [ + { + "PtrType": { + "layout": { + "abi": { + "Scalar": { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 0 + }, + "value": { + "Pointer": 0 + } + } + } + }, + "abi_align": 8, + "fields": "Primitive", + "size": { + "num_bits": 64 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "pointee_type": "elided" + } + } + ], + [ + { + "PtrType": { + "layout": { + "abi": { + "Scalar": { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 0 + }, + "value": { + "Pointer": 0 + } + } + } + }, + "abi_align": 8, + "fields": "Primitive", + "size": { + "num_bits": 64 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "pointee_type": "elided" + } + } + ], + [ + { + "RefType": { + "layout": { + "abi": { + "Scalar": { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + } + }, + "abi_align": 8, + "fields": "Primitive", + "size": { + "num_bits": 64 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "pointee_type": "elided" + } + } + ], + [ + { + "RefType": { + "layout": { + "abi": { + "Scalar": { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + } + }, + "abi_align": 8, + "fields": "Primitive", + "size": { + "num_bits": 64 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "pointee_type": "elided" + } + } + ], + [ + { + "RefType": { + "layout": { + "abi": { + "Scalar": { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + } + }, + "abi_align": 8, + "fields": "Primitive", + "size": { + "num_bits": 64 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "pointee_type": "elided" + } + } + ], + [ + { + "RefType": { + "layout": { + "abi": { + "Scalar": { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + } + }, + "abi_align": 8, + "fields": "Primitive", + "size": { + "num_bits": 64 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "pointee_type": "elided" + } + } + ], + [ + { + "RefType": { + "layout": { + "abi": { + "Scalar": { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + } + }, + "abi_align": 8, + "fields": "Primitive", + "size": { + "num_bits": 64 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "pointee_type": "elided" + } + } + ], + [ + { + "RefType": { + "layout": { + "abi": { + "Scalar": { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + } + }, + "abi_align": 8, + "fields": "Primitive", + "size": { + "num_bits": 64 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "pointee_type": "elided" + } + } + ], + [ + { + "RefType": { + "layout": { + "abi": { + "Scalar": { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + } + }, + "abi_align": 8, + "fields": "Primitive", + "size": { + "num_bits": 64 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "pointee_type": "elided" + } + } + ], + [ + { + "RefType": { + "layout": { + "abi": { + "Scalar": { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + } + }, + "abi_align": 8, + "fields": "Primitive", + "size": { + "num_bits": 64 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "pointee_type": "elided" + } + } + ], + [ + { + "RefType": { + "layout": { + "abi": { + "Scalar": { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + } + }, + "abi_align": 8, + "fields": "Primitive", + "size": { + "num_bits": 64 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "pointee_type": "elided" + } + } + ], + [ + { + "RefType": { + "layout": { + "abi": { + "ScalarPair": [ + { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + }, + { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 0 + }, + "value": { + "Int": { + "length": "I64", + "signed": false + } + } + } + } + ] + }, + "abi_align": 8, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 0 + }, + { + "num_bits": 64 + } + ] + } + }, + "size": { + "num_bits": 128 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "pointee_type": "elided" + } + } + ], + [ + { + "RefType": { + "layout": { + "abi": { + "ScalarPair": [ + { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + }, + { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 0 + }, + "value": { + "Int": { + "length": "I64", + "signed": false + } + } + } + } + ] + }, + "abi_align": 8, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 0 + }, + { + "num_bits": 64 + } + ] + } + }, + "size": { + "num_bits": 128 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "pointee_type": "elided" + } + } + ], + [ + { + "RefType": { + "layout": { + "abi": { + "ScalarPair": [ + { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + }, + { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 0 + }, + "value": { + "Int": { + "length": "I64", + "signed": false + } + } + } + } + ] + }, + "abi_align": 8, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 0 + }, + { + "num_bits": 64 + } + ] + } + }, + "size": { + "num_bits": 128 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "pointee_type": "elided" + } + } + ], + [ + { + "RefType": { + "layout": { + "abi": { + "ScalarPair": [ + { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + }, + { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 0 + }, + "value": { + "Int": { + "length": "I64", + "signed": false + } + } + } + } + ] + }, + "abi_align": 8, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 0 + }, + { + "num_bits": 64 + } + ] + } + }, + "size": { + "num_bits": 128 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "pointee_type": "elided" + } + } + ], + [ + { + "RefType": { + "layout": { + "abi": { + "ScalarPair": [ + { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + }, + { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 0 + }, + "value": { + "Int": { + "length": "I64", + "signed": false + } + } + } + } + ] + }, + "abi_align": 8, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 0 + }, + { + "num_bits": 64 + } + ] + } + }, + "size": { + "num_bits": 128 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "pointee_type": "elided" + } + } + ], + [ + { + "RefType": { + "layout": { + "abi": { + "ScalarPair": [ + { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + }, + { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + } + ] + }, + "abi_align": 8, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 0 + }, + { + "num_bits": 64 + } + ] + } + }, + "size": { + "num_bits": 128 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "pointee_type": "elided" + } + } + ], + [ + { + "RefType": { + "layout": { + "abi": { + "ScalarPair": [ + { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + }, + { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + } + ] + }, + "abi_align": 8, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 0 + }, + { + "num_bits": 64 + } + ] + } + }, + "size": { + "num_bits": 128 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "pointee_type": "elided" + } + } + ], + [ + { + "RefType": { + "layout": { + "abi": { + "ScalarPair": [ + { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + }, + { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + } + ] + }, + "abi_align": 8, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 0 + }, + { + "num_bits": 64 + } + ] + } + }, + "size": { + "num_bits": 128 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "pointee_type": "elided" + } + } + ] + ] +} From 955f8a276c6a93fd959df776b46f005395c45a7d Mon Sep 17 00:00:00 2001 From: cds-amal Date: Wed, 4 Mar 2026 14:12:47 -0500 Subject: [PATCH 02/13] docs(tests): add @covers annotations to all integration test programs Each test .rs file now has a //! @covers: line describing the Rust constructs it exercises (e.g. closures, enums, fn pointer coercion). These are module-level doc comments so they show up in rustdoc, and the trace-report tooling extracts them for the coverage summary. Golden files regenerated for the programs where the new doc comment changed the crate-level attributes in the MIR output. --- tests/integration/programs/assert_eq.rs | 1 + tests/integration/programs/binop.rs | 1 + tests/integration/programs/char-trivial.rs | 1 + tests/integration/programs/closure-args.rs | 1 + .../programs/closure-args.smir.json.expected | 2 +- tests/integration/programs/closure-no-args.rs | 1 + .../closure-no-args.smir.json.expected | 2 +- .../programs/const-arithm-simple.rs | 1 + tests/integration/programs/div.rs | 1 + .../integration/programs/double-ref-deref.rs | 1 + tests/integration/programs/enum.rs | 1 + tests/integration/programs/fibonacci.rs | 1 + tests/integration/programs/float.rs | 1 + tests/integration/programs/fn-ptr-in-arg.rs | 1 + tests/integration/programs/modulo.rs | 1 + .../integration/programs/mutual_recursion.rs | 1 + .../programs/option-construction.rs | 1 + tests/integration/programs/param_types.rs | 1 + .../programs/primitive-type-bounds.rs | 1 + .../programs/recursion-simple-match.rs | 1 + .../integration/programs/recursion-simple.rs | 1 + tests/integration/programs/ref-deref.rs | 1 + .../integration/programs/reify-fn-pointer.rs | 3 +- .../reify-fn-pointer.smir.json.expected | 129 +++++++++++------- tests/integration/programs/shl_min.rs | 1 + tests/integration/programs/slice.rs | 1 + .../static-vtable-nonbuiltin-deref.rs | 1 + .../integration/programs/strange-ref-deref.rs | 1 + tests/integration/programs/struct.rs | 1 + tests/integration/programs/sum-to-n.rs | 1 + tests/integration/programs/tuple-eq.rs | 1 + tests/integration/programs/tuples-simple.rs | 1 + .../integration/programs/unevaluated-const.rs | 1 + .../unevaluated-const.smir.json.expected | 115 ++++++++++------ tests/integration/programs/weirdRefs.rs | 1 + 35 files changed, 181 insertions(+), 100 deletions(-) diff --git a/tests/integration/programs/assert_eq.rs b/tests/integration/programs/assert_eq.rs index f4bb6f35..f4e24071 100644 --- a/tests/integration/programs/assert_eq.rs +++ b/tests/integration/programs/assert_eq.rs @@ -1,3 +1,4 @@ +//! @covers: assert_eq macro expansion, string formatting machinery fn main() { let a = 42; let b = 3 + 39; diff --git a/tests/integration/programs/binop.rs b/tests/integration/programs/binop.rs index c132e75e..48117760 100644 --- a/tests/integration/programs/binop.rs +++ b/tests/integration/programs/binop.rs @@ -1,3 +1,4 @@ +//! @covers: binary operators (arithmetic, bitwise, comparison) fn test_binop(x:i32, y:i32) -> () { // Arithmetic // Addition diff --git a/tests/integration/programs/char-trivial.rs b/tests/integration/programs/char-trivial.rs index 78236fbd..80cbfa89 100644 --- a/tests/integration/programs/char-trivial.rs +++ b/tests/integration/programs/char-trivial.rs @@ -1,3 +1,4 @@ +//! @covers: char type, char literals, equality fn main() { let a:char = 'a'; diff --git a/tests/integration/programs/closure-args.rs b/tests/integration/programs/closure-args.rs index cf91f52e..5fac04e9 100644 --- a/tests/integration/programs/closure-args.rs +++ b/tests/integration/programs/closure-args.rs @@ -1,3 +1,4 @@ +//! @covers: closure with captured arguments, closure call fn main() { let sum = |x, y| -> i32 { x + y }; diff --git a/tests/integration/programs/closure-args.smir.json.expected b/tests/integration/programs/closure-args.smir.json.expected index 72c44917..9e598acd 100644 --- a/tests/integration/programs/closure-args.smir.json.expected +++ b/tests/integration/programs/closure-args.smir.json.expected @@ -2620,7 +2620,7 @@ ], [ { - "FunType": "{closure@tests/integration/programs/closure-args.rs:2:15: 2:28}" + "FunType": "{closure@tests/integration/programs/closure-args.rs:3:15: 3:28}" } ] ] diff --git a/tests/integration/programs/closure-no-args.rs b/tests/integration/programs/closure-no-args.rs index 7ec541c5..9bf518b2 100644 --- a/tests/integration/programs/closure-no-args.rs +++ b/tests/integration/programs/closure-no-args.rs @@ -1,3 +1,4 @@ +//! @covers: zero-argument closure, closure call fn main() { let sum = || -> u32 { 42 }; diff --git a/tests/integration/programs/closure-no-args.smir.json.expected b/tests/integration/programs/closure-no-args.smir.json.expected index dacc8052..cd542d56 100644 --- a/tests/integration/programs/closure-no-args.smir.json.expected +++ b/tests/integration/programs/closure-no-args.smir.json.expected @@ -2315,7 +2315,7 @@ ], [ { - "FunType": "{closure@tests/integration/programs/closure-no-args.rs:2:15: 2:24}" + "FunType": "{closure@tests/integration/programs/closure-no-args.rs:3:15: 3:24}" } ] ] diff --git a/tests/integration/programs/const-arithm-simple.rs b/tests/integration/programs/const-arithm-simple.rs index 251d6b67..2bac1424 100644 --- a/tests/integration/programs/const-arithm-simple.rs +++ b/tests/integration/programs/const-arithm-simple.rs @@ -1,3 +1,4 @@ +//! @covers: function calls, usize comparison, return values fn test(x: usize, y:usize) -> bool { return x > y; } diff --git a/tests/integration/programs/div.rs b/tests/integration/programs/div.rs index 616292ce..76d09fdc 100644 --- a/tests/integration/programs/div.rs +++ b/tests/integration/programs/div.rs @@ -1,3 +1,4 @@ +//! @covers: integer division fn main() { assert!(420 / 10 ==42); } \ No newline at end of file diff --git a/tests/integration/programs/double-ref-deref.rs b/tests/integration/programs/double-ref-deref.rs index a91f8ac1..d5137fac 100644 --- a/tests/integration/programs/double-ref-deref.rs +++ b/tests/integration/programs/double-ref-deref.rs @@ -1,3 +1,4 @@ +//! @covers: double references, double dereference fn main() { let a = 42; let b = &a; diff --git a/tests/integration/programs/enum.rs b/tests/integration/programs/enum.rs index 8b020d20..68c1e8ed 100644 --- a/tests/integration/programs/enum.rs +++ b/tests/integration/programs/enum.rs @@ -1,3 +1,4 @@ +//! @covers: enum declaration, variant construction #![allow(unused)] #![allow(dead_code)] enum Letter { diff --git a/tests/integration/programs/fibonacci.rs b/tests/integration/programs/fibonacci.rs index aa06798b..0dd76282 100644 --- a/tests/integration/programs/fibonacci.rs +++ b/tests/integration/programs/fibonacci.rs @@ -1,3 +1,4 @@ +//! @covers: recursion, match expression with wildcard pattern fn fibonacci(n:u32) -> u32 { match n { 0 => 0, diff --git a/tests/integration/programs/float.rs b/tests/integration/programs/float.rs index 3e1c38b1..b9c2d9fa 100644 --- a/tests/integration/programs/float.rs +++ b/tests/integration/programs/float.rs @@ -1,3 +1,4 @@ +//! @covers: floating-point types (f32, f64), float arithmetic fn main() { let a:f32 = 3.5; let b:f32 = 1.2; diff --git a/tests/integration/programs/fn-ptr-in-arg.rs b/tests/integration/programs/fn-ptr-in-arg.rs index 99dc5834..61520315 100644 --- a/tests/integration/programs/fn-ptr-in-arg.rs +++ b/tests/integration/programs/fn-ptr-in-arg.rs @@ -1,3 +1,4 @@ +//! @covers: fn pointer as higher-order argument, Option::map, byte array conversion fn main() { let bytes: [u8; 8] = [0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; let opt: Option<[u8; 8]> = Some(bytes); diff --git a/tests/integration/programs/modulo.rs b/tests/integration/programs/modulo.rs index e76b3efb..5b490894 100644 --- a/tests/integration/programs/modulo.rs +++ b/tests/integration/programs/modulo.rs @@ -1,3 +1,4 @@ +//! @covers: modulo operator fn main() { assert!(42 % 10 == 2); } \ No newline at end of file diff --git a/tests/integration/programs/mutual_recursion.rs b/tests/integration/programs/mutual_recursion.rs index 7037bc80..5b431817 100644 --- a/tests/integration/programs/mutual_recursion.rs +++ b/tests/integration/programs/mutual_recursion.rs @@ -1,3 +1,4 @@ +//! @covers: mutually recursive functions, if/else control flow fn is_even(n:u32) -> bool { if n == 0 { true diff --git a/tests/integration/programs/option-construction.rs b/tests/integration/programs/option-construction.rs index e2b9b98c..5e1b033f 100644 --- a/tests/integration/programs/option-construction.rs +++ b/tests/integration/programs/option-construction.rs @@ -1,3 +1,4 @@ +//! @covers: Option type, Some/None construction, unwrap #![allow(unused)] fn main() { let a:Option = Some(42); diff --git a/tests/integration/programs/param_types.rs b/tests/integration/programs/param_types.rs index 7dbe68da..7757f029 100644 --- a/tests/integration/programs/param_types.rs +++ b/tests/integration/programs/param_types.rs @@ -1,3 +1,4 @@ +//! @covers: generic structs, monomorphized type parameters, Result type // scratch/param_types.rs struct WithParam { diff --git a/tests/integration/programs/primitive-type-bounds.rs b/tests/integration/programs/primitive-type-bounds.rs index 036fb2f5..c182f036 100644 --- a/tests/integration/programs/primitive-type-bounds.rs +++ b/tests/integration/programs/primitive-type-bounds.rs @@ -1,3 +1,4 @@ +//! @covers: unsigned integer boundary values, overflow arithmetic fn main () { let a:u32 = 4294967295; let b:u32 = 4294967294 + 1; diff --git a/tests/integration/programs/recursion-simple-match.rs b/tests/integration/programs/recursion-simple-match.rs index 96b4086d..2ae81dd3 100644 --- a/tests/integration/programs/recursion-simple-match.rs +++ b/tests/integration/programs/recursion-simple-match.rs @@ -1,3 +1,4 @@ +//! @covers: recursion via match expression fn sum_to_n_rec(n:u32) -> u32 { match n { 0 => 0, diff --git a/tests/integration/programs/recursion-simple.rs b/tests/integration/programs/recursion-simple.rs index e15793f8..0d650577 100644 --- a/tests/integration/programs/recursion-simple.rs +++ b/tests/integration/programs/recursion-simple.rs @@ -1,3 +1,4 @@ +//! @covers: recursion via if/else fn sum_to_n_rec(n:u32) -> u32 { if n == 0 { 0 diff --git a/tests/integration/programs/ref-deref.rs b/tests/integration/programs/ref-deref.rs index d637a6ca..525d74f5 100644 --- a/tests/integration/programs/ref-deref.rs +++ b/tests/integration/programs/ref-deref.rs @@ -1,3 +1,4 @@ +//! @covers: reference creation, dereference fn main() { let a = 42; let b = &a; diff --git a/tests/integration/programs/reify-fn-pointer.rs b/tests/integration/programs/reify-fn-pointer.rs index 9373db74..3b550b99 100644 --- a/tests/integration/programs/reify-fn-pointer.rs +++ b/tests/integration/programs/reify-fn-pointer.rs @@ -1,5 +1,4 @@ -/// Exercises ReifyFnPointer casts: coercing a function item -/// (which has a unique zero-sized type) into a function pointer. +//! @covers: ReifyFnPointer cast (fn item coerced to fn pointer via type annotation) fn add(a: i32, b: i32) -> i32 { a + b } diff --git a/tests/integration/programs/reify-fn-pointer.smir.json.expected b/tests/integration/programs/reify-fn-pointer.smir.json.expected index 50b68fa1..af9ca1cf 100644 --- a/tests/integration/programs/reify-fn-pointer.smir.json.expected +++ b/tests/integration/programs/reify-fn-pointer.smir.json.expected @@ -5010,34 +5010,6 @@ } } ], - [ - { - "TupleType": { - "layout": { - "abi": { - "Aggregate": { - "sized": true - } - }, - "abi_align": 1, - "fields": { - "Arbitrary": { - "offsets": [] - } - }, - "size": { - "num_bits": 0 - }, - "variants": { - "Single": { - "index": 0 - } - } - }, - "types": "elided" - } - } - ], [ { "TupleType": { @@ -5047,34 +5019,28 @@ { "Initialized": { "valid_range": { - "end": 4294967295, - "start": 0 + "end": 18446744073709551615, + "start": 1 }, "value": { - "Int": { - "length": "I32", - "signed": true - } + "Pointer": 0 } } }, { "Initialized": { "valid_range": { - "end": 1, - "start": 0 + "end": 18446744073709551615, + "start": 1 }, "value": { - "Int": { - "length": "I8", - "signed": false - } + "Pointer": 0 } } } ] }, - "abi_align": 4, + "abi_align": 8, "fields": { "Arbitrary": { "offsets": [ @@ -5082,13 +5048,41 @@ "num_bits": 0 }, { - "num_bits": 32 + "num_bits": 64 } ] } }, "size": { - "num_bits": 64 + "num_bits": 128 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "types": "elided" + } + } + ], + [ + { + "TupleType": { + "layout": { + "abi": { + "Aggregate": { + "sized": true + } + }, + "abi_align": 1, + "fields": { + "Arbitrary": { + "offsets": [] + } + }, + "size": { + "num_bits": 0 }, "variants": { "Single": { @@ -5109,28 +5103,34 @@ { "Initialized": { "valid_range": { - "end": 18446744073709551615, - "start": 1 + "end": 4294967295, + "start": 0 }, "value": { - "Pointer": 0 + "Int": { + "length": "I32", + "signed": true + } } } }, { "Initialized": { "valid_range": { - "end": 18446744073709551615, - "start": 1 + "end": 1, + "start": 0 }, "value": { - "Pointer": 0 + "Int": { + "length": "I8", + "signed": false + } } } } ] }, - "abi_align": 8, + "abi_align": 4, "fields": { "Arbitrary": { "offsets": [ @@ -5138,13 +5138,13 @@ "num_bits": 0 }, { - "num_bits": 64 + "num_bits": 32 } ] } }, "size": { - "num_bits": 128 + "num_bits": 64 }, "variants": { "Single": { @@ -5184,6 +5184,7 @@ } } }, + "mutability": "Mut", "pointee_type": "elided" } } @@ -5216,6 +5217,7 @@ } } }, + "mutability": "Mut", "pointee_type": "elided" } } @@ -5248,6 +5250,7 @@ } } }, + "mutability": "Not", "pointee_type": "elided" } } @@ -5280,6 +5283,7 @@ } } }, + "mutability": "Not", "pointee_type": "elided" } } @@ -5312,6 +5316,7 @@ } } }, + "mutability": "Not", "pointee_type": "elided" } } @@ -5344,6 +5349,7 @@ } } }, + "mutability": "Mut", "pointee_type": "elided" } } @@ -5376,6 +5382,7 @@ } } }, + "mutability": "Mut", "pointee_type": "elided" } } @@ -5408,6 +5415,7 @@ } } }, + "mutability": "Not", "pointee_type": "elided" } } @@ -5440,6 +5448,7 @@ } } }, + "mutability": "Not", "pointee_type": "elided" } } @@ -5472,6 +5481,7 @@ } } }, + "mutability": "Not", "pointee_type": "elided" } } @@ -5504,6 +5514,7 @@ } } }, + "mutability": "Not", "pointee_type": "elided" } } @@ -5536,6 +5547,7 @@ } } }, + "mutability": "Not", "pointee_type": "elided" } } @@ -5568,6 +5580,7 @@ } } }, + "mutability": "Not", "pointee_type": "elided" } } @@ -5627,6 +5640,7 @@ } } }, + "mutability": "Not", "pointee_type": "elided" } } @@ -5686,6 +5700,7 @@ } } }, + "mutability": "Not", "pointee_type": "elided" } } @@ -5745,6 +5760,7 @@ } } }, + "mutability": "Not", "pointee_type": "elided" } } @@ -5804,6 +5820,7 @@ } } }, + "mutability": "Not", "pointee_type": "elided" } } @@ -5860,6 +5877,7 @@ } } }, + "mutability": "Mut", "pointee_type": "elided" } } @@ -5916,6 +5934,7 @@ } } }, + "mutability": "Not", "pointee_type": "elided" } } @@ -5972,9 +5991,15 @@ } } }, + "mutability": "Not", "pointee_type": "elided" } } + ], + [ + { + "FunType": "{closure@std::rt::lang_start<()>::{closure#0}}" + } ] ] } diff --git a/tests/integration/programs/shl_min.rs b/tests/integration/programs/shl_min.rs index d33c2718..721c5572 100644 --- a/tests/integration/programs/shl_min.rs +++ b/tests/integration/programs/shl_min.rs @@ -1,3 +1,4 @@ +//! @covers: left shift of signed integer minimum values (i8 through i128) fn main() { assert!(-128_i8 << 1 == 0); assert!(-32768_i16 << 1 == 0); diff --git a/tests/integration/programs/slice.rs b/tests/integration/programs/slice.rs index bff6e82a..64c97efc 100644 --- a/tests/integration/programs/slice.rs +++ b/tests/integration/programs/slice.rs @@ -1,3 +1,4 @@ +//! @covers: array slicing, slice comparison fn main() { let a = [1, 2, 3, 4]; diff --git a/tests/integration/programs/static-vtable-nonbuiltin-deref.rs b/tests/integration/programs/static-vtable-nonbuiltin-deref.rs index 3e177922..e14392b0 100644 --- a/tests/integration/programs/static-vtable-nonbuiltin-deref.rs +++ b/tests/integration/programs/static-vtable-nonbuiltin-deref.rs @@ -1,3 +1,4 @@ +//! @covers: static trait objects, dyn dispatch, vtable allocation use std::fmt::Debug; static S: u8 = 7; diff --git a/tests/integration/programs/strange-ref-deref.rs b/tests/integration/programs/strange-ref-deref.rs index 13e71d74..d4fedabf 100644 --- a/tests/integration/programs/strange-ref-deref.rs +++ b/tests/integration/programs/strange-ref-deref.rs @@ -1,3 +1,4 @@ +//! @covers: mutable reference reassignment, self-referential reborrow fn main() { let a = 42; let mut b = &a; diff --git a/tests/integration/programs/struct.rs b/tests/integration/programs/struct.rs index c05abb55..b058c232 100644 --- a/tests/integration/programs/struct.rs +++ b/tests/integration/programs/struct.rs @@ -1,3 +1,4 @@ +//! @covers: struct declaration, field access, field arithmetic struct St { a:u32, b:u32, diff --git a/tests/integration/programs/sum-to-n.rs b/tests/integration/programs/sum-to-n.rs index 5741aa36..393113c2 100644 --- a/tests/integration/programs/sum-to-n.rs +++ b/tests/integration/programs/sum-to-n.rs @@ -1,3 +1,4 @@ +//! @covers: while loop, mutable bindings, function composition fn sum_to_n(n:usize) -> usize { let mut sum = 0; let mut counter = n; diff --git a/tests/integration/programs/tuple-eq.rs b/tests/integration/programs/tuple-eq.rs index 0a79e18c..c261544c 100644 --- a/tests/integration/programs/tuple-eq.rs +++ b/tests/integration/programs/tuple-eq.rs @@ -1,3 +1,4 @@ +//! @covers: tuple construction, tuple equality fn main() { let tup:(i32, i32) = (42, 99); diff --git a/tests/integration/programs/tuples-simple.rs b/tests/integration/programs/tuples-simple.rs index 9493bc4f..92275582 100644 --- a/tests/integration/programs/tuples-simple.rs +++ b/tests/integration/programs/tuples-simple.rs @@ -1,3 +1,4 @@ +//! @covers: tuple construction, tuple field access fn main() { let tup:(i32, i32) = (42, 99); diff --git a/tests/integration/programs/unevaluated-const.rs b/tests/integration/programs/unevaluated-const.rs index 953d8e57..f328eb26 100644 --- a/tests/integration/programs/unevaluated-const.rs +++ b/tests/integration/programs/unevaluated-const.rs @@ -1,3 +1,4 @@ +//! @covers: const evaluation (associated consts in generic contexts, const generics) /// Exercises const evaluation patterns: associated constants in generic /// contexts and const generic parameters. On the current nightly, all /// constants are eagerly evaluated during monomorphization (appearing as diff --git a/tests/integration/programs/unevaluated-const.smir.json.expected b/tests/integration/programs/unevaluated-const.smir.json.expected index 2192e190..f2ee3268 100644 --- a/tests/integration/programs/unevaluated-const.smir.json.expected +++ b/tests/integration/programs/unevaluated-const.smir.json.expected @@ -6350,34 +6350,6 @@ } } ], - [ - { - "TupleType": { - "layout": { - "abi": { - "Aggregate": { - "sized": true - } - }, - "abi_align": 1, - "fields": { - "Arbitrary": { - "offsets": [] - } - }, - "size": { - "num_bits": 0 - }, - "variants": { - "Single": { - "index": 0 - } - } - }, - "types": "elided" - } - } - ], [ { "TupleType": { @@ -6388,27 +6360,21 @@ "Initialized": { "valid_range": { "end": 18446744073709551615, - "start": 0 + "start": 1 }, "value": { - "Int": { - "length": "I64", - "signed": false - } + "Pointer": 0 } } }, { "Initialized": { "valid_range": { - "end": 1, - "start": 0 + "end": 18446744073709551615, + "start": 1 }, "value": { - "Int": { - "length": "I8", - "signed": false - } + "Pointer": 0 } } } @@ -6440,6 +6406,34 @@ } } ], + [ + { + "TupleType": { + "layout": { + "abi": { + "Aggregate": { + "sized": true + } + }, + "abi_align": 1, + "fields": { + "Arbitrary": { + "offsets": [] + } + }, + "size": { + "num_bits": 0 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "types": "elided" + } + } + ], [ { "TupleType": { @@ -6450,21 +6444,27 @@ "Initialized": { "valid_range": { "end": 18446744073709551615, - "start": 1 + "start": 0 }, "value": { - "Pointer": 0 + "Int": { + "length": "I64", + "signed": false + } } } }, { "Initialized": { "valid_range": { - "end": 18446744073709551615, - "start": 1 + "end": 1, + "start": 0 }, "value": { - "Pointer": 0 + "Int": { + "length": "I8", + "signed": false + } } } } @@ -6524,6 +6524,7 @@ } } }, + "mutability": "Mut", "pointee_type": "elided" } } @@ -6556,6 +6557,7 @@ } } }, + "mutability": "Mut", "pointee_type": "elided" } } @@ -6588,6 +6590,7 @@ } } }, + "mutability": "Not", "pointee_type": "elided" } } @@ -6620,6 +6623,7 @@ } } }, + "mutability": "Not", "pointee_type": "elided" } } @@ -6652,6 +6656,7 @@ } } }, + "mutability": "Not", "pointee_type": "elided" } } @@ -6684,6 +6689,7 @@ } } }, + "mutability": "Mut", "pointee_type": "elided" } } @@ -6716,6 +6722,7 @@ } } }, + "mutability": "Mut", "pointee_type": "elided" } } @@ -6748,6 +6755,7 @@ } } }, + "mutability": "Not", "pointee_type": "elided" } } @@ -6780,6 +6788,7 @@ } } }, + "mutability": "Not", "pointee_type": "elided" } } @@ -6812,6 +6821,7 @@ } } }, + "mutability": "Not", "pointee_type": "elided" } } @@ -6844,6 +6854,7 @@ } } }, + "mutability": "Not", "pointee_type": "elided" } } @@ -6876,6 +6887,7 @@ } } }, + "mutability": "Not", "pointee_type": "elided" } } @@ -6908,6 +6920,7 @@ } } }, + "mutability": "Not", "pointee_type": "elided" } } @@ -6940,6 +6953,7 @@ } } }, + "mutability": "Not", "pointee_type": "elided" } } @@ -6999,6 +7013,7 @@ } } }, + "mutability": "Not", "pointee_type": "elided" } } @@ -7058,6 +7073,7 @@ } } }, + "mutability": "Not", "pointee_type": "elided" } } @@ -7117,6 +7133,7 @@ } } }, + "mutability": "Not", "pointee_type": "elided" } } @@ -7176,6 +7193,7 @@ } } }, + "mutability": "Not", "pointee_type": "elided" } } @@ -7235,6 +7253,7 @@ } } }, + "mutability": "Not", "pointee_type": "elided" } } @@ -7291,6 +7310,7 @@ } } }, + "mutability": "Mut", "pointee_type": "elided" } } @@ -7347,6 +7367,7 @@ } } }, + "mutability": "Not", "pointee_type": "elided" } } @@ -7403,9 +7424,15 @@ } } }, + "mutability": "Not", "pointee_type": "elided" } } + ], + [ + { + "FunType": "{closure@std::rt::lang_start<()>::{closure#0}}" + } ] ] } diff --git a/tests/integration/programs/weirdRefs.rs b/tests/integration/programs/weirdRefs.rs index d80bfca2..4c471336 100644 --- a/tests/integration/programs/weirdRefs.rs +++ b/tests/integration/programs/weirdRefs.rs @@ -1,3 +1,4 @@ +//! @covers: mutable ref chains, struct with ref fields, field projections through derefs #[derive(Debug)] struct MyStruct { a_value: i8, From d81e16281ba6cc7e678bda73f2db0b4557a0b9cb Mon Sep 17 00:00:00 2001 From: cds-amal Date: Wed, 4 Mar 2026 14:12:58 -0500 Subject: [PATCH 03/13] feat(tests): add make trace-report for pipeline coverage analysis Adds a trace-report target that runs TRACE=1 across all integration tests and produces a coverage summary. The report shows: - event counts with per-program attribution - invariant verification (UnevaluatedConstDiscovered should stay at 0) - sub-category breakdown with gaps classified as actionable vs structurally unreachable (e.g. FnDef/FnPtr/Closure ty_kinds are actionable gaps; Coroutine/Pat are unreachable) - per-program @covers annotations extracted from test source files The analysis logic lives in trace-report.py (called by trace-report.sh) to keep the Makefile target minimal. --- Makefile | 7 +- tests/integration/trace-report.py | 204 ++++++++++++++++++++++++++++++ tests/integration/trace-report.sh | 22 ++++ 3 files changed, 232 insertions(+), 1 deletion(-) create mode 100644 tests/integration/trace-report.py create mode 100755 tests/integration/trace-report.sh diff --git a/Makefile b/Makefile index eace0fc9..be0301cf 100644 --- a/Makefile +++ b/Makefile @@ -43,7 +43,12 @@ integration-test: golden: make integration-test DIFF=">" -format: +.PHONY: trace-report +trace-report: SMIR ?= cargo run -- "-Zno-codegen" +trace-report: + bash tests/integration/trace-report.sh $(TESTDIR) $(SMIR) | tee tests/integration/trace-report.txt + +format: cargo fmt bash -O globstar -c 'nixfmt **/*.nix' diff --git a/tests/integration/trace-report.py b/tests/integration/trace-report.py new file mode 100644 index 00000000..8228c1af --- /dev/null +++ b/tests/integration/trace-report.py @@ -0,0 +1,204 @@ +"""Aggregate trace event coverage and report gaps. + +Called by trace-report.sh after TRACE=1 runs have been collected. +Usage: trace-report.py +""" + +import json +import glob +import os +import re +import sys +from collections import Counter + +trace_dir = sys.argv[1] +test_dir = sys.argv[2] if len(sys.argv) > 2 else None + +# ── Collect events ────────────────────────────────────────────────── + +counts = {} +by_program = {} # event -> { program -> count } +sub_values = {} # event -> field -> Counter(value -> count) +sub_programs = {} # event -> field -> value -> set(programs) + +SUB_FIELDS = ["ty_kind", "sym_kind", "source"] + +files = sorted(glob.glob(trace_dir + "/*.smir.trace.json")) +if not files: + print("No trace files found. Is TRACE=1 working?") + sys.exit(1) + +for f in files: + prog = os.path.basename(f).replace(".smir.trace.json", "") + for e in json.load(open(f)): + ev = e["event"] + counts[ev] = counts.get(ev, 0) + 1 + by_program.setdefault(ev, {}) + by_program[ev][prog] = by_program[ev].get(prog, 0) + 1 + for key in SUB_FIELDS: + if key in e: + sub_values.setdefault(ev, {}).setdefault(key, Counter()) + sub_values[ev][key][e[key]] += 1 + sub_programs.setdefault(ev, {}).setdefault(key, {}) + sub_programs[ev][key].setdefault(e[key], set()) + sub_programs[ev][key][e[key]].add(prog) + +n = len(files) + +# ── Event summary ─────────────────────────────────────────────────── + +print(f"Trace coverage across {n} test(s):\n") +print(f" {'Count':>6} Event") +print(f" {'-----':>6} -----") +for k, v in sorted(counts.items(), key=lambda x: -x[1]): + progs = by_program.get(k, {}) + np = len(progs) + if np == n: + detail = "all programs" + elif np <= 3: + detail = ", ".join(sorted(progs.keys())) + else: + detail = f"{np}/{n} programs" + print(f" {v:6} {k} ({detail})") + +# ── Coverage vs invariant classification ──────────────────────────── + +coverage_events = [ + "ItemDiscovered", "BodyWalkStarted", "BodyWalkFinished", + "FunctionCallResolved", "DropGlueResolved", "ReifyFnPointerResolved", + "AllocationCollected", "FnDefAsValue", + "TypeCollected", "SpanResolved", "AssemblyStarted", +] + +invariant_events = [ + "UnevaluatedConstDiscovered", +] + +uncovered = [e for e in coverage_events if e not in counts] +violated = [e for e in invariant_events if counts.get(e, 0) > 0] + +if uncovered: + print(f"\nUncovered ({len(uncovered)}):") + for e in uncovered: + print(f" ** {e}") + +if violated: + print(f"\nInvariant violations ({len(violated)}):") + for e in violated: + print(f" !! {e}: {counts[e]} occurrence(s)") + +held = [e for e in invariant_events if counts.get(e, 0) == 0] +if held: + print(f"\nInvariants holding ({len(held)}):") + for e in held: + print(f" ok {e}") + +if not uncovered and not violated: + print("\nAll coverage events exercised, all invariants holding.") + +# ── Sub-category breakdown ────────────────────────────────────────── + +# Known universe of values for each (event, field) pair, classified as +# either "actionable" (could be covered with a test) or "unreachable" +# (structurally impossible or requires unstable/exotic features). +# Each entry maps a value to a reason string (None = actionable). +KNOWN_UNIVERSE = { + ("TypeCollected", "ty_kind"): { + # actionable + "Bool": None, "Char": None, "Int": None, "Uint": None, "Float": None, + "Adt": None, "Str": None, "Array": None, "Slice": None, + "RawPtr": None, "Ref": None, "Dynamic": None, "Never": None, "Tuple": None, + "FnDef": None, "FnPtr": None, "Closure": None, + "Foreign": None, + # unreachable or exotic + "Coroutine": "async/generators monomorphize to ADT state machines", + "CoroutineWitness": "async/generators monomorphize to ADT state machines", + "Pat": "unstable feature (pattern_types)", + }, + ("FunctionCallResolved", "sym_kind"): { + "normal": None, "intrinsic": None, + "no_op": "no-op shims only arise from drop glue, not call terminators", + }, + ("DropGlueResolved", "sym_kind"): { + "no_op": None, + "normal": "drop glue is always a no-op shim", + "intrinsic": "drop glue is always a no-op shim", + }, + ("ReifyFnPointerResolved", "sym_kind"): { + "normal": None, + "intrinsic": "intrinsics cannot be coerced to fn pointers", + "no_op": "no-op shims cannot be coerced to fn pointers", + }, + ("ItemDiscovered", "source"): { + "mono_collect": None, + "unevaluated_const": "compiler eagerly evaluates all consts on current nightly", + }, +} + +print("\n" + "=" * 60) +print("Sub-category breakdown:") +print("=" * 60) + +for ev in sorted(sub_values): + for key in sorted(sub_values[ev]): + counter = sub_values[ev][key] + universe_key = (ev, key) + universe = KNOWN_UNIVERSE.get(universe_key) + + print(f"\n {ev} / {key}:") + for val, count in counter.most_common(): + progs = sub_programs[ev][key][val] + np = len(progs) + if np == n: + detail = "all" + elif np <= 3: + detail = ", ".join(sorted(progs)) + else: + detail = f"{np}/{n}" + print(f" {count:6} {val} ({detail})") + + if universe: + actionable = [v for v in universe if v not in counter and universe[v] is None] + unreachable = [(v, universe[v]) for v in universe if v not in counter and universe[v] is not None] + if actionable: + print(f" gaps (actionable):") + for v in actionable: + print(f" ** {v}") + if unreachable: + print(f" gaps (unreachable):") + for v, reason in unreachable: + print(f" -- {v} ({reason})") + +# ── Per-program annotations ───────────────────────────────────────── + +covers = {} +if test_dir: + for rs in sorted(glob.glob(test_dir + "/*.rs")): + prog = os.path.basename(rs).replace(".rs", "") + with open(rs) as f: + for line in f: + m = re.match(r"//[!/]\s*@covers:\s*(.+)", line) + if m: + covers[prog] = m.group(1).strip() + break + +if covers: + print(f"\nTest programs ({len(covers)}/{n} annotated):\n") + for prog in sorted(covers): + events = [] + for ev in sorted(by_program): + if prog in by_program[ev]: + events.append(ev) + print(f" {prog}") + print(f" covers: {covers[prog]}") + unique = [ev for ev in events if len(by_program[ev]) == 1] + if unique: + print(f" unique: {', '.join(unique)}") + unannotated = sorted(set( + os.path.basename(f).replace(".smir.trace.json", "") + for f in files + ) - set(covers)) + if unannotated: + print(f"\n Missing @covers annotation:") + for p in unannotated: + print(f" ** {p}") diff --git a/tests/integration/trace-report.sh b/tests/integration/trace-report.sh new file mode 100755 index 00000000..f5639b31 --- /dev/null +++ b/tests/integration/trace-report.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash +# Run TRACE=1 across integration tests and aggregate event coverage. +# +# Usage: trace-report.sh +# Example: trace-report.sh tests/integration/programs cargo run -- -Zno-codegen + +set -euo pipefail + +testdir="$1"; shift +smir=("$@") + +tmpdir=$(mktemp -d) +trap 'rm -rf "$tmpdir"' EXIT + +for rust in "$testdir"/*.rs; do + name=$(basename "$rust" .rs) + echo "Tracing $name..." + TRACE=1 "${smir[@]}" --out-dir "$tmpdir" "$rust" 2>/dev/null +done + +script_dir="$(cd "$(dirname "$0")" && pwd)" +python3 "$script_dir/trace-report.py" "$tmpdir" "$testdir" From 3baa24ea6779f7781c6a126906c8ee017d113caf Mon Sep 17 00:00:00 2001 From: cds-amal Date: Wed, 4 Mar 2026 19:41:09 -0500 Subject: [PATCH 04/13] fix(trace): emit TypeCollected events for FnDef, FnPtr, and Closure The Closure, FnDef, and FnPtr branches in TyCollector::visit_ty were traversing types without emitting TraceEvent::TypeCollected, so the trace report showed them as actionable coverage gaps even though the code paths were being exercised by every test program via stdlib. Closure was already inserted into the types map but lacked the trace push; FnDef and FnPtr are traversal-only (not stored) but still deserve trace visibility. --- src/printer/ty_visitor.rs | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/printer/ty_visitor.rs b/src/printer/ty_visitor.rs index 632f6241..01060852 100644 --- a/src/printer/ty_visitor.rs +++ b/src/printer/ty_visitor.rs @@ -70,8 +70,16 @@ impl Visitor for TyCollector<'_> { let control = self.visit_instance(instance); // Mirror other branches: record closure Ty only when traversal succeeds. if matches!(control, ControlFlow::Continue(_)) { + let kind = ty.kind(); let maybe_layout_shape = ty.layout().ok().map(|layout| layout.shape()); - self.types.insert(*ty, (ty.kind(), maybe_layout_shape)); + if let Some(buf) = &mut self.trace_buffer { + buf.push(TraceEvent::TypeCollected { + item: String::new(), + location: None, + ty_kind: ty_kind_tag(&kind).to_string(), + }); + } + self.types.insert(*ty, (kind, maybe_layout_shape)); } control } @@ -82,11 +90,25 @@ impl Visitor for TyCollector<'_> { } TyKind::RigidTy(RigidTy::FnDef(def, ref args)) => { self.resolved.insert(*ty); + if let Some(buf) = &mut self.trace_buffer { + buf.push(TraceEvent::TypeCollected { + item: String::new(), + location: None, + ty_kind: "FnDef".to_string(), + }); + } let instance = Instance::resolve(def, args).unwrap(); self.visit_instance(instance) } TyKind::RigidTy(RigidTy::FnPtr(binder_stable)) => { self.resolved.insert(*ty); + if let Some(buf) = &mut self.trace_buffer { + buf.push(TraceEvent::TypeCollected { + item: String::new(), + location: None, + ty_kind: "FnPtr".to_string(), + }); + } let fn_abi = crate::compat::types::fn_ptr_abi(self.tcx, binder_stable); let mut inputs_outputs: Vec = fn_abi.args.iter().map(|arg_abi| arg_abi.ty).collect(); From 5bce3c82999d4d2740715bca5248772d224094f0 Mon Sep 17 00:00:00 2001 From: cds-amal Date: Wed, 4 Mar 2026 19:41:18 -0500 Subject: [PATCH 05/13] feat(trace): use readable item names, annotate stdlib-only coverage Switch tracer.current_item from mangled symbol names to readable (demangled) names (e.g. "main", "std::rt::lang_start::<()>") so downstream scripts can classify items by origin without a demangler. The mangled name is preserved in current_item_symbol for consumers that need it. The trace report now tracks whether each sub-category value (ty_kind, sym_kind, etc.) was ever seen from a user-code body vs only from stdlib bodies, and annotates the latter with "stdlib only" in the breakdown. --- src/printer/collect.rs | 18 +++++++++++++++--- src/printer/tracer.rs | 11 ++++++++++- tests/integration/trace-report.py | 24 ++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 4 deletions(-) diff --git a/src/printer/collect.rs b/src/printer/collect.rs index 228e0680..22bc69f1 100644 --- a/src/printer/collect.rs +++ b/src/printer/collect.rs @@ -35,6 +35,15 @@ use super::util::take_any; use crate::compat::mono_collect::mono_item_name; +/// Readable (demangled) name for a mono item, used by the tracer. +fn readable_item_name(mono_item: &MonoItem) -> String { + match mono_item { + MonoItem::Fn(inst) => inst.name(), + MonoItem::Static(def) => def.name(), + MonoItem::GlobalAsm(data) => crate::printer::hash(data).to_string(), + } +} + /// Log a warning when a body was expected but missing. fn warn_missing_body(mono_item: &MonoItem) { match mono_item { @@ -152,9 +161,11 @@ fn collect_and_analyze_items( // Emit BodyWalkStarted before creating the BodyAnalyzer (borrow scoping). if let Some(tracer) = tracer.as_mut() { let before = snapshot(&calls_map, &visited_allocs, &ty_visitor, &span_map); - tracer.current_item = Some(item.symbol_name.clone()); + let readable = readable_item_name(&mono_item); + tracer.current_item = Some(readable.clone()); + tracer.current_item_symbol = Some(item.symbol_name.clone()); tracer.push(TraceEvent::BodyWalkStarted { - item: item.symbol_name.clone(), + item: readable, before, }); } @@ -179,10 +190,11 @@ fn collect_and_analyze_items( if let Some(tracer) = tracer.as_mut() { let after = snapshot(&calls_map, &visited_allocs, &ty_visitor, &span_map); tracer.push(TraceEvent::BodyWalkFinished { - item: item.symbol_name.clone(), + item: tracer.item_name(), after, }); tracer.current_item = None; + tracer.current_item_symbol = None; } enqueue_unevaluated_consts( diff --git a/src/printer/tracer.rs b/src/printer/tracer.rs index e2bb5dd3..8ff48284 100644 --- a/src/printer/tracer.rs +++ b/src/printer/tracer.rs @@ -153,7 +153,15 @@ pub(super) enum TraceEvent { /// Accumulates trace events during the pipeline. pub(super) struct Tracer { pub events: Vec, + /// Readable (demangled) name of the item currently being walked. pub current_item: Option, + /// Mangled symbol name of the item currently being walked. + // TODO(review): trace events currently use the readable name (`current_item`) + // so that downstream scripts (trace-report.py) can match items to their + // originating crate without a demangler. We keep the mangled name around in + // case downstream consumers need it. If reviewers prefer mangled-only or + // both-in-every-event, this is the place to change it. + pub current_item_symbol: Option, } impl Tracer { @@ -161,6 +169,7 @@ impl Tracer { Tracer { events: Vec::new(), current_item: None, + current_item_symbol: None, } } @@ -168,7 +177,7 @@ impl Tracer { self.events.push(event); } - /// The current item name, or a fallback for events outside a body walk. + /// The current readable item name, or a fallback for events outside a body walk. pub fn item_name(&self) -> String { self.current_item .clone() diff --git a/tests/integration/trace-report.py b/tests/integration/trace-report.py index 8228c1af..f0519167 100644 --- a/tests/integration/trace-report.py +++ b/tests/integration/trace-report.py @@ -23,6 +23,10 @@ SUB_FIELDS = ["ty_kind", "sym_kind", "source"] +# Track whether a sub-category value was seen via user code (not just stdlib). +# Key structure mirrors sub_programs: event -> field -> value -> set(programs). +sub_user_programs = {} + files = sorted(glob.glob(trace_dir + "/*.smir.trace.json")) if not files: print("No trace files found. Is TRACE=1 working?") @@ -30,6 +34,9 @@ for f in files: prog = os.path.basename(f).replace(".smir.trace.json", "") + # Trace events now use readable (demangled) item names, e.g. "main", + # "test_binop", "main::{closure#0}". Stdlib items start with "std::", + # "core::", "alloc::", or "<" (trait impl shims). for e in json.load(open(f)): ev = e["event"] counts[ev] = counts.get(ev, 0) + 1 @@ -42,6 +49,19 @@ sub_programs.setdefault(ev, {}).setdefault(key, {}) sub_programs[ev][key].setdefault(e[key], set()) sub_programs[ev][key][e[key]].add(prog) + # Check if this event came from user code (not stdlib). + item = e.get("item", "") + is_stdlib = ( + not item + or item.startswith("std::") + or item.startswith("core::") + or item.startswith("alloc::") + or item.startswith("<") + ) + if not is_stdlib: + sub_user_programs.setdefault(ev, {}).setdefault(key, {}) + sub_user_programs[ev][key].setdefault(e[key], set()) + sub_user_programs[ev][key][e[key]].add(prog) n = len(files) @@ -155,6 +175,10 @@ detail = ", ".join(sorted(progs)) else: detail = f"{np}/{n}" + # Annotate if this value only appears via stdlib bodies. + user_progs = sub_user_programs.get(ev, {}).get(key, {}).get(val, set()) + if not user_progs: + detail += ", stdlib only" print(f" {count:6} {val} ({detail})") if universe: From e43b69ab55830f9d87a2f277ac79247428435c3d Mon Sep 17 00:00:00 2001 From: cds-amal Date: Wed, 4 Mar 2026 19:41:24 -0500 Subject: [PATCH 06/13] test: add foreign-type test, close all actionable coverage gaps Add foreign-type.rs exercising extern types (the only ty_kind that genuinely needed a new test program; FnDef, FnPtr, and Closure were already covered by existing tests via stdlib but weren't being traced). The trace report now shows zero actionable gaps across all sub-category breakdowns. --- tests/integration/programs/foreign-type.rs | 13 + .../programs/foreign-type.smir.json.expected | 2704 +++++++++++++++++ tests/integration/trace-report.txt | 171 ++ 3 files changed, 2888 insertions(+) create mode 100644 tests/integration/programs/foreign-type.rs create mode 100644 tests/integration/programs/foreign-type.smir.json.expected create mode 100644 tests/integration/trace-report.txt diff --git a/tests/integration/programs/foreign-type.rs b/tests/integration/programs/foreign-type.rs new file mode 100644 index 00000000..ad48b0ff --- /dev/null +++ b/tests/integration/programs/foreign-type.rs @@ -0,0 +1,13 @@ +//! @covers: Foreign type kind (extern type used behind a pointer) +#![feature(extern_types)] + +extern "C" { + type Opaque; +} + +fn main() { + // Create a raw pointer to a Foreign type. + // We never dereference it; we just need the type to be collected. + let ptr: *const Opaque = core::ptr::null::() as *const Opaque; + assert!(ptr.is_null()); +} diff --git a/tests/integration/programs/foreign-type.smir.json.expected b/tests/integration/programs/foreign-type.smir.json.expected new file mode 100644 index 00000000..bbc921ca --- /dev/null +++ b/tests/integration/programs/foreign-type.smir.json.expected @@ -0,0 +1,2704 @@ +{ + "allocs": [ + { + "global_alloc": { + "Memory": { + "align": 1, + "bytes": [ + 97, + 115, + 115, + 101, + 114, + 116, + 105, + 111, + 110, + 32, + 102, + 97, + 105, + 108, + 101, + 100, + 58, + 32, + 112, + 116, + 114, + 46, + 105, + 115, + 95, + 110, + 117, + 108, + 108, + 40, + 41 + ], + "mutability": "Not", + "provenance": { + "ptrs": [] + } + } + } + } + ], + "functions": [ + [ + { + "IntrinsicSym": "black_box" + } + ], + [ + { + "NoOpSym": "" + } + ], + [ + { + "NormalSym": "_ZN3std2rt10lang_start28_$u7b$$u7b$closure$u7d$$u7d$17h" + } + ], + [ + { + "NormalSym": "_ZN3std2rt19lang_start_internal17h" + } + ], + [ + { + "NormalSym": "_ZN3std3sys9backtrace28__rust_begin_short_backtrace17h" + } + ], + [ + { + "NormalSym": "_ZN4core3ops8function6FnOnce9call_once17h" + } + ], + [ + { + "NormalSym": "_ZN4core3ops8function6FnOnce9call_once17h" + } + ], + [ + { + "NormalSym": "_ZN4core3ptr4null17h" + } + ], + [ + { + "NormalSym": "_ZN4core3ptr9const_ptr33_$LT$impl$u20$$BP$const$u20$T$GT$7is_null17h" + } + ], + [ + { + "NormalSym": "_ZN4core9panicking5panic17h" + } + ], + [ + { + "NormalSym": "_ZN54_$LT$$LP$$RP$$u20$as$u20$std..process..Termination$GT$6report17h" + } + ] + ], + "items": [ + { + "details": null, + "mono_item_kind": { + "MonoItemFn": { + "body": { + "arg_count": 0, + "blocks": [ + { + "statements": [], + "terminator": { + "kind": { + "Call": { + "args": [], + "destination": { + "local": 2, + "projection": [] + }, + "func": { + "Constant": { + "const_": { + "id": 12, + "kind": "ZeroSized" + }, + "span": 71, + "user_ty": null + } + }, + "target": 1, + "unwind": "Continue" + } + }, + "span": 72 + } + }, + { + "statements": [ + { + "kind": { + "Assign": [ + { + "local": 1, + "projection": [] + }, + { + "Cast": [ + "PtrToPtr", + { + "Move": { + "local": 2, + "projection": [] + } + }, + 29 + ] + } + ] + }, + "span": 75 + } + ], + "terminator": { + "kind": { + "Call": { + "args": [ + { + "Copy": { + "local": 1, + "projection": [] + } + } + ], + "destination": { + "local": 3, + "projection": [] + }, + "func": { + "Constant": { + "const_": { + "id": 13, + "kind": "ZeroSized" + }, + "span": 73, + "user_ty": null + } + }, + "target": 2, + "unwind": "Continue" + } + }, + "span": 74 + } + }, + { + "statements": [], + "terminator": { + "kind": { + "SwitchInt": { + "discr": { + "Move": { + "local": 3, + "projection": [] + } + }, + "targets": { + "branches": [ + [ + 0, + 4 + ] + ], + "otherwise": 3 + } + } + }, + "span": 74 + } + }, + { + "statements": [], + "terminator": { + "kind": "Return", + "span": 76 + } + }, + { + "statements": [], + "terminator": { + "kind": { + "Call": { + "args": [ + { + "Constant": { + "const_": { + "id": 15, + "kind": { + "Allocated": { + "align": 8, + "bytes": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 31, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "mutability": "Mut", + "provenance": { + "ptrs": [ + [ + 0, + 0 + ] + ] + } + } + } + }, + "span": 32, + "user_ty": null + } + } + ], + "destination": { + "local": 4, + "projection": [] + }, + "func": { + "Constant": { + "const_": { + "id": 14, + "kind": "ZeroSized" + }, + "span": 77, + "user_ty": null + } + }, + "target": null, + "unwind": "Continue" + } + }, + "span": 77 + } + } + ], + "locals": [ + { + "mutability": "Mut", + "span": 78 + }, + { + "mutability": "Not", + "span": 79 + }, + { + "mutability": "Mut", + "span": 72 + }, + { + "mutability": "Mut", + "span": 74 + }, + { + "mutability": "Mut", + "span": 77 + } + ], + "span": 80, + "spread_arg": null, + "var_debug_info": [ + { + "argument_index": null, + "composite": null, + "name": "ptr", + "source_info": { + "scope": 1, + "span": 79 + }, + "value": { + "Place": { + "local": 1, + "projection": [] + } + } + } + ] + }, + "id": 8, + "name": "main" + } + }, + "symbol_name": "_ZN12foreign_type4main17h" + }, + { + "details": null, + "mono_item_kind": { + "MonoItemFn": { + "body": { + "arg_count": 0, + "blocks": [ + { + "statements": [ + { + "kind": { + "Assign": [ + { + "local": 0, + "projection": [] + }, + { + "Use": { + "Constant": { + "const_": { + "id": 8, + "kind": { + "Allocated": { + "align": 8, + "bytes": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "mutability": "Mut", + "provenance": { + "ptrs": [] + } + } + } + }, + "span": 32, + "user_ty": null + } + } + } + ] + }, + "span": 45 + } + ], + "terminator": { + "kind": "Return", + "span": 44 + } + } + ], + "locals": [ + { + "mutability": "Mut", + "span": 46 + } + ], + "span": 51, + "spread_arg": null, + "var_debug_info": [ + { + "argument_index": 1, + "composite": null, + "name": "addr", + "source_info": { + "scope": 1, + "span": 47 + }, + "value": { + "Const": { + "const_": { + "id": 9, + "kind": { + "Allocated": { + "align": 8, + "bytes": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "mutability": "Mut", + "provenance": { + "ptrs": [] + } + } + } + }, + "span": 48, + "user_ty": null + } + } + }, + { + "argument_index": 1, + "composite": null, + "name": "data_pointer", + "source_info": { + "scope": 2, + "span": 49 + }, + "value": { + "Const": { + "const_": { + "id": 10, + "kind": { + "Allocated": { + "align": 8, + "bytes": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "mutability": "Mut", + "provenance": { + "ptrs": [] + } + } + } + }, + "span": 32, + "user_ty": null + } + } + }, + { + "argument_index": 2, + "composite": null, + "name": "metadata", + "source_info": { + "scope": 2, + "span": 50 + }, + "value": { + "Const": { + "const_": { + "id": 4, + "kind": "ZeroSized" + }, + "span": 32, + "user_ty": null + } + } + } + ] + }, + "id": 4, + "name": "std::ptr::null::" + } + }, + "symbol_name": "_ZN4core3ptr4null17h" + }, + { + "details": null, + "mono_item_kind": { + "MonoItemFn": { + "body": { + "arg_count": 1, + "blocks": [ + { + "statements": [], + "terminator": { + "kind": "Return", + "span": 52 + } + } + ], + "locals": [ + { + "mutability": "Mut", + "span": 52 + }, + { + "mutability": "Not", + "span": 52 + } + ], + "span": 52, + "spread_arg": null, + "var_debug_info": [] + }, + "id": 5, + "name": "std::ptr::drop_in_place::<{closure@std::rt::lang_start<()>::{closure#0}}>" + } + }, + "symbol_name": "_ZN4core3ptr85drop_in_place$LT$std..rt..lang_start$LT$$LP$$RP$$GT$..$u7b$$u7b$closure$u7d$$u7d$$GT$17h" + }, + { + "details": null, + "mono_item_kind": { + "MonoItemFn": { + "body": { + "arg_count": 1, + "blocks": [ + { + "statements": [], + "terminator": { + "kind": { + "Call": { + "args": [ + { + "Move": { + "local": 1, + "projection": [] + } + }, + { + "Constant": { + "const_": { + "id": 4, + "kind": "ZeroSized" + }, + "span": 32, + "user_ty": null + } + } + ], + "destination": { + "local": 0, + "projection": [] + }, + "func": { + "Constant": { + "const_": { + "id": 3, + "kind": "ZeroSized" + }, + "span": 31, + "user_ty": null + } + }, + "target": 1, + "unwind": "Continue" + } + }, + "span": 33 + } + }, + { + "statements": [], + "terminator": { + "kind": { + "Call": { + "args": [ + { + "Constant": { + "const_": { + "id": 4, + "kind": "ZeroSized" + }, + "span": 32, + "user_ty": null + } + } + ], + "destination": { + "local": 2, + "projection": [] + }, + "func": { + "Constant": { + "const_": { + "id": 5, + "kind": "ZeroSized" + }, + "span": 34, + "user_ty": null + } + }, + "target": 2, + "unwind": "Unreachable" + } + }, + "span": 35 + } + }, + { + "statements": [], + "terminator": { + "kind": "Return", + "span": 36 + } + } + ], + "locals": [ + { + "mutability": "Mut", + "span": 37 + }, + { + "mutability": "Not", + "span": 38 + }, + { + "mutability": "Not", + "span": 39 + } + ], + "span": 42, + "spread_arg": null, + "var_debug_info": [ + { + "argument_index": 1, + "composite": null, + "name": "f", + "source_info": { + "scope": 0, + "span": 38 + }, + "value": { + "Place": { + "local": 1, + "projection": [] + } + } + }, + { + "argument_index": null, + "composite": null, + "name": "result", + "source_info": { + "scope": 1, + "span": 40 + }, + "value": { + "Place": { + "local": 0, + "projection": [] + } + } + }, + { + "argument_index": 1, + "composite": null, + "name": "dummy", + "source_info": { + "scope": 2, + "span": 41 + }, + "value": { + "Const": { + "const_": { + "id": 4, + "kind": "ZeroSized" + }, + "span": 32, + "user_ty": null + } + } + } + ] + }, + "id": 2, + "name": "std::sys::backtrace::__rust_begin_short_backtrace::" + } + }, + "symbol_name": "_ZN3std3sys9backtrace28__rust_begin_short_backtrace17h" + }, + { + "details": null, + "mono_item_kind": { + "MonoItemFn": { + "body": { + "arg_count": 1, + "blocks": [ + { + "statements": [ + { + "kind": { + "Assign": [ + { + "local": 0, + "projection": [] + }, + { + "Use": { + "Constant": { + "const_": { + "id": 11, + "kind": { + "Allocated": { + "align": 1, + "bytes": [ + 0 + ], + "mutability": "Mut", + "provenance": { + "ptrs": [] + } + } + } + }, + "span": 67, + "user_ty": null + } + } + } + ] + }, + "span": 67 + } + ], + "terminator": { + "kind": "Return", + "span": 66 + } + } + ], + "locals": [ + { + "mutability": "Mut", + "span": 68 + }, + { + "mutability": "Not", + "span": 69 + } + ], + "span": 70, + "spread_arg": null, + "var_debug_info": [ + { + "argument_index": 1, + "composite": null, + "name": "self", + "source_info": { + "scope": 0, + "span": 69 + }, + "value": { + "Const": { + "const_": { + "id": 4, + "kind": "ZeroSized" + }, + "span": 32, + "user_ty": null + } + } + } + ] + }, + "id": 7, + "name": "<() as std::process::Termination>::report" + } + }, + "symbol_name": "_ZN54_$LT$$LP$$RP$$u20$as$u20$std..process..Termination$GT$6report17h" + }, + { + "details": null, + "mono_item_kind": { + "MonoItemFn": { + "body": { + "arg_count": 1, + "blocks": [ + { + "statements": [ + { + "kind": { + "Assign": [ + { + "local": 2, + "projection": [] + }, + { + "Cast": [ + "PtrToPtr", + { + "Copy": { + "local": 1, + "projection": [] + } + }, + 25 + ] + } + ] + }, + "span": 54 + }, + { + "kind": { + "StorageLive": 3 + }, + "span": 55 + }, + { + "kind": { + "Assign": [ + { + "local": 3, + "projection": [] + }, + { + "Cast": [ + "Transmute", + { + "Copy": { + "local": 2, + "projection": [] + } + }, + 26 + ] + } + ] + }, + "span": 56 + }, + { + "kind": { + "Assign": [ + { + "local": 0, + "projection": [] + }, + { + "BinaryOp": [ + "Eq", + { + "Move": { + "local": 3, + "projection": [] + } + }, + { + "Constant": { + "const_": { + "id": 9, + "kind": { + "Allocated": { + "align": 8, + "bytes": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "mutability": "Mut", + "provenance": { + "ptrs": [] + } + } + } + }, + "span": 57, + "user_ty": null + } + } + ] + } + ] + }, + "span": 58 + }, + { + "kind": { + "StorageDead": 3 + }, + "span": 57 + } + ], + "terminator": { + "kind": "Return", + "span": 53 + } + } + ], + "locals": [ + { + "mutability": "Mut", + "span": 59 + }, + { + "mutability": "Not", + "span": 60 + }, + { + "mutability": "Not", + "span": 61 + }, + { + "mutability": "Mut", + "span": 55 + } + ], + "span": 65, + "spread_arg": null, + "var_debug_info": [ + { + "argument_index": 1, + "composite": null, + "name": "self", + "source_info": { + "scope": 0, + "span": 60 + }, + "value": { + "Place": { + "local": 1, + "projection": [] + } + } + }, + { + "argument_index": null, + "composite": null, + "name": "ptr", + "source_info": { + "scope": 1, + "span": 61 + }, + "value": { + "Place": { + "local": 2, + "projection": [] + } + } + }, + { + "argument_index": 1, + "composite": null, + "name": "ptr", + "source_info": { + "scope": 2, + "span": 62 + }, + "value": { + "Place": { + "local": 2, + "projection": [] + } + } + }, + { + "argument_index": 1, + "composite": null, + "name": "self", + "source_info": { + "scope": 3, + "span": 63 + }, + "value": { + "Place": { + "local": 2, + "projection": [] + } + } + }, + { + "argument_index": 1, + "composite": null, + "name": "self", + "source_info": { + "scope": 4, + "span": 64 + }, + "value": { + "Place": { + "local": 2, + "projection": [] + } + } + } + ] + }, + "id": 6, + "name": "std::ptr::const_ptr::::is_null" + } + }, + "symbol_name": "_ZN4core3ptr9const_ptr33_$LT$impl$u20$$BP$const$u20$T$GT$7is_null17h" + }, + { + "details": null, + "mono_item_kind": { + "MonoItemFn": { + "body": { + "arg_count": 1, + "blocks": [ + { + "statements": [ + { + "kind": { + "StorageLive": 2 + }, + "span": 16 + }, + { + "kind": { + "StorageLive": 3 + }, + "span": 15 + }, + { + "kind": { + "StorageLive": 4 + }, + "span": 17 + }, + { + "kind": { + "Assign": [ + { + "local": 4, + "projection": [] + }, + { + "Use": { + "Copy": { + "local": 1, + "projection": [ + "Deref", + { + "Field": [ + 0, + 7 + ] + } + ] + } + } + } + ] + }, + "span": 17 + } + ], + "terminator": { + "kind": { + "Call": { + "args": [ + { + "Move": { + "local": 4, + "projection": [] + } + } + ], + "destination": { + "local": 3, + "projection": [] + }, + "func": { + "Constant": { + "const_": { + "id": 1, + "kind": "ZeroSized" + }, + "span": 14, + "user_ty": null + } + }, + "target": 1, + "unwind": "Continue" + } + }, + "span": 15 + } + }, + { + "statements": [ + { + "kind": { + "StorageDead": 4 + }, + "span": 19 + } + ], + "terminator": { + "kind": { + "Call": { + "args": [ + { + "Move": { + "local": 3, + "projection": [] + } + } + ], + "destination": { + "local": 2, + "projection": [] + }, + "func": { + "Constant": { + "const_": { + "id": 2, + "kind": "ZeroSized" + }, + "span": 18, + "user_ty": null + } + }, + "target": 2, + "unwind": "Continue" + } + }, + "span": 16 + } + }, + { + "statements": [ + { + "kind": { + "StorageDead": 3 + }, + "span": 21 + }, + { + "kind": { + "StorageLive": 5 + }, + "span": 22 + }, + { + "kind": { + "Assign": [ + { + "local": 5, + "projection": [] + }, + { + "Ref": [ + { + "kind": "ReErased" + }, + "Shared", + { + "local": 2, + "projection": [ + { + "Field": [ + 0, + 15 + ] + } + ] + } + ] + } + ] + }, + "span": 22 + }, + { + "kind": { + "StorageLive": 6 + }, + "span": 23 + }, + { + "kind": { + "Assign": [ + { + "local": 6, + "projection": [] + }, + { + "Use": { + "Copy": { + "local": 2, + "projection": [ + { + "Field": [ + 0, + 15 + ] + }, + { + "Field": [ + 0, + 9 + ] + } + ] + } + } + } + ] + }, + "span": 23 + }, + { + "kind": { + "Assign": [ + { + "local": 0, + "projection": [] + }, + { + "Cast": [ + "IntToInt", + { + "Move": { + "local": 6, + "projection": [] + } + }, + 16 + ] + } + ] + }, + "span": 24 + }, + { + "kind": { + "StorageDead": 6 + }, + "span": 25 + }, + { + "kind": { + "StorageDead": 5 + }, + "span": 26 + }, + { + "kind": { + "StorageDead": 2 + }, + "span": 27 + } + ], + "terminator": { + "kind": "Return", + "span": 20 + } + } + ], + "locals": [ + { + "mutability": "Mut", + "span": 28 + }, + { + "mutability": "Mut", + "span": 3 + }, + { + "mutability": "Mut", + "span": 16 + }, + { + "mutability": "Mut", + "span": 15 + }, + { + "mutability": "Mut", + "span": 17 + }, + { + "mutability": "Mut", + "span": 22 + }, + { + "mutability": "Mut", + "span": 23 + } + ], + "span": 3, + "spread_arg": null, + "var_debug_info": [ + { + "argument_index": null, + "composite": null, + "name": "main", + "source_info": { + "scope": 0, + "span": 9 + }, + "value": { + "Place": { + "local": 1, + "projection": [ + "Deref", + { + "Field": [ + 0, + 7 + ] + } + ] + } + } + }, + { + "argument_index": 1, + "composite": null, + "name": "self", + "source_info": { + "scope": 1, + "span": 29 + }, + "value": { + "Place": { + "local": 2, + "projection": [] + } + } + }, + { + "argument_index": 1, + "composite": null, + "name": "self", + "source_info": { + "scope": 2, + "span": 30 + }, + "value": { + "Place": { + "local": 5, + "projection": [] + } + } + } + ] + }, + "id": 1, + "name": "std::rt::lang_start::<()>::{closure#0}" + } + }, + "symbol_name": "_ZN3std2rt10lang_start28_$u7b$$u7b$closure$u7d$$u7d$17h" + }, + { + "details": null, + "mono_item_kind": { + "MonoItemFn": { + "body": { + "arg_count": 2, + "blocks": [ + { + "statements": [], + "terminator": { + "kind": { + "Call": { + "args": [], + "destination": { + "local": 0, + "projection": [] + }, + "func": { + "Move": { + "local": 1, + "projection": [] + } + }, + "target": 1, + "unwind": "Continue" + } + }, + "span": 43 + } + }, + { + "statements": [], + "terminator": { + "kind": "Return", + "span": 43 + } + } + ], + "locals": [ + { + "mutability": "Mut", + "span": 43 + }, + { + "mutability": "Not", + "span": 43 + }, + { + "mutability": "Not", + "span": 43 + } + ], + "span": 43, + "spread_arg": 2, + "var_debug_info": [] + }, + "id": 3, + "name": ">::call_once" + } + }, + "symbol_name": "_ZN4core3ops8function6FnOnce9call_once17h" + }, + { + "details": null, + "mono_item_kind": { + "MonoItemFn": { + "body": { + "arg_count": 2, + "blocks": [ + { + "statements": [], + "terminator": { + "kind": { + "Call": { + "args": [ + { + "Move": { + "local": 1, + "projection": [ + "Deref" + ] + } + }, + { + "Move": { + "local": 2, + "projection": [] + } + } + ], + "destination": { + "local": 0, + "projection": [] + }, + "func": { + "Constant": { + "const_": { + "id": 6, + "kind": "ZeroSized" + }, + "span": 43, + "user_ty": null + } + }, + "target": 1, + "unwind": "Continue" + } + }, + "span": 43 + } + }, + { + "statements": [], + "terminator": { + "kind": "Return", + "span": 43 + } + } + ], + "locals": [ + { + "mutability": "Mut", + "span": 43 + }, + { + "mutability": "Not", + "span": 43 + }, + { + "mutability": "Not", + "span": 43 + } + ], + "span": 43, + "spread_arg": 2, + "var_debug_info": [] + }, + "id": 3, + "name": "<{closure@std::rt::lang_start<()>::{closure#0}} as std::ops::FnOnce<()>>::call_once" + } + }, + "symbol_name": "_ZN4core3ops8function6FnOnce40call_once$u7b$$u7b$vtable.shim$u7d$$u7d$17h" + }, + { + "details": null, + "mono_item_kind": { + "MonoItemFn": { + "body": { + "arg_count": 2, + "blocks": [ + { + "statements": [ + { + "kind": { + "Assign": [ + { + "local": 3, + "projection": [] + }, + { + "Ref": [ + { + "kind": "ReErased" + }, + { + "Mut": { + "kind": "Default" + } + }, + { + "local": 1, + "projection": [] + } + ] + } + ] + }, + "span": 43 + } + ], + "terminator": { + "kind": { + "Call": { + "args": [ + { + "Move": { + "local": 3, + "projection": [] + } + }, + { + "Move": { + "local": 2, + "projection": [] + } + } + ], + "destination": { + "local": 0, + "projection": [] + }, + "func": { + "Constant": { + "const_": { + "id": 7, + "kind": "ZeroSized" + }, + "span": 43, + "user_ty": null + } + }, + "target": 1, + "unwind": { + "Cleanup": 3 + } + } + }, + "span": 43 + } + }, + { + "statements": [], + "terminator": { + "kind": { + "Drop": { + "place": { + "local": 1, + "projection": [] + }, + "target": 2, + "unwind": "Continue" + } + }, + "span": 43 + } + }, + { + "statements": [], + "terminator": { + "kind": "Return", + "span": 43 + } + }, + { + "statements": [], + "terminator": { + "kind": { + "Drop": { + "place": { + "local": 1, + "projection": [] + }, + "target": 4, + "unwind": "Terminate" + } + }, + "span": 43 + } + }, + { + "statements": [], + "terminator": { + "kind": "Resume", + "span": 43 + } + } + ], + "locals": [ + { + "mutability": "Mut", + "span": 43 + }, + { + "mutability": "Not", + "span": 43 + }, + { + "mutability": "Not", + "span": 43 + }, + { + "mutability": "Not", + "span": 43 + } + ], + "span": 43, + "spread_arg": 2, + "var_debug_info": [] + }, + "id": 3, + "name": "<{closure@std::rt::lang_start<()>::{closure#0}} as std::ops::FnOnce<()>>::call_once" + } + }, + "symbol_name": "_ZN4core3ops8function6FnOnce9call_once17h" + }, + { + "details": null, + "mono_item_kind": { + "MonoItemFn": { + "body": { + "arg_count": 4, + "blocks": [ + { + "statements": [ + { + "kind": { + "StorageLive": 5 + }, + "span": 1 + }, + { + "kind": { + "StorageLive": 6 + }, + "span": 2 + }, + { + "kind": { + "StorageLive": 8 + }, + "span": 3 + }, + { + "kind": { + "Assign": [ + { + "local": 8, + "projection": [] + }, + { + "Aggregate": [ + { + "Closure": [ + 1, + [ + { + "Type": 1 + }, + { + "Type": 2 + }, + { + "Type": 3 + }, + { + "Type": 4 + } + ] + ] + }, + [ + { + "Copy": { + "local": 1, + "projection": [] + } + } + ] + ] + } + ] + }, + "span": 3 + }, + { + "kind": { + "Assign": [ + { + "local": 7, + "projection": [] + }, + { + "Ref": [ + { + "kind": "ReErased" + }, + "Shared", + { + "local": 8, + "projection": [] + } + ] + } + ] + }, + "span": 2 + }, + { + "kind": { + "Assign": [ + { + "local": 6, + "projection": [] + }, + { + "Cast": [ + { + "PointerCoercion": "Unsize" + }, + { + "Copy": { + "local": 7, + "projection": [] + } + }, + 5 + ] + } + ] + }, + "span": 2 + } + ], + "terminator": { + "kind": { + "Call": { + "args": [ + { + "Move": { + "local": 6, + "projection": [] + } + }, + { + "Move": { + "local": 2, + "projection": [] + } + }, + { + "Move": { + "local": 3, + "projection": [] + } + }, + { + "Move": { + "local": 4, + "projection": [] + } + } + ], + "destination": { + "local": 5, + "projection": [] + }, + "func": { + "Constant": { + "const_": { + "id": 0, + "kind": "ZeroSized" + }, + "span": 0, + "user_ty": null + } + }, + "target": 1, + "unwind": "Continue" + } + }, + "span": 1 + } + }, + { + "statements": [ + { + "kind": { + "StorageDead": 6 + }, + "span": 5 + }, + { + "kind": { + "Assign": [ + { + "local": 0, + "projection": [] + }, + { + "Use": { + "Copy": { + "local": 5, + "projection": [ + { + "Downcast": 0 + }, + { + "Field": [ + 0, + 6 + ] + } + ] + } + } + } + ] + }, + "span": 6 + }, + { + "kind": { + "StorageDead": 8 + }, + "span": 7 + }, + { + "kind": { + "StorageDead": 5 + }, + "span": 7 + } + ], + "terminator": { + "kind": "Return", + "span": 4 + } + } + ], + "locals": [ + { + "mutability": "Mut", + "span": 8 + }, + { + "mutability": "Not", + "span": 9 + }, + { + "mutability": "Not", + "span": 10 + }, + { + "mutability": "Not", + "span": 11 + }, + { + "mutability": "Not", + "span": 12 + }, + { + "mutability": "Mut", + "span": 1 + }, + { + "mutability": "Mut", + "span": 2 + }, + { + "mutability": "Not", + "span": 2 + }, + { + "mutability": "Not", + "span": 3 + } + ], + "span": 13, + "spread_arg": null, + "var_debug_info": [ + { + "argument_index": 1, + "composite": null, + "name": "main", + "source_info": { + "scope": 0, + "span": 9 + }, + "value": { + "Place": { + "local": 1, + "projection": [] + } + } + }, + { + "argument_index": 2, + "composite": null, + "name": "argc", + "source_info": { + "scope": 0, + "span": 10 + }, + "value": { + "Place": { + "local": 2, + "projection": [] + } + } + }, + { + "argument_index": 3, + "composite": null, + "name": "argv", + "source_info": { + "scope": 0, + "span": 11 + }, + "value": { + "Place": { + "local": 3, + "projection": [] + } + } + }, + { + "argument_index": 4, + "composite": null, + "name": "sigpipe", + "source_info": { + "scope": 0, + "span": 12 + }, + "value": { + "Place": { + "local": 4, + "projection": [] + } + } + }, + { + "argument_index": null, + "composite": null, + "name": "v", + "source_info": { + "scope": 1, + "span": 6 + }, + "value": { + "Place": { + "local": 0, + "projection": [] + } + } + } + ] + }, + "id": 0, + "name": "std::rt::lang_start::<()>" + } + }, + "symbol_name": "_ZN3std2rt10lang_start17h" + } + ], + "types": [ + [ + { + "PrimitiveType": "Bool" + } + ], + [ + { + "PrimitiveType": "Str" + } + ], + [ + { + "PrimitiveType": { + "Int": "I32" + } + } + ], + [ + { + "PrimitiveType": { + "Int": "Isize" + } + } + ], + [ + { + "PrimitiveType": { + "Uint": "U32" + } + } + ], + [ + { + "PrimitiveType": { + "Uint": "U8" + } + } + ], + [ + { + "PrimitiveType": { + "Uint": "Usize" + } + } + ], + [ + { + "EnumType": { + "discriminants": [ + 0, + 1 + ], + "fields": "elided", + "layout": { + "abi": { + "Scalar": { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 0 + }, + "value": { + "Int": { + "length": "I64", + "signed": true + } + } + } + } + }, + "abi_align": 8, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 0 + } + ] + } + }, + "size": { + "num_bits": 64 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "name": "std::result::Result" + } + } + ], + [ + { + "StructType": { + "fields": "elided", + "layout": { + "abi": { + "Aggregate": { + "sized": true + } + }, + "abi_align": 8, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 0 + }, + { + "num_bits": 128 + }, + { + "num_bits": 160 + } + ] + } + }, + "size": { + "num_bits": 192 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "name": "std::panic::Location<'_>" + } + } + ], + [ + { + "StructType": { + "fields": "elided", + "layout": { + "abi": { + "Scalar": { + "Initialized": { + "valid_range": { + "end": 255, + "start": 0 + }, + "value": { + "Int": { + "length": "I8", + "signed": false + } + } + } + } + }, + "abi_align": 1, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 0 + } + ] + } + }, + "size": { + "num_bits": 8 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "name": "std::process::ExitCode" + } + } + ], + [ + { + "StructType": { + "fields": "elided", + "layout": { + "abi": { + "Scalar": { + "Initialized": { + "valid_range": { + "end": 255, + "start": 0 + }, + "value": { + "Int": { + "length": "I8", + "signed": false + } + } + } + } + }, + "abi_align": 1, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 0 + } + ] + } + }, + "size": { + "num_bits": 8 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "name": "std::sys::pal::unix::process::process_common::ExitCode" + } + } + ], + [ + { + "TupleType": { + "layout": { + "abi": { + "Aggregate": { + "sized": true + } + }, + "abi_align": 1, + "fields": { + "Arbitrary": { + "offsets": [] + } + }, + "size": { + "num_bits": 0 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "types": "elided" + } + } + ], + [ + { + "PtrType": { + "layout": { + "abi": { + "Scalar": { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 0 + }, + "value": { + "Pointer": 0 + } + } + } + }, + "abi_align": 8, + "fields": "Primitive", + "size": { + "num_bits": 64 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "mutability": "Mut", + "pointee_type": "elided" + } + } + ], + [ + { + "PtrType": { + "layout": { + "abi": { + "Scalar": { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 0 + }, + "value": { + "Pointer": 0 + } + } + } + }, + "abi_align": 8, + "fields": "Primitive", + "size": { + "num_bits": 64 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "mutability": "Not", + "pointee_type": "elided" + } + } + ], + [ + { + "PtrType": { + "layout": { + "abi": { + "Scalar": { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 0 + }, + "value": { + "Pointer": 0 + } + } + } + }, + "abi_align": 8, + "fields": "Primitive", + "size": { + "num_bits": 64 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "mutability": "Not", + "pointee_type": "elided" + } + } + ], + [ + { + "PtrType": { + "layout": { + "abi": { + "Scalar": { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 0 + }, + "value": { + "Pointer": 0 + } + } + } + }, + "abi_align": 8, + "fields": "Primitive", + "size": { + "num_bits": 64 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "mutability": "Not", + "pointee_type": "elided" + } + } + ], + [ + { + "PtrType": { + "layout": { + "abi": { + "Scalar": { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 0 + }, + "value": { + "Pointer": 0 + } + } + } + }, + "abi_align": 8, + "fields": "Primitive", + "size": { + "num_bits": 64 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "mutability": "Not", + "pointee_type": "elided" + } + } + ], + [ + { + "RefType": { + "layout": { + "abi": { + "Scalar": { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + } + }, + "abi_align": 8, + "fields": "Primitive", + "size": { + "num_bits": 64 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "mutability": "Mut", + "pointee_type": "elided" + } + } + ], + [ + { + "RefType": { + "layout": { + "abi": { + "Scalar": { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + } + }, + "abi_align": 8, + "fields": "Primitive", + "size": { + "num_bits": 64 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "mutability": "Not", + "pointee_type": "elided" + } + } + ], + [ + { + "RefType": { + "layout": { + "abi": { + "Scalar": { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + } + }, + "abi_align": 8, + "fields": "Primitive", + "size": { + "num_bits": 64 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "mutability": "Not", + "pointee_type": "elided" + } + } + ], + [ + { + "RefType": { + "layout": { + "abi": { + "Scalar": { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + } + }, + "abi_align": 8, + "fields": "Primitive", + "size": { + "num_bits": 64 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "mutability": "Not", + "pointee_type": "elided" + } + } + ], + [ + { + "RefType": { + "layout": { + "abi": { + "ScalarPair": [ + { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + }, + { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 0 + }, + "value": { + "Int": { + "length": "I64", + "signed": false + } + } + } + } + ] + }, + "abi_align": 8, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 0 + }, + { + "num_bits": 64 + } + ] + } + }, + "size": { + "num_bits": 128 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "mutability": "Not", + "pointee_type": "elided" + } + } + ], + [ + { + "RefType": { + "layout": { + "abi": { + "ScalarPair": [ + { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + }, + { + "Initialized": { + "valid_range": { + "end": 18446744073709551615, + "start": 1 + }, + "value": { + "Pointer": 0 + } + } + } + ] + }, + "abi_align": 8, + "fields": { + "Arbitrary": { + "offsets": [ + { + "num_bits": 0 + }, + { + "num_bits": 64 + } + ] + } + }, + "size": { + "num_bits": 128 + }, + "variants": { + "Single": { + "index": 0 + } + } + }, + "mutability": "Not", + "pointee_type": "elided" + } + } + ], + [ + { + "FunType": "{closure@std::rt::lang_start<()>::{closure#0}}" + } + ] + ] +} diff --git a/tests/integration/trace-report.txt b/tests/integration/trace-report.txt new file mode 100644 index 00000000..9ef46e70 --- /dev/null +++ b/tests/integration/trace-report.txt @@ -0,0 +1,171 @@ +Tracing assert_eq... +Tracing binop... +Tracing char-trivial... +Tracing closure-args... +Tracing closure-no-args... +Tracing const-arithm-simple... +Tracing div... +Tracing double-ref-deref... +Tracing enum... +Tracing fibonacci... +Tracing float... +Tracing fn-ptr-in-arg... +Tracing foreign-type... +Tracing modulo... +Tracing mutual_recursion... +Tracing option-construction... +Tracing param_types... +Tracing primitive-type-bounds... +Tracing recursion-simple-match... +Tracing recursion-simple... +Tracing ref-deref... +Tracing reify-fn-pointer... +Tracing shl_min... +Tracing slice... +Tracing static-vtable-nonbuiltin-deref... +Tracing strange-ref-deref... +Tracing struct... +Tracing sum-to-n... +Tracing tuple-eq... +Tracing tuples-simple... +Tracing unevaluated-const... +Tracing weirdRefs... +Trace coverage across 32 test(s): + + Count Event + ----- ----- + 2530 SpanResolved (all programs) + 1349 TypeCollected (all programs) + 363 FnDefAsValue (all programs) + 361 FunctionCallResolved (all programs) + 345 ItemDiscovered (all programs) + 345 BodyWalkStarted (all programs) + 345 BodyWalkFinished (all programs) + 328 AllocationCollected (all programs) + 67 DropGlueResolved (all programs) + 32 AssemblyStarted (all programs) + 1 ReifyFnPointerResolved (reify-fn-pointer) + +Invariants holding (1): + ok UnevaluatedConstDiscovered + +All coverage events exercised, all invariants holding. + +============================================================ +Sub-category breakdown: +============================================================ + + DropGlueResolved / sym_kind: + 67 no_op (all, stdlib only) + gaps (unreachable): + -- normal (drop glue is always a no-op shim) + -- intrinsic (drop glue is always a no-op shim) + + FunctionCallResolved / sym_kind: + 327 normal (all) + 34 intrinsic (all, stdlib only) + gaps (unreachable): + -- no_op (no-op shims only arise from drop glue, not call terminators) + + ItemDiscovered / source: + 345 mono_collect (all, stdlib only) + gaps (unreachable): + -- unevaluated_const (compiler eagerly evaluates all consts on current nightly) + + ReifyFnPointerResolved / sym_kind: + 1 normal (reify-fn-pointer) + gaps (unreachable): + -- intrinsic (intrinsics cannot be coerced to fn pointers) + -- no_op (no-op shims cannot be coerced to fn pointers) + + TypeCollected / ty_kind: + 321 FnDef (all) + 277 Ref (all) + 212 Adt (all) + 111 RawPtr (all) + 76 Uint (all) + 69 Int (all) + 52 Tuple (all) + 44 Dynamic (all) + 37 FnPtr (all) + 34 Closure (all) + 32 Never (all) + 30 Str (30/32) + 25 Bool (25/32) + 14 Slice (5/32) + 7 Char (7/32) + 5 Array (4/32) + 2 Float (float) + 1 Foreign (foreign-type, stdlib only) + gaps (unreachable): + -- Coroutine (async/generators monomorphize to ADT state machines) + -- CoroutineWitness (async/generators monomorphize to ADT state machines) + -- Pat (unstable feature (pattern_types)) + +Test programs (32/32 annotated): + + assert_eq + covers: assert_eq macro expansion, string formatting machinery + binop + covers: binary operators (arithmetic, bitwise, comparison) + char-trivial + covers: char type, char literals, equality + closure-args + covers: closure with captured arguments, closure call + closure-no-args + covers: zero-argument closure, closure call + const-arithm-simple + covers: function calls, usize comparison, return values + div + covers: integer division + double-ref-deref + covers: double references, double dereference + enum + covers: enum declaration, variant construction + fibonacci + covers: recursion, match expression with wildcard pattern + float + covers: floating-point types (f32, f64), float arithmetic + fn-ptr-in-arg + covers: fn pointer as higher-order argument, Option::map, byte array conversion + foreign-type + covers: Foreign type kind (extern type used behind a pointer) + modulo + covers: modulo operator + mutual_recursion + covers: mutually recursive functions, if/else control flow + option-construction + covers: Option type, Some/None construction, unwrap + param_types + covers: generic structs, monomorphized type parameters, Result type + primitive-type-bounds + covers: unsigned integer boundary values, overflow arithmetic + recursion-simple + covers: recursion via if/else + recursion-simple-match + covers: recursion via match expression + ref-deref + covers: reference creation, dereference + reify-fn-pointer + covers: ReifyFnPointer cast (fn item coerced to fn pointer via type annotation) + unique: ReifyFnPointerResolved + shl_min + covers: left shift of signed integer minimum values (i8 through i128) + slice + covers: array slicing, slice comparison + static-vtable-nonbuiltin-deref + covers: static trait objects, dyn dispatch, vtable allocation + strange-ref-deref + covers: mutable reference reassignment, self-referential reborrow + struct + covers: struct declaration, field access, field arithmetic + sum-to-n + covers: while loop, mutable bindings, function composition + tuple-eq + covers: tuple construction, tuple equality + tuples-simple + covers: tuple construction, tuple field access + unevaluated-const + covers: const evaluation (associated consts in generic contexts, const generics) + weirdRefs + covers: mutable ref chains, struct with ref fields, field projections through derefs From a49b28b8be6e294c2766d8289bd96462749b6063 Mon Sep 17 00:00:00 2001 From: cds-amal Date: Wed, 4 Mar 2026 19:43:26 -0500 Subject: [PATCH 07/13] docs: document first-walked-body-wins semantics in TyCollector The type dedup guard means whichever body is walked first claims the trace event for a given type. Since body walk order is non-deterministic (HashMap iteration), the trace report's "stdlib only" annotation reflects walk order, not whether user code actually references the type. --- src/printer/ty_visitor.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/printer/ty_visitor.rs b/src/printer/ty_visitor.rs index 01060852..7c8a1f22 100644 --- a/src/printer/ty_visitor.rs +++ b/src/printer/ty_visitor.rs @@ -58,6 +58,12 @@ impl Visitor for TyCollector<'_> { type Break = (); fn visit_ty(&mut self, ty: &stable_mir::ty::Ty) -> ControlFlow { + // Each type is collected (and traced) at most once. Because + // `collect_and_analyze_items` pulls from a HashMap, body walk order + // is effectively non-deterministic: whichever body is walked first + // "wins" the trace event for a given type. This means the trace + // report's stdlib-only annotation reflects which body *happened* to + // be walked first, not whether user code references the type. if self.types.contains_key(ty) || self.resolved.contains(ty) { return ControlFlow::Continue(()); } From 0cf8d09b62275ae6eec5bb6e39301df44571914b Mon Sep 17 00:00:00 2001 From: cds-amal Date: Wed, 4 Mar 2026 19:46:26 -0500 Subject: [PATCH 08/13] fix(trace): emit TypeCollected on every encounter, not just the first The dedup guard in TyCollector::visit_ty prevented infinite recursion on self-referential types, but it also suppressed trace events for subsequent bodies that reference the same type. This meant the trace report's "stdlib only" annotation was an artifact of walk order (HashMap iteration is non-deterministic), not a statement about whether user code actually references the type. Now we emit a trace event before the early return, so every body that encounters a type gets credited. The dedup guard still prevents recursion and duplicate map insertions; only the trace is affected. --- src/printer/ty_visitor.rs | 18 ++++++++++------ tests/integration/trace-report.txt | 34 +++++++++++++++--------------- 2 files changed, 29 insertions(+), 23 deletions(-) diff --git a/src/printer/ty_visitor.rs b/src/printer/ty_visitor.rs index 7c8a1f22..26c9cda1 100644 --- a/src/printer/ty_visitor.rs +++ b/src/printer/ty_visitor.rs @@ -58,13 +58,19 @@ impl Visitor for TyCollector<'_> { type Break = (); fn visit_ty(&mut self, ty: &stable_mir::ty::Ty) -> ControlFlow { - // Each type is collected (and traced) at most once. Because - // `collect_and_analyze_items` pulls from a HashMap, body walk order - // is effectively non-deterministic: whichever body is walked first - // "wins" the trace event for a given type. This means the trace - // report's stdlib-only annotation reflects which body *happened* to - // be walked first, not whether user code references the type. if self.types.contains_key(ty) || self.resolved.contains(ty) { + // The type is already collected; skip recursion (which also + // serves as a cycle breaker for self-referential types). We + // still emit a trace event so that *every* body that references + // a type gets credited, not just whichever body happened to be + // walked first. + if let Some(buf) = &mut self.trace_buffer { + buf.push(TraceEvent::TypeCollected { + item: String::new(), + location: None, + ty_kind: ty_kind_tag(&ty.kind()).to_string(), + }); + } return ControlFlow::Continue(()); } diff --git a/tests/integration/trace-report.txt b/tests/integration/trace-report.txt index 9ef46e70..920b7552 100644 --- a/tests/integration/trace-report.txt +++ b/tests/integration/trace-report.txt @@ -34,8 +34,8 @@ Trace coverage across 32 test(s): Count Event ----- ----- + 4964 TypeCollected (all programs) 2530 SpanResolved (all programs) - 1349 TypeCollected (all programs) 363 FnDefAsValue (all programs) 361 FunctionCallResolved (all programs) 345 ItemDiscovered (all programs) @@ -79,24 +79,24 @@ Sub-category breakdown: -- no_op (no-op shims cannot be coerced to fn pointers) TypeCollected / ty_kind: - 321 FnDef (all) - 277 Ref (all) - 212 Adt (all) - 111 RawPtr (all) - 76 Uint (all) - 69 Int (all) - 52 Tuple (all) + 794 Tuple (all) + 784 Ref (all) + 718 Int (all) + 622 Uint (all) + 550 Adt (all) + 368 FnDef (all) + 264 FnPtr (all) + 221 Closure (all) + 189 RawPtr (all) + 176 Never (all) + 139 Bool (25/32) 44 Dynamic (all) - 37 FnPtr (all) - 34 Closure (all) - 32 Never (all) 30 Str (30/32) - 25 Bool (25/32) - 14 Slice (5/32) - 7 Char (7/32) - 5 Array (4/32) - 2 Float (float) - 1 Foreign (foreign-type, stdlib only) + 20 Array (4/32) + 16 Float (float) + 15 Slice (5/32) + 13 Char (7/32) + 1 Foreign (foreign-type) gaps (unreachable): -- Coroutine (async/generators monomorphize to ADT state machines) -- CoroutineWitness (async/generators monomorphize to ADT state machines) From 0348d0cdd7e99b6e7aa9cc97b4c47baa90dc1804 Mon Sep 17 00:00:00 2001 From: cds-amal Date: Wed, 4 Mar 2026 19:57:29 -0500 Subject: [PATCH 09/13] docs: document non-deterministic provenance for nested types The dedup guard in visit_ty skips recursion, so nested types (e.g. the Foreign pointee inside a RawPtr) are only traced from whichever body first visits the outer type. Since body walk order depends on HashMap iteration, the trace report's provenance annotation for nested types may vary between runs. --- src/printer/ty_visitor.rs | 9 +++++++ tests/integration/trace-report.txt | 42 +++++++++++++++--------------- 2 files changed, 30 insertions(+), 21 deletions(-) diff --git a/src/printer/ty_visitor.rs b/src/printer/ty_visitor.rs index 26c9cda1..0f08e754 100644 --- a/src/printer/ty_visitor.rs +++ b/src/printer/ty_visitor.rs @@ -64,6 +64,15 @@ impl Visitor for TyCollector<'_> { // still emit a trace event so that *every* body that references // a type gets credited, not just whichever body happened to be // walked first. + // + // Note: skipping recursion means *nested* types (e.g. the + // Foreign pointee inside a RawPtr) are only traced from the + // first body that visits the outer type. Combined with + // non-deterministic body walk order (HashMap iteration in + // collect_and_analyze_items), this makes provenance attribution + // for nested types non-deterministic. The trace report's + // "stdlib only" / "user code" annotation for such types may + // vary between runs. if let Some(buf) = &mut self.trace_buffer { buf.push(TraceEvent::TypeCollected { item: String::new(), diff --git a/tests/integration/trace-report.txt b/tests/integration/trace-report.txt index 920b7552..4cb64d36 100644 --- a/tests/integration/trace-report.txt +++ b/tests/integration/trace-report.txt @@ -34,7 +34,7 @@ Trace coverage across 32 test(s): Count Event ----- ----- - 4964 TypeCollected (all programs) + 4960 TypeCollected (all programs) 2530 SpanResolved (all programs) 363 FnDefAsValue (all programs) 361 FunctionCallResolved (all programs) @@ -62,7 +62,7 @@ Sub-category breakdown: -- intrinsic (drop glue is always a no-op shim) FunctionCallResolved / sym_kind: - 327 normal (all) + 327 normal (all, user + stdlib) 34 intrinsic (all, stdlib only) gaps (unreachable): -- no_op (no-op shims only arise from drop glue, not call terminators) @@ -73,30 +73,30 @@ Sub-category breakdown: -- unevaluated_const (compiler eagerly evaluates all consts on current nightly) ReifyFnPointerResolved / sym_kind: - 1 normal (reify-fn-pointer) + 1 normal (reify-fn-pointer, user code) gaps (unreachable): -- intrinsic (intrinsics cannot be coerced to fn pointers) -- no_op (no-op shims cannot be coerced to fn pointers) TypeCollected / ty_kind: - 794 Tuple (all) - 784 Ref (all) - 718 Int (all) - 622 Uint (all) - 550 Adt (all) - 368 FnDef (all) - 264 FnPtr (all) - 221 Closure (all) - 189 RawPtr (all) - 176 Never (all) - 139 Bool (25/32) - 44 Dynamic (all) - 30 Str (30/32) - 20 Array (4/32) - 16 Float (float) - 15 Slice (5/32) - 13 Char (7/32) - 1 Foreign (foreign-type) + 794 Tuple (all, user code) + 784 Ref (all, user + stdlib) + 718 Int (all, user + stdlib) + 622 Uint (all, user + stdlib) + 550 Adt (all, user + stdlib) + 368 FnDef (all, user + stdlib) + 264 FnPtr (all, user + stdlib) + 217 Closure (all, user + stdlib) + 189 RawPtr (all, user + stdlib) + 176 Never (all, user + stdlib) + 139 Bool (25/32, user code) + 44 Dynamic (all, user + stdlib) + 30 Str (30/32, user + stdlib) + 20 Array (4/32, user code) + 16 Float (float, user code) + 15 Slice (5/32, user + stdlib) + 13 Char (7/32, user + stdlib) + 1 Foreign (foreign-type, user code) gaps (unreachable): -- Coroutine (async/generators monomorphize to ADT state machines) -- CoroutineWitness (async/generators monomorphize to ADT state machines) From d4350bfceb19722d03ecf15113be2f3c7864e7ff Mon Sep 17 00:00:00 2001 From: cds-amal Date: Wed, 4 Mar 2026 20:24:29 -0500 Subject: [PATCH 10/13] feat(trace): add descendant replay for deterministic type provenance The dedup guard in TyCollector::visit_ty skips recursion on already- collected types (necessary for cycle breaking), which meant nested types were only traced from whichever body first visited the outer type. Since body walk order is non-deterministic (HashMap iteration), this made the trace report's provenance annotations flicker between "user code" and "stdlib only" across runs. Introduce a descendant replay strategy: during a type's first traversal, snapshot the trace buffer before recursion, then record every ty_kind tag appended during recursion as a "descendant" of that outer type. On subsequent dedup hits, replay all descendant tags so every body that references an outer type (e.g. *const Opaque) also gets provenance credit for its nested types (e.g. Foreign). Also refactored the visitor to reduce nesting: extracted a trace_type() helper for the repeated buffer-push pattern, replaced nested if-matches!/match-with-wildcard with early returns, and organized impl blocks with section comments. The descendants map is only populated when TRACE=1, so there is zero overhead in normal operation. --- src/printer/ty_visitor.rs | 287 +++++++++++++++++++++++++++----------- 1 file changed, 203 insertions(+), 84 deletions(-) diff --git a/src/printer/ty_visitor.rs b/src/printer/ty_visitor.rs index 0f08e754..cba91da5 100644 --- a/src/printer/ty_visitor.rs +++ b/src/printer/ty_visitor.rs @@ -7,6 +7,39 @@ //! Note that some special kinds (function definitions/pointers and coroutine //! witnesses) are traversed only to gather the types they reference and are //! not themselves stored as entries in the type map. +//! +//! # Dedup, cycle breaking, and trace provenance +//! +//! Types can be self-referential (e.g. a linked list whose field is +//! `Option>`), so `visit_ty` maintains a dedup guard: once a type +//! appears in `types` or `resolved`, we skip recursion to break cycles. +//! This is correct for the types map (the same type always produces the same +//! `TyKind` and `LayoutShape`), but it creates a provenance problem for +//! tracing. +//! +//! The pipeline walks mono item bodies in HashMap iteration order (see +//! `collect_and_analyze_items`), which is non-deterministic. Without special +//! handling, a nested type like `Foreign` (the pointee inside `*const Opaque`) +//! would only be traced from whichever body *first* visited the outer +//! `RawPtr`; if a stdlib body happens to win, the trace report would label +//! the type "stdlib only" even though user code references it too. +//! +//! To get deterministic provenance the visitor uses a **descendant replay** +//! strategy: +//! +//! 1. **First traversal**: before recursing into a type's children, snapshot +//! the trace buffer length. After recursion, everything appended past that +//! point is a descendant. Stash those `ty_kind` tags in a `descendants` +//! map keyed by the outer type. +//! +//! 2. **Subsequent dedup hits**: instead of just emitting one event for the +//! outer type, replay the full set of descendant tags too. Every body that +//! references `*const Opaque` therefore also gets credited for `Foreign`, +//! regardless of walk order. +//! +//! The `descendants` map is only populated when `TRACE=1`, so there is no +//! overhead in normal operation. The types map and recursion/cycle-breaking +//! logic are completely unaffected. use crate::compat::middle::ty::TyCtxt; use crate::compat::stable_mir; @@ -23,13 +56,31 @@ use super::tracer::{ty_kind_tag, TraceEvent}; pub(super) struct TyCollector<'tcx> { tcx: TyCtxt<'tcx>, + /// The collected types map: `Ty -> (TyKind, Option)`. + /// Serves as the dedup guard for types that get stored (everything + /// except FnDef, FnPtr, and CoroutineWitness). pub types: TyMap, + /// Dedup guard for traversal-only types (FnDef, FnPtr, Closure before + /// its successful insertion). Together with `types`, prevents infinite + /// recursion on self-referential type trees. resolved: HashSet, - /// When tracing is enabled, newly collected types are buffered here. - /// The caller (BodyAnalyzer::visit_ty) drains this buffer after each - /// ty.visit() call and copies events into the main Tracer with the - /// correct item context. This sidesteps the double-&mut problem. + /// When tracing is enabled (`TRACE=1`), newly collected types are + /// buffered here. The caller (`BodyAnalyzer::visit_ty`) drains this + /// buffer after each `ty.visit()` call and stamps each event with + /// the current item context and source location. This sidesteps + /// the double-`&mut` problem (BodyAnalyzer borrows both the tracer + /// and the TyCollector). pub trace_buffer: Option>, + /// Descendant replay map for trace provenance (see module-level docs). + /// + /// During a type's first traversal, we snapshot the trace buffer before + /// recursion and record every `ty_kind` tag appended during recursion as + /// a "descendant" of that type. On subsequent dedup hits we replay these + /// tags so the current body gets provenance credit for nested types it + /// never directly visits (because the dedup guard skips recursion). + /// + /// Only populated when `trace_buffer` is `Some`. + descendants: HashMap>, } impl TyCollector<'_> { @@ -39,10 +90,105 @@ impl TyCollector<'_> { types: HashMap::new(), resolved: HashSet::new(), trace_buffer: if trace { Some(Vec::new()) } else { None }, + descendants: HashMap::new(), } } } +// ── Trace helpers ──────────────────────────────────────────────────────── +// +// These methods implement the snapshot/record/replay protocol described in +// the module-level docs. They are no-ops when tracing is disabled. + +impl TyCollector<'_> { + /// Push a `TypeCollected` trace event into the buffer. + /// No-op when tracing is disabled. + fn trace_type(&mut self, ty_kind: &str) { + if let Some(buf) = &mut self.trace_buffer { + buf.push(TraceEvent::TypeCollected { + item: String::new(), + location: None, + ty_kind: ty_kind.to_string(), + }); + } + } + + /// Capture the current trace buffer length so we can later identify + /// which events were appended during recursion into a type's children. + /// + /// Call this *before* `super_visit` / `visit_instance`. After recursion, + /// pass the returned value to [`record_descendants`] to stash the + /// descendant ty_kind tags. + /// + /// Returns 0 when tracing is disabled (the value is never used in that + /// case, but returning 0 avoids an `Option` at every call site). + #[inline(always)] + fn trace_snapshot(&self) -> usize { + match &self.trace_buffer { + Some(buf) => buf.len(), + None => 0, + } + } + + /// Scan the trace buffer from `snapshot` to the current end, extract + /// every `TypeCollected` ty_kind tag, and stash them in the + /// `descendants` map keyed by `ty`. + /// + /// Must be called *after* recursion completes (i.e. after `super_visit` + /// or `visit_instance`), and only once per type (first traversal). + /// The stashed tags are later replayed by [`replay_with_descendants`] + /// on dedup hits. + fn record_descendants(&mut self, ty: stable_mir::ty::Ty, snapshot: usize) { + let Some(buf) = &self.trace_buffer else { return }; + let descs: Vec = buf[snapshot..] + .iter() + .filter_map(|ev| match ev { + TraceEvent::TypeCollected { ty_kind, .. } => Some(ty_kind.clone()), + _ => None, + }) + .collect(); + if !descs.is_empty() { + self.descendants.insert(ty, descs); + } + } + + /// Emit a `TypeCollected` trace event for `ty` itself, then replay + /// all descendant ty_kind tags recorded during its first traversal. + /// + /// Called on dedup hits (when `types` or `resolved` already contain the + /// type). This is the key to deterministic provenance: without replay, + /// the dedup guard would skip recursion and nested types would only be + /// attributed to whichever body happened to be walked first. + /// + /// Example: `*const Opaque` (RawPtr) contains `Opaque` (Foreign). + /// On first traversal, `record_descendants` stashes `["Foreign"]` for + /// the RawPtr. When a second body later visits `*const Opaque` and hits + /// the dedup guard, we replay the `Foreign` tag so that body also gets + /// credit for the nested type. + fn replay_with_descendants(&mut self, ty: &stable_mir::ty::Ty) { + let Some(buf) = &mut self.trace_buffer else { return }; + + buf.push(TraceEvent::TypeCollected { + item: String::new(), + location: None, + ty_kind: ty_kind_tag(&ty.kind()).to_string(), + }); + + // Clone to avoid borrow conflict: self.descendants is read while + // self.trace_buffer is mutably borrowed above. + let Some(descs) = self.descendants.get(ty).cloned() else { return }; + for ty_kind in descs { + buf.push(TraceEvent::TypeCollected { + item: String::new(), + location: None, + ty_kind, + }); + } + } +} + +// ── Instance visitor ───────────────────────────────────────────────────── + impl TyCollector<'_> { #[inline(always)] fn visit_instance(&mut self, instance: Instance) -> ControlFlow<::Break> { @@ -54,89 +200,72 @@ impl TyCollector<'_> { } } +// ── Visitor impl ───────────────────────────────────────────────────────── + impl Visitor for TyCollector<'_> { type Break = (); fn visit_ty(&mut self, ty: &stable_mir::ty::Ty) -> ControlFlow { + // ── Dedup guard / cycle breaker ────────────────────────────── + // If we've already collected or resolved this type, don't recurse + // (avoids infinite loops on self-referential types like linked + // lists). Instead, replay the full descendant trace so the + // *current* body gets provenance credit for nested types too. if self.types.contains_key(ty) || self.resolved.contains(ty) { - // The type is already collected; skip recursion (which also - // serves as a cycle breaker for self-referential types). We - // still emit a trace event so that *every* body that references - // a type gets credited, not just whichever body happened to be - // walked first. - // - // Note: skipping recursion means *nested* types (e.g. the - // Foreign pointee inside a RawPtr) are only traced from the - // first body that visits the outer type. Combined with - // non-deterministic body walk order (HashMap iteration in - // collect_and_analyze_items), this makes provenance attribution - // for nested types non-deterministic. The trace report's - // "stdlib only" / "user code" annotation for such types may - // vary between runs. - if let Some(buf) = &mut self.trace_buffer { - buf.push(TraceEvent::TypeCollected { - item: String::new(), - location: None, - ty_kind: ty_kind_tag(&ty.kind()).to_string(), - }); - } + self.replay_with_descendants(ty); return ControlFlow::Continue(()); } + // ── First traversal ────────────────────────────────────────── + // Each branch follows the same trace protocol: + // 1. trace_snapshot() -- mark the buffer position + // 2. recurse (super_visit / visit_instance) + // 3. record_descendants() -- stash child ty_kinds for replay + // 4. trace_type() -- push own TypeCollected event + // 5. insert into types / resolved match ty.kind() { TyKind::RigidTy(RigidTy::Closure(def, ref args)) => { self.resolved.insert(*ty); + let snap = self.trace_snapshot(); let instance = Instance::resolve_closure(def, args, stable_mir::ty::ClosureKind::Fn).unwrap(); let control = self.visit_instance(instance); - // Mirror other branches: record closure Ty only when traversal succeeds. - if matches!(control, ControlFlow::Continue(_)) { - let kind = ty.kind(); - let maybe_layout_shape = ty.layout().ok().map(|layout| layout.shape()); - if let Some(buf) = &mut self.trace_buffer { - buf.push(TraceEvent::TypeCollected { - item: String::new(), - location: None, - ty_kind: ty_kind_tag(&kind).to_string(), - }); - } - self.types.insert(*ty, (kind, maybe_layout_shape)); + if !matches!(control, ControlFlow::Continue(_)) { + return control; } + let kind = ty.kind(); + let maybe_layout_shape = ty.layout().ok().map(|layout| layout.shape()); + self.record_descendants(*ty, snap); + self.trace_type(&ty_kind_tag(&kind)); + self.types.insert(*ty, (kind, maybe_layout_shape)); control } - // Break on CoroutineWitnesses, because they aren't expected when getting the layout TyKind::RigidTy(RigidTy::CoroutineWitness(..)) => { debug_log_println!("DEBUG: TyCollector skipping CoroutineWitness: {:?}", ty); ControlFlow::Break(()) } TyKind::RigidTy(RigidTy::FnDef(def, ref args)) => { self.resolved.insert(*ty); - if let Some(buf) = &mut self.trace_buffer { - buf.push(TraceEvent::TypeCollected { - item: String::new(), - location: None, - ty_kind: "FnDef".to_string(), - }); - } + let snap = self.trace_snapshot(); + self.trace_type("FnDef"); let instance = Instance::resolve(def, args).unwrap(); - self.visit_instance(instance) + let control = self.visit_instance(instance); + self.record_descendants(*ty, snap); + control } TyKind::RigidTy(RigidTy::FnPtr(binder_stable)) => { self.resolved.insert(*ty); - if let Some(buf) = &mut self.trace_buffer { - buf.push(TraceEvent::TypeCollected { - item: String::new(), - location: None, - ty_kind: "FnPtr".to_string(), - }); - } + let snap = self.trace_snapshot(); + self.trace_type("FnPtr"); let fn_abi = crate::compat::types::fn_ptr_abi(self.tcx, binder_stable); let mut inputs_outputs: Vec = fn_abi.args.iter().map(|arg_abi| arg_abi.ty).collect(); inputs_outputs.push(fn_abi.ret.ty); - inputs_outputs.super_visit(self) + let control = inputs_outputs.super_visit(self); + self.record_descendants(*ty, snap); + control } - // The visitor won't collect field types for ADTs, therefore doing it explicitly + // The visitor won't collect field types for ADTs, therefore doing it explicitly. TyKind::RigidTy(RigidTy::Adt(adt_def, args)) => { let fields = adt_def .variants() @@ -145,41 +274,31 @@ impl Visitor for TyCollector<'_> { .map(|f| f.ty_with_args(&args)) .collect::>(); + let snap = self.trace_snapshot(); let control = ty.super_visit(self); - if matches!(control, ControlFlow::Continue(_)) { - let kind = ty.kind(); - let maybe_layout_shape = ty.layout().ok().map(|layout| layout.shape()); - if let Some(buf) = &mut self.trace_buffer { - buf.push(TraceEvent::TypeCollected { - item: String::new(), // filled by caller - location: None, // filled by caller - ty_kind: ty_kind_tag(&kind).to_string(), - }); - } - self.types.insert(*ty, (kind, maybe_layout_shape)); - fields.super_visit(self) - } else { - control + if !matches!(control, ControlFlow::Continue(_)) { + return control; } + let kind = ty.kind(); + let maybe_layout_shape = ty.layout().ok().map(|layout| layout.shape()); + self.trace_type(&ty_kind_tag(&kind)); + self.types.insert(*ty, (kind, maybe_layout_shape)); + let control = fields.super_visit(self); + self.record_descendants(*ty, snap); + control } _ => { + let snap = self.trace_snapshot(); let control = ty.super_visit(self); - match control { - ControlFlow::Continue(_) => { - let kind = ty.kind(); - let maybe_layout_shape = ty.layout().ok().map(|layout| layout.shape()); - if let Some(buf) = &mut self.trace_buffer { - buf.push(TraceEvent::TypeCollected { - item: String::new(), // filled by caller - location: None, // filled by caller - ty_kind: ty_kind_tag(&kind).to_string(), - }); - } - self.types.insert(*ty, (kind, maybe_layout_shape)); - control - } - _ => control, + if !matches!(control, ControlFlow::Continue(_)) { + return control; } + let kind = ty.kind(); + let maybe_layout_shape = ty.layout().ok().map(|layout| layout.shape()); + self.trace_type(&ty_kind_tag(&kind)); + self.types.insert(*ty, (kind, maybe_layout_shape)); + self.record_descendants(*ty, snap); + control } } } From e495f4fa5ec9a0d0d53f59767b2e652c816bb9b1 Mon Sep 17 00:00:00 2001 From: cds-amal Date: Wed, 4 Mar 2026 20:24:53 -0500 Subject: [PATCH 11/13] feat(trace-report): add explicit provenance labels to sub-categories The sub-category breakdown now labels every value with one of three provenance annotations: "user code" (all occurrences from user bodies), "user + stdlib" (both), or "stdlib only" (never seen in user code). Previously only "stdlib only" was annotated; the absence of a label was ambiguous. --- tests/integration/trace-report.py | 6 ++++- tests/integration/trace-report.txt | 38 +++++++++++++++--------------- 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/tests/integration/trace-report.py b/tests/integration/trace-report.py index f0519167..7592fac4 100644 --- a/tests/integration/trace-report.py +++ b/tests/integration/trace-report.py @@ -175,10 +175,14 @@ detail = ", ".join(sorted(progs)) else: detail = f"{np}/{n}" - # Annotate if this value only appears via stdlib bodies. + # Annotate provenance: user code, stdlib, or both. user_progs = sub_user_programs.get(ev, {}).get(key, {}).get(val, set()) if not user_progs: detail += ", stdlib only" + elif len(user_progs) < np: + detail += ", user + stdlib" + else: + detail += ", user code" print(f" {count:6} {val} ({detail})") if universe: diff --git a/tests/integration/trace-report.txt b/tests/integration/trace-report.txt index 4cb64d36..6ce1a829 100644 --- a/tests/integration/trace-report.txt +++ b/tests/integration/trace-report.txt @@ -34,7 +34,7 @@ Trace coverage across 32 test(s): Count Event ----- ----- - 4960 TypeCollected (all programs) + 17118 TypeCollected (all programs) 2530 SpanResolved (all programs) 363 FnDefAsValue (all programs) 361 FunctionCallResolved (all programs) @@ -79,24 +79,24 @@ Sub-category breakdown: -- no_op (no-op shims cannot be coerced to fn pointers) TypeCollected / ty_kind: - 794 Tuple (all, user code) - 784 Ref (all, user + stdlib) - 718 Int (all, user + stdlib) - 622 Uint (all, user + stdlib) - 550 Adt (all, user + stdlib) - 368 FnDef (all, user + stdlib) - 264 FnPtr (all, user + stdlib) - 217 Closure (all, user + stdlib) - 189 RawPtr (all, user + stdlib) - 176 Never (all, user + stdlib) - 139 Bool (25/32, user code) - 44 Dynamic (all, user + stdlib) - 30 Str (30/32, user + stdlib) - 20 Array (4/32, user code) - 16 Float (float, user code) - 15 Slice (5/32, user + stdlib) - 13 Char (7/32, user + stdlib) - 1 Foreign (foreign-type, user code) + 3729 Uint (all, user + stdlib) + 2798 Tuple (all, user code) + 2429 Adt (all, user + stdlib) + 2314 Int (all, user + stdlib) + 2135 Ref (all, user + stdlib) + 572 Closure (all, user + stdlib) + 527 FnPtr (all, user + stdlib) + 500 Never (all, user + stdlib) + 415 FnDef (all, user + stdlib) + 375 RawPtr (all, user + stdlib) + 330 Bool (25/32, user code) + 244 Str (30/32, user code) + 236 Char (7/32, user + stdlib) + 207 Dynamic (all, user + stdlib) + 188 Slice (5/32, user code) + 85 Array (4/32, user code) + 30 Float (float, user code) + 4 Foreign (foreign-type, user code) gaps (unreachable): -- Coroutine (async/generators monomorphize to ADT state machines) -- CoroutineWitness (async/generators monomorphize to ADT state machines) From b277e071494d617d3fb8b752cd2e20546974114c Mon Sep 17 00:00:00 2001 From: cds-amal Date: Wed, 4 Mar 2026 20:25:05 -0500 Subject: [PATCH 12/13] feat(tests): add make trace-idempotency target Runs the trace report twice and diffs the structural output (ty_kind names, provenance labels, program lists, gap classifications, per-test annotations) to verify that provenance attribution is stable across non-deterministic body walk order. Raw event counts are stripped before comparison since descendant replays compound differently depending on HashMap iteration order. --- Makefile | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/Makefile b/Makefile index be0301cf..ccde5ca4 100644 --- a/Makefile +++ b/Makefile @@ -48,6 +48,31 @@ trace-report: SMIR ?= cargo run -- "-Zno-codegen" trace-report: bash tests/integration/trace-report.sh $(TESTDIR) $(SMIR) | tee tests/integration/trace-report.txt +# Run the trace report twice and verify that provenance attribution is +# stable across non-deterministic body walk order (HashMap iteration). +# Raw event counts vary between runs (descendant replays compound +# differently), so we strip leading counts and compare only the +# structural output: ty_kind names, provenance labels, program lists, +# gap classifications, and per-test annotations. +.PHONY: trace-idempotency +trace-idempotency: SMIR ?= cargo run -- "-Zno-codegen" +trace-idempotency: + @tmpdir_a=$$(mktemp -d) && tmpdir_b=$$(mktemp -d) && \ + trap 'rm -rf "$$tmpdir_a" "$$tmpdir_b"' EXIT && \ + echo "Run 1..." && \ + bash tests/integration/trace-report.sh $(TESTDIR) $(SMIR) \ + | sed 's/^ *[0-9]* //' > "$$tmpdir_a/report.txt" && \ + echo "Run 2..." && \ + bash tests/integration/trace-report.sh $(TESTDIR) $(SMIR) \ + | sed 's/^ *[0-9]* //' > "$$tmpdir_b/report.txt" && \ + if diff -u "$$tmpdir_a/report.txt" "$$tmpdir_b/report.txt" > /dev/null 2>&1; then \ + echo "Trace provenance is stable across runs."; \ + else \ + echo "Trace provenance DIVERGED between runs:"; \ + diff -u "$$tmpdir_a/report.txt" "$$tmpdir_b/report.txt" || true; \ + exit 1; \ + fi + format: cargo fmt bash -O globstar -c 'nixfmt **/*.nix' From 21584f94df4bddec4c4dec21a56dccfe10735095 Mon Sep 17 00:00:00 2001 From: cds-amal Date: Wed, 4 Mar 2026 23:14:42 -0500 Subject: [PATCH 13/13] cargo clippy --- src/printer/collect.rs | 5 ++++- src/printer/ty_visitor.rs | 18 ++++++++++++------ 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/printer/collect.rs b/src/printer/collect.rs index 22bc69f1..09b36647 100644 --- a/src/printer/collect.rs +++ b/src/printer/collect.rs @@ -63,7 +63,10 @@ fn warn_missing_body(mono_item: &MonoItem) { } } -fn collect_items(tcx: TyCtxt<'_>, tracer: &mut Option) -> HashMap { +fn collect_items( + tcx: TyCtxt<'_>, + tracer: &mut Option, +) -> HashMap { // get initial set of mono_items let items = mono_collect(tcx); items diff --git a/src/printer/ty_visitor.rs b/src/printer/ty_visitor.rs index cba91da5..a73e9970 100644 --- a/src/printer/ty_visitor.rs +++ b/src/printer/ty_visitor.rs @@ -139,7 +139,9 @@ impl TyCollector<'_> { /// The stashed tags are later replayed by [`replay_with_descendants`] /// on dedup hits. fn record_descendants(&mut self, ty: stable_mir::ty::Ty, snapshot: usize) { - let Some(buf) = &self.trace_buffer else { return }; + let Some(buf) = &self.trace_buffer else { + return; + }; let descs: Vec = buf[snapshot..] .iter() .filter_map(|ev| match ev { @@ -166,7 +168,9 @@ impl TyCollector<'_> { /// the dedup guard, we replay the `Foreign` tag so that body also gets /// credit for the nested type. fn replay_with_descendants(&mut self, ty: &stable_mir::ty::Ty) { - let Some(buf) = &mut self.trace_buffer else { return }; + let Some(buf) = &mut self.trace_buffer else { + return; + }; buf.push(TraceEvent::TypeCollected { item: String::new(), @@ -176,7 +180,9 @@ impl TyCollector<'_> { // Clone to avoid borrow conflict: self.descendants is read while // self.trace_buffer is mutably borrowed above. - let Some(descs) = self.descendants.get(ty).cloned() else { return }; + let Some(descs) = self.descendants.get(ty).cloned() else { + return; + }; for ty_kind in descs { buf.push(TraceEvent::TypeCollected { item: String::new(), @@ -236,7 +242,7 @@ impl Visitor for TyCollector<'_> { let kind = ty.kind(); let maybe_layout_shape = ty.layout().ok().map(|layout| layout.shape()); self.record_descendants(*ty, snap); - self.trace_type(&ty_kind_tag(&kind)); + self.trace_type(ty_kind_tag(&kind)); self.types.insert(*ty, (kind, maybe_layout_shape)); control } @@ -281,7 +287,7 @@ impl Visitor for TyCollector<'_> { } let kind = ty.kind(); let maybe_layout_shape = ty.layout().ok().map(|layout| layout.shape()); - self.trace_type(&ty_kind_tag(&kind)); + self.trace_type(ty_kind_tag(&kind)); self.types.insert(*ty, (kind, maybe_layout_shape)); let control = fields.super_visit(self); self.record_descendants(*ty, snap); @@ -295,7 +301,7 @@ impl Visitor for TyCollector<'_> { } let kind = ty.kind(); let maybe_layout_shape = ty.layout().ok().map(|layout| layout.shape()); - self.trace_type(&ty_kind_tag(&kind)); + self.trace_type(ty_kind_tag(&kind)); self.types.insert(*ty, (kind, maybe_layout_shape)); self.record_descendants(*ty, snap); control