Skip to main content

MirFunction

Struct MirFunction 

Source
pub struct MirFunction {
    pub name: String,
    pub blocks: Vec<BasicBlock>,
    pub num_locals: u16,
    pub param_slots: Vec<SlotId>,
    pub param_reference_kinds: Vec<Option<BorrowKind>>,
    pub local_types: Vec<LocalTypeInfo>,
    pub span: Span,
    pub field_name_table: HashMap<FieldIdx, String>,
    pub local_struct_type_names: HashMap<SlotId, String>,
    pub local_typed_array_element_types: HashMap<SlotId, ConcreteType>,
    pub local_declared_scalar_types: HashMap<SlotId, ConcreteType>,
}
Expand description

The MIR representation of a single function.

Fields§

§name: String§blocks: Vec<BasicBlock>

The basic blocks forming the CFG.

§num_locals: u16

Number of local variable slots.

§param_slots: Vec<SlotId>

Which locals are function parameters.

§param_reference_kinds: Vec<Option<BorrowKind>>

Per-parameter reference kind, aligned with param_slots.

§local_types: Vec<LocalTypeInfo>

Type information for locals (for Copy/Clone inference).

§span: Span

Source span of the function.

§field_name_table: HashMap<FieldIdx, String>

Mapping from FieldIdx to field name, for JIT field access resolution.

§local_struct_type_names: HashMap<SlotId, String>

Per-slot user-struct type name for slots produced by Expr::StructLiteral { name, .. } lowering.

ADR-006 §2.7.5 producing-site classification — Phase 3 cluster-0 Round 13 T1’ gap 1 closure. The bytecode compiler’s concrete_type_from_annotation (crates/shape-vm/src/compiler/v2_map_emission.rs:357) does NOT resolve user-struct names to a per-struct StructLayoutId (the _ => None arm at line 378), and the conduit producer at compiler/helpers.rs:508 stamps Struct(StructLayoutId(0)) for every ObjectStore regardless of struct identity. Neither path makes user-struct type name observable at conduit-time.

This map is populated at MIR lowering for Expr::StructLiteral { name, .. } sites (the canonical user-struct construction shape — let t = X {}, let p = Point { x: 1, y: 2 }). The conduit producer reads the map at Call-terminator destination-stamp time for MirConstant::Method(_) terminators to look up the trait method declared return ConcreteType via the find_default_trait_impl_for_type_method chain.

None (no entry) for slots that aren’t user-struct constructions — primitives, collections, plain object literals, function returns, etc. The downstream classifier surfaces unstamped per §2.7.7 #9 / forbidden #9 (no fabricated default).

§local_typed_array_element_types: HashMap<SlotId, ConcreteType>

Per-slot empty-typed-array element ConcreteType for slots produced by let mut <name>: Array<C> = [] lowering (where C is a concrete_type_from_annotation-resolvable element type).

ADR-006 §2.7.5 stamp-at-compile-time — V3-S6e-jit-specialized-vec- map-aggregate-classify (Phase 3 cluster-0+1 Wave 3 Stabilize Round 2, 2026-05-16; V3-S6 multi-session chain checkpoint-final).

Closes the W11-jit-new-array gap inside monomorphized Vec.map<U> / Vec.filter<U> specialization bodies. V3-S6a’s synthesize_empty_array_result_annotation writes Array<C> onto the let mut result = [] var-decl AST node for the specialized function; this map captures that annotation at MIR lowering so the conduit producer at crates/shape-vm/src/compiler/helpers.rs::infer_top_level_concrete_ types_from_mir_with_resolvers can stamp concrete_types[result_slot] = Array(elem).

Why MIR-level rather than just bytecode-side: the empty array literal at MIR lowering goes through lower_array_expr → emit_container_store_if_needed which short-circuits for ContainerStoreKind::Array with empty operands (helpers.rs:128-130). No StatementKind::ArrayStore is emitted, so the helpers.rs:687 ArrayStore walker never fires on empty literals. The conduit producer has no other source for the element kind on an empty Aggregate slot.

Producer: mir/lowering/stmt.rs::lower_var_decl (var-decl with annotation Array<C> AND value Expr::Array(items) with items.is_empty()). Consumer: compiler/helpers.rs::infer_top_level_concrete_types_from_ mir_with_resolvers (new pass before slot-move propagation).

None (no entry) for slots that aren’t empty-typed-array-literal initializations — non-empty array literals flow through the existing ArrayStore operand-kind inference path; absent annotation means no proven element kind and the JIT surfaces-and-stops per §2.7.7 #9 forbidden Bool-default.

§local_declared_scalar_types: HashMap<SlotId, ConcreteType>

Per-slot declared scalar ConcreteType for let-bindings whose type annotation resolves to a narrow integer width (i8/i16/ i32/u8/u16/u32).

ADR-006 §2.7.5 stamp-at-compile-time — R5c-2-β-γ (c) jit-narrow-wrap. The MIR Rvalue::Use(Constant(Int(_))) carrier is width-blind: a bare integer literal has no width, so infer_top_level_concrete_types_from_mir classifies every MirConstant::Int as ConcreteType::I64. Top-level let a: i32 = 100 bindings are module bindings (not bytecode locals — see compiler/compiler_impl_reference_model.rs:1472), so the bytecode-compiler’s per-local side-tables never carry the declared narrow width either. Without a width source the JIT declares the slot as a Cranelift I64 variable and emits iadd/isub/imul at 64-bit width — overflow does not wrap to the declared width, diverging from the bytecode VM’s AddI32/AddTyped truncating opcodes.

This map is populated at MIR lowering for var-decls whose type_annotation resolves through concrete_type_from_annotation to one of the narrow integer scalar ConcreteType variants. The conduit producer (compiler/helpers.rs::infer_top_level_concrete_types_from_mir_ with_resolvers) reads it to stamp concrete_types[slot] with the proven narrow width, which the JIT then projects to NativeKind::Int32/Int8/etc., declares the slot at the matching Cranelift width, and lowers arithmetic so overflow wraps.

None (no entry) for slots without a narrow-int annotation — plain int/number/heap types are unaffected.

Producer: mir/lowering/stmt.rs::lower_var_decl. Consumer: compiler/helpers.rs::infer_top_level_concrete_types_ from_mir_with_resolvers.

Implementations§

Source§

impl MirFunction

Source

pub fn entry_block(&self) -> BasicBlockId

Get the entry block (always block 0).

Source

pub fn iter_blocks(&self) -> impl Iterator<Item = &BasicBlock>

Iterate over all blocks.

Source

pub fn block(&self, id: BasicBlockId) -> &BasicBlock

Get a block by ID.

Source

pub fn all_points(&self) -> Vec<(Point, BasicBlockId, usize)>

Linearize all statements into a flat list of points. Returns (point, block_id, statement_index) triples.

Trait Implementations§

Source§

impl Clone for MirFunction

Source§

fn clone(&self) -> MirFunction

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for MirFunction

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

impl<T> Allocation for T
where T: RefUnwindSafe + Send + Sync,