Functions, generics and callbacks
This page describes the current checkout, including unreleased work. Status and evidence policy applies to every entry.
Top-level and member calls
Status: Partial.
Direct top-level calls, immutable property getters, and supported member operations lower by exact symbol. Only admitted declarations and signatures are executable. Supported virtual/interface dispatch follows the object-model contract.
Evidence:
MinimalScriptLoweringTest,
tests multi-file terminal program lowers through trusted symbols and same-named guest function remains an
ordinary project call, plus same-named guest calls preserve their resolved targets for vm conformance
paired with testKotlinNamedCallsVmConformance.
Related work: not scheduled
Transparent blocking across project calls
Status: Supported.
An ordinary Guest function may call another ordinary function and resume across an asynchronous host capability without a coroutine calling convention.
Evidence:
MinimalScriptLoweringTest,
test ordinary project call resumes transparently across host blocking, and
kotlin_writer.rs,
test k2_ordinary_project_call_resumes_across_async_capability.
Default arguments
Status: Partial.
Platform APIs may publish constant Int or qualified enum-entry defaults, which direct platform calls lower
without JVM mask dispatchers. Omitted Array<String> parameters in project functions are supported only for
direct emptyArray() or direct arrayOf call defaults. Primary constructors evaluate supported Guest default
expressions at ordinary call sites after explicit arguments; general project function defaults remain limited
to the documented forms.
Evidence:
MinimalScriptLoweringTest,
tests sound beep lowers deterministically to a blocking Boolean capability operation, string arrays support
copyOfRange and supported default arguments, and primary constructor defaults preserve argument order and
earlier parameters paired with testKotlinConstructorDefaultsVmConformance;
ParameterInfoQueryTest,
test parameter info exposes a platform Int default.
Related work: not scheduled
Extension functions and overloads
Status: Partial.
K2 resolves project extensions and overloads by symbol, and same-named project functions do not impersonate trusted intrinsics. Execution coverage is not comprehensive.
Evidence:
MinimalScriptLoweringTest,
tests same-named char array helper remains an ordinary project call and same-named guest function remains
an ordinary project call, plus same-named guest calls preserve their resolved targets for vm conformance
paired with testKotlinNamedCallsVmConformance.
Related work: not scheduled
Named and vararg arguments
Status: Partial.
Ordinary K2 argument binding works only when the resulting direct call stays in the admitted signature subset;
direct arrayOf and listOf varargs are specially lowered, while spread arrays are rejected.
Related work: not scheduled
Generic functions, classes, and interfaces
Status: Partial.
Top-level fun <T> calls with inferred or explicit concrete arguments and invariant class Cell<T> style
declarations are specialized at compile time. Primary-constructor fields and direct methods use concrete
scalar or reference types; a non-null Int remains unboxed in both calls and fields. Platform library bodies
containing generic functions or generic classes are specialized in a consumer; generic class methods and
constructor fields retain concrete Int and reference layouts. Generic member bodies can call top-level
generic helpers that introduce further generic class instances; class and function dependencies are collected
until specialization is complete. Mixed modules retain precompiled ordinary functions alongside generic/inline
bodies; specialization can call a shared compiled private helper without publishing it as Kotlin API or
duplicating its implementation. Ordinary library bodies may materialize concrete generic classes and
interfaces, including those in return and parameter types. Consumers and dependent libraries reuse an
available trusted specialization, including its constructors, fields and methods, with one nominal owner.
Variants absent from dependencies remain source-specialized; inconsistent layouts, missing member exports and
ambiguous owners are rejected. Function-valued parameters of source-compiled generic functions use the
specialized element type, as exercised by the Iterable<T> predicate helpers. Concrete generic interfaces and
covariant result interfaces support the read-only List<T> contract. Inherited interface selection methods
retain their concrete owner and callback types when called through a concrete implementation or a parent
interface, including an intermediate generic interface. Overloads can share firstOrNull, strict selection
and filtering without default callback expressions.
Evidence: generic interface selection defaults preserve inherited typed callbacks, executed by
testKotlinProviderDefaultsVmConformance (short-circuiting, absence, typed filtering and strict failure).
Open and abstract generic classes with Any or interface parents can be specialized as concrete superclasses
of ordinary classes and companions; constructor delegation and inherited virtual methods retain the
specialization. Imported interfaces remain in the nominal parent list, so upcasts and type tests retain their
contract. Generic classes extending a class other than Any remain rejected.
Evidence: canonical peripheral companion specializes shared typed queries, executed by
testKotlinPeripheralQueriesVmConformance. ### Generic value classes and limits
Concrete generic value-class fields and member methods specialize through the same bounded model; generic interface bridges and precompiled producer/consumer layouts retain their nominal identity.
Evidence: multi field value classes preserve direct layouts nested calls and managed boundaries and
multi field value classes share canonical layouts across precompiled addon boundaries, executed by
testKotlinMfvcVmConformance. Contravariance, reified parameters and generic methods declaring their own type
parameters remain outside the subset. Direct Any values use the supported primitive boxes.
Expansion is bounded to 256 function and 256 class variants per compilation. Binary generic library templates
and runtime instantiation are absent.
Evidence:
MinimalScriptLoweringTest,
tests generic identity specializes primitive and reference calls, generic cell specializes field layout and
preserves aliases, generic interface dispatch retains concrete Int and reference types, list Int
covariance to Any preserves the list and boxes reads, and unsupported generic forms report source
diagnostics without artifacts;
K2CompilerAdapterTest,
test source library generic functions and classes specialize in consumer; VM conformance tasks
testKotlinGenericFunctionsVmConformance, testKotlinGenericCellVmConformance, and
testKotlinGenericLibraryVmConformance. Concrete library reuse is covered by
LibrarySpecializationsTest
and
CompuktersFir2IrPipelineTest.
Related work: #652, #656, #670, #676
Lambdas, local functions, and function references
Status: Partial.
Non-null function values using supported Guest parameter and result types are admitted in project function
signatures and locals: values may be passed, returned, stored, and invoked. The compiler generates an
interface for each distinct concrete signature without a fixed arity cut-off; artifact and VM limits still
apply. A function value can also be passed as an argument to another function value. Nested lambdas may
capture values through multiple lexical scopes and remain callable after the enclosing invocation returns.
Unbound references to non-suspending Guest top-level functions can likewise be stored, passed, returned, and
invoked, including with an inferred KFunction type. Only invocation is supported; reflection operations are
not. Bound references to ordinary Guest instance methods also work: the receiver expression is evaluated once,
retained by the function value, and dispatched virtually or through its interface when invoked. Unbound
instance-method references (Type::method) accept the receiver as their first argument and use the same
runtime dispatch. References to supported Guest primary constructors (::Type) can be stored, passed,
returned, and invoked, including zero- and multi-argument constructors. An expected function type may omit
trailing constructor parameters with supported defaults. Each invocation evaluates those defaults and
constructs a fresh instance through the existing class layout. Each lambda evaluation creates an ordinary
managed closure object; lambdas may capture immutable scalar and reference values, and reference captures
preserve the original referent and aliasing. A captured local var with no assignments after its
initialization is stored directly in the closure, like a val. A reassigned captured local uses one ordinary
managed typed cell per dynamic variable instance, shared by the enclosing code and every sibling closure;
primitive payloads remain unboxed.
Evidence: read-only captured vars avoid cells while reassigned vars retain them in
MinimalScriptLoweringTest, and read-only scalar, wide, nullable, reference and mutable capture execution in
testKotlinFunctionValuesVmConformance. Concrete supported generic collection instances such as
ArrayList<Item> may be captured through val or var; shared cells follow later reassignment.
Evidence: Iterable destination operations append preserve types and return identity in
MinimalScriptLoweringTest, executed by testKotlinDestinationVmConformance. Programs can declare top-level
and extension inline functions in project or admitted source-library files. Supported non-suspend,
non-reified calls are expanded before closure discovery; concrete generic inline calls retain scalar types.
Local/non-local and nested returns, Unit/Nothing, nullable and wide results, default callbacks and class
initializers are covered by GuestInlineIntegrationTest and testKotlinInlineBlocksVmConformance. Direct
scalar-only callbacks emit no object allocations in the focused artifact test. Stored/noinline callbacks,
escaping crossinline wrappers, nested captures and shared mutable cells retain ordinary managed ownership.
Runtime-referenced inline definitions remain usable; unused templates are discarded. Canonical
platform/intrinsic calls remain atomic, including transparent suspension through an expanded callback.
Member/local, suspend and reified inline declarations, unavailable/unadmitted bodies and unresolved type
arguments outside a supported enclosing generic owner are rejected with TARGET diagnostics. Preflight rejects
recursive inline dependencies, depth above 64 and cumulative projected work above 1,000,000 units;
specialization allows at most 256 variants and 64 active levels. These are conservative compiler safety
bounds, not calibrated VM capacity budgets. Production worker and JVM-plugin entry tests exercise the shared
pass; function-values, generic-library and transparent-call VM scenarios cover its integration.
Callback-taking collection extensions are inline and admit non-local returns from direct lambdas. Ordinary
generic wrappers retain their concrete emitter specialization; stored callbacks retain managed ownership.
Tasks.launch accepts direct, stored, and returned () -> Unit values. A direct top-level
Tasks.launch(::worker) remains a static spawn without a closure allocation. Types unsupported elsewhere in
Guest Kotlin, local-function and property references, constructors outside the admitted Guest class subset,
other adapted references, and variance conversions between different function signatures remain unsupported.
Evidence:
MinimalScriptLoweringTest,
tests supported function values lower to managed closures and shared capture cells (including nested
closures and shared mutable captures), task launch accepts direct stored and returned Unit lambdas,
unsupported closure shapes produce stable diagnostics, direct top level ordinary task lowers to spawn and
join, task launch rejects unsupported local and bound references, function value variance conversion is
rejected before artifact publication, supported constructor references lower to ordinary function values,
default adapted constructor references lower to managed function values, and unsupported constructor
reference is rejected before artifact publication; root tasks testKotlinFunctionValuesVmConformance and
testKotlinAdaptedConstructorsVmConformance.
Related work: #627, #631, #628, #632, #633, #634, #635, #636, #644
Recursion
Status: Partial.
Direct calls and bounded VM call depth can represent recursion, but no Kotlin-to-VM recursive source conformance test defines it as a supported language contract.
Related work: not scheduled
Top-level state
Status: Partial.
Immutable top-level properties support direct Int, Long, Float, Double, Boolean, Char, and
String literals plus direct IntChannel(capacity) construction. They lower to lazily initialized static VM
storage. Top-level var, custom or delegated accessors, initializer dependencies, and arbitrary object
construction remain unsupported.
Evidence:
MinimalScriptLoweringTest,
tests top level IntChannel lowers to VM owned bounded handoff and IntChannel construction rejects
unsupported ownership and capacity.
Related work: #614
Value-class method and constructor references, typed callbacks and capture storage follow the value-class contract.