Skip to content

Apply spread operator when delegating variadic static funcs to companion - #261

Merged
marcprux merged 1 commit into
skiptools:mainfrom
vincentborko:pr/variadic-spread
Jul 24, 2026
Merged

Apply spread operator when delegating variadic static funcs to companion#261
marcprux merged 1 commit into
skiptools:mainfrom
vincentborko:pr/variadic-spread

Conversation

@vincentborko

Copy link
Copy Markdown
Contributor

Motivation

When a public/internal static function has a variadic parameter, the generated companion delegation drops the spread operator, producing uncompilable Kotlin (issue #64):

Argument type mismatch: actual type is 'kotlin.Array<CapturedType(out kotlin.String)>', but 'kotlin.String' was expected.

Root cause

A static function is transpiled to an override on the type's companion object plus a delegating open fun on the inner CompanionClass that calls back into the concrete implementation. Both are declared with vararg, but appendCompanionClassDelegatingMember (KotlinStatementTypes.swift) forwarded each argument by bare name. Inside the delegate a vararg parameter has its Array type, so the call needs the spread (*) operator.

Before:

open fun initBridge(context: Int, vararg libraryNames: String) = A.initBridge(context = context, libraryNames)

After:

open fun initBridge(context: Int, vararg libraryNames: String) = A.initBridge(context = context, *libraryNames)

Fix

Prefix the forwarded argument with * when the parameter is variadic — for both the unlabeled (*libraryNames) and labeled (names = *names) argument forms.

Testing

  • New StaticTests.testStaticVariadicSpread asserts the spread is emitted for both the unlabeled and labeled variadic forms (byte-for-byte against the generated Kotlin).
  • Full swift test suite green (923 tests, 0 failures).

A public/internal static function is emitted as an `override` on the type's
`companion object` plus a delegating `open fun` on `CompanionClass` that calls
back into the concrete implementation. For a variadic parameter the delegating
member is declared `vararg`, but `appendCompanionClassDelegatingMember` forwarded
the argument by bare name, so inside the delegate the parameter has its Array
type and Kotlin rejects the call:

    Argument type mismatch: actual type is 'kotlin.Array<...>',
    but 'kotlin.String' was expected.

Prefix the forwarded argument with the spread ("*") operator when the parameter
is variadic, for both the labeled and unlabeled argument forms.

Fixes skiptools#64.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@cla-bot cla-bot Bot added the cla-signed label Jul 24, 2026
@marcprux
marcprux merged commit 4ce8ad6 into skiptools:main Jul 24, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants