Arrays, ranges and progressions

← Guest standard library support

This is an executable API inventory for the current checkout. Status and evidence policy applies to every entry. Signatures are indexed in the generated Guest API reference.

Arrays

UTF-16 CharArray materialization

Status: Supported.

CharArray(size), indexed access, mutation, size, concatToString(start, end), and String(array, start, length) preserve exact UTF-16 code units through Guest execution.

Evidence: MinimalScriptLoweringTest, test primitive char array lowers deterministically for exact utf16 materialization, and kotlin_writer.rs, test k2_char_array_program_executes_exact_utf16_materialization.

Bulk array copying

Status: Supported.

All twelve primitive array families and admitted generic Array<T> support public copyOf(), copyOf(newSize), and copyInto(destination, destinationOffset = 0, startIndex = 0, endIndex = size). Copies preserve element values/reference identity, overlap, empty ranges, truncation, and zero/null padding. Resized generic-array copies return Array<T?>; copyInto admits assignable elements through an Array<out T> source. Dense primitive Array<T> copies retain scalar storage when the element type stays non-null; copies into nullable or Any storage box each scalar in a metered index loop. The full range is validated before any destination writes, including empty ranges. Receivers and explicit arguments evaluate once. Native copying is bounded by the Guest budget without temporary buffers; ArrayList growth uses these APIs. Negative sizes and invalid ranges throw typed catchable exceptions through the shared operation-error mechanism.

Evidence: testKotlinIntArrayVmConformance, bulk_array_copy_preserves_overlap_in_both_directions_across_tiny_budgets, and bulk_array_instruction_resumes_with_exact_dynamic_cost_and_one_retirement.

Related work: #679

Reference Array<T> operations

Status: Partial.

Entry Array<String>, emptyArray<T>(), direct arrayOf calls, size, indexed get/set, and direct for loops work for String, supported Guest class references, value classes, and Any, including nullable forms and nominal primitive boxes, with concrete uses inside specialized generic functions. Array<Any> boxes supported scalars when constructed or written, preserves object identity, and returns the stored reference on reads. Direct iteration snapshots the array reference once, observes subsequent element writes, and uses the indexed language lowering without a stored iterator. arrayOfNulls<T>(size) creates null-filled arrays for supported reference elements and nullable primitive boxes, including generic specializations; negative sizes throw catchable NegativeArraySizeException.

Evidence: testKotlinMutableListVmConformance. copyOfRange is available only for Array<String>. Non-null primitive elements use dense specialized storage, described below. Spread arguments, stored iterators, nested-array element storage, and higher-order operations remain unavailable.

Evidence: MinimalScriptLoweringTest, tests string arrays can be constructed read and written and string arrays support copyOfRange and supported default arguments, plus nullable Int and collection elements preserve values and nulls (testKotlinNullableCollectionsVmConformance), reference arrays preserve Guest class elements and aliases and guest arrays reject stored iterators spread and nested storage, paired with testKotlinReferenceArrayVmConformance and gc_tests.rs, test collector_scans_reference_arrays.

Evidence: reference array loops preserve specialized elements source identity and cleanup for vm execution in MinimalScriptLoweringTest, executed by testKotlinReferenceArrayVmConformance at budgets 64 and 512.

Related work: #656 Imported non-generic nominal classes also work as reference-array elements, including nullable storage backing typed device lists.

Evidence: text display program lowers deterministically for GameTest, executed by the real text-display scenario in :v26_1-neoforge:runGameTestServer with TextDisplay.all() and typed filtering.

Reference-array initializer constructors

Status: Supported.

Array(size) { index -> value } and Array(size, initializer) create arrays of admitted elements: all twelve non-null primitive families, String, Any, source/imported class references, value classes (including Vector3f), nullable elements and nullable primitive boxes. Generic container elements such as Array<Cell<T>> work after concrete specialization. A bare Array<T> constructor in a non-reified generic function is rejected by K2; reified inline functions remain unsupported. The initializer may be a capturing lambda, a stored function or a supported callable reference.

Size and initializer expressions evaluate once, left-to-right, before allocation. The callback receives each ascending index exactly once; zero size calls it zero times. A negative size raises managed NegativeArraySizeException without invoking the callback body, while preserving initializer-expression side effects. An exception from a callback propagates immediately and preserves completed side effects. Value-class results use the same nominal managed boxes as arrayOf; generated loops and allocation use existing metered VM instructions and ordinary GC roots. Non-null primitives use dense scalar storage, without element boxes. General array covariance remains outside the admitted subset.

Evidence: reference arrays preserve Guest class elements and aliases in MinimalScriptLoweringTest, executed by testKotlinReferenceArrayVmConformance under small execution budgets and allocation pressure. The primitive generic arrays specialize dense storage and reference boundary copies for vm execution case covers all twelve primitive constructor results; guest arrays reject stored iterators spread and nested storage protects the remaining unsupported forms. IDE test array initializer constructors resolve with source and metadata inputs checks both source-attached and metadata-only sessions.

Related work: #730

Dense primitive Array<T> specialization

Status: Supported.

Array<Boolean>, Array<Byte>, Array<Short>, Array<Char>, Array<Int>, Array<Long>, Array<Float>, Array<Double>, Array<UByte>, Array<UShort>, Array<UInt> and Array<ULong> store non-null elements as packed scalars. Byte/short families use one/two bytes per element; the other families reuse their primitive array widths. arrayOf, emptyArray, initializer constructors, indexed get/set, size, direct for loops, copyOf and copyInto work through concrete generic function/class specialization.

Each remains a distinct nominal generic-array type, rather than an alias of IntArray or another primitive array. Passing the array through Any preserves its identity and layout; extracting a scalar into Any uses its nominal primitive box. Nullable primitive arrays and Array<Any> retain reference storage. copyOf(newSize) returns nullable elements, boxes copied values and pads with null, even when shrinking. No-argument copyOf() and copies between matching non-null specializations preserve dense storage. Narrow signed/unsigned values, full unsigned magnitude and floating IEEE values retain their scalar contracts.

Evidence: primitive generic arrays specialize dense storage and reference boundary copies for vm execution in MinimalScriptLoweringTest checks deterministic nominal scalar/storage layouts and emits the mandatory .packed.cpkt sidecar for testKotlinReferenceArrayVmConformance. It executes all twelve families, generic functions/classes, copying into nullable/Any arrays, bounds/size errors, identity, casts, floating edges, initializer exceptions and GC pressure with a 256 KiB heap at execution budgets 64 and 512. IDE test primitive generic arrays resolve constructors copies and loops with source and metadata inputs checks both platform input modes.

Related work: #743

All twelve primitive array families

Status: Supported.

BooleanArray, ByteArray, ShortArray, CharArray, IntArray, LongArray, FloatArray, DoubleArray, UByteArray, UShortArray, UIntArray, and ULongArray support size constructors, (Int) -> T initializers, their *ArrayOf factories, size, indexed reads and writes, direct for loops, copyOf, and overlapping copyInto, including its receiver-size default. Initializers receive ascending indexes exactly once, and are never invoked for a negative size. New slots use the primitive zero value. Byte and short families use compact one- and two-byte storage; unsigned families preserve their nominal identity and full magnitude. Bounds and negative sizes raise managed exceptions. Stored iterators, indices, and spread factory arguments remain outside the admitted subset.

Evidence: all primitive operators preserve narrow signed unsigned and nominal semantics in GuestInlineIntegrationTest, executed by testKotlinPrimitivesVmConformance; specialized IntArray lowers deterministically for vm conformance exercises copies and exceptions for every family via testKotlinIntArrayVmConformance; platform bundle test receiver array size defaults round trip and reject incompatible declarations.

DoubleArray

Status: Supported.

Unboxed F64 storage supports DoubleArray(size), doubleArrayOf, zero initialization, size, indexed reads/writes, direct for loops with break/continue, copyOf (including resize with zero padding) and overlapping copyInto. Factory arguments and loop sources evaluate once. Bounds and negative sizes raise managed exceptions. Arrays retain identity equality; generated data-class hashing uses element hashes. No boxed Double allocation is needed for element storage or direct iteration.

Evidence: DoubleArray storage copying iteration and failures lower for vm conformance and testKotlinDoubleArrayVmConformance, plus the Guest Double IDE diagnostic test.

Related work: #688

Additional focused IntArray evidence: specialized IntArray lowers to unboxed primitive array instructions and unsupported IntArray forms publish no artifact in MinimalScriptLoweringTest cover instruction selection and rejection of the excluded array shapes. MFVC reference-array storage executes in testKotlinMfvcVmConformance.

Ranges and progressions

Primitive ranges and progressions

Status: Supported.

Signed integral range operators widen to IntRange or LongRange; unsigned operators widen to UIntRange or ULongRange. CharRange retains UTF-16 values. .., ..<, until, downTo, positive step, membership, stored progressions, chained steps, and iterators execute as ordinary Guest library code. ClosedRange and OpenEndRange views retain their bounds and membership; requesting an exclusive upper bound for a range ending at the primitive maximum raises IllegalStateException. Aligned progression endpoints avoid overflow across the entire signed/unsigned range, and iterators stop before incrementing past the final element. Empty progressions stay empty; an exhausted iterator throws NoSuchElementException. Float/Double closed and open-end ranges support IEEE membership and empty checks, including NaN and signed zero; Boolean closed and open-end ranges use its comparable ordering. These ranges do not define iteration. Direct Int loops retain the allocation-free language lowering.

Evidence: primitive ranges preserve bounds steps termination and floating membership, allocation free Int loops lower deterministically for vm execution, and testKotlinIntLoopsVmConformance.