Rust type mapping

The target maps exact source evidence and sealed ownership facts, not TypeScript display names.

Source contractRust representation
boolean / boolbool
int8uint128matching Rust fixed-width integer
nativeInt, nativeUintisize, usize
float32, float64f32, f64
stringString or &str only when complete use analysis proves the ABI
`Tundefined` / selected nullable
mutable dense T[]Vec<T> or selected JS array carrier
readonly array parameterborrowed slice when the closed ABI proves it
homogeneous fixed tuple / FixedArray<T, N>[T; N] when exact length and element carrier are proven
heterogeneous tupleRust tuple
Ref<T, L>, Mut<T, L>&'l T, &'l mut T
Pointer<T>tsonic_rust_runtime::Location<T>
NativePointer<T>, constPtr<T>, mutPtr<T>native raw pointer with exact mutability
closed structural objectgenerated Rust record/enum/trait representation selected by layout policy
producer-owned broad valuefinite tsonic_rust_js::JsValue carrier for proved operations

Provider-backed values retain exact crate, module, item, generic, lifetime, const, associated-type, ABI, safety, fallibility, and foundation identities. No source type is silently boxed merely to make an unsupported operation compile.

Fixed arrays

The fixed-array carrier retains the exact extent as an integer constant in [T; N], including bigint source extents, without converting it through a JavaScript number. Native usize representability and allocation limits remain native constraints; exact emitted constants do not certify those constraints.

Source .length is a separate operation. Number-based extents through 2147483647 use the existing checked int32 result. Larger numeric .length reads reject with RUST_FIXED_ARRAY_LENGTH_RANGE_UNSUPPORTED; bigint-based reads, even for 2n, reject with RUST_FIXED_ARRAY_LENGTH_RUNTIME_BASE_UNSUPPORTED. A bigint metadata count does not authorize a numeric source result. Literal index/cardinality checks and rest bounds use exact counts; dynamic indexing retains its checked int32 index, and iteration retains native bounds. This is not blanket support for every fixed-array operation.

The shared layout contract supports array metadata observations without materializing [T; N], including huge zero-sized arrays. A native array carrier does not supply a physical layout codec: raw conversion or demanded backing requiring an inline array, directly or through record children, rejects with an explicit unsupported-array reason. Existing scalar/record codecs and ordinary dynamic-array element backing do not constitute such an adapter.

Broad values

An any or unknown annotation does not select a general Rust carrier:

export function keep(value: unknown): unknown {
  return value;
}

This is rejected when the parameter must cross the Rust ABI without a concrete carrier. Narrowing it first is ordinary TypeScript and produces a concrete target type:

export function text(value: unknown): string {
  return typeof value === "string" ? value : "not text";
}

An approved producer can select a finite broad carrier. Under the JavaScript surface, for example, JSON.parse produces JsValue; a matching JSON or JS operation may consume that value. This is exact producer evidence, not a spelling-based conversion from arbitrary any.

See TypeScript types and utilities for the pinned utility inventory and the target-neutral any and unknown rules.