Skip to content

SuspendInterop: framework named shared conflicts with object shared #131

Description

@boringcactus

Questions:

What is the problem?

The default Kotlin Multiplatform settings for a new project created in Android Studio name the shared library shared and the iOS framework shared.framework. However, the shared instance of a Kotlin object Foo is named Foo.shared in Swift, and SKIE's generated coroutine wrapper code does not handle this correctly. (Or perhaps its generated code used to work in Xcode 15 but does not work in Xcode 16.)

The Kotlin code

object Foo {
    suspend fun bar() {}
}

will have the Shared.Foo.swift

// Generated by Touchlab SKIE 0.10.0

import Foundation

extension shared.Foo {

    @available(iOS 13, macOS 10.15, watchOS 6, tvOS 13, *)
    public func bar() async throws -> Swift.Void {
        return try await SwiftCoroutineDispatcher.dispatch {
            shared.__SkieSuspendWrappersKt.Skie_Suspend__3__bar(dispatchReceiver: self, suspendHandler: $0)
        }
    }

}

which will cause the build errors

error: Compilation failed: The /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swiftc command returned non-zero exit code: 1.
output:
generated/Shared/Shared.Foo.swift:10:13: error: static member 'shared' cannot be used on instance of type 'Foo'
 8 |     public func bar() async throws -> Swift.Void {
 9 |         return try await SwiftCoroutineDispatcher.dispatch {
10 |             shared.__SkieSuspendWrappersKt.Skie_Suspend__3__bar(dispatchReceiver: self, suspendHandler: $0)
             `- error: static member 'shared' cannot be used on instance of type 'Foo'
11 |         }
12 |     }

generated/Shared/Shared.Foo.swift:10:20: error: value of type 'Foo' has no member '__SkieSuspendWrappersKt'
 8 |     public func bar() async throws -> Swift.Void {
 9 |         return try await SwiftCoroutineDispatcher.dispatch {
10 |             shared.__SkieSuspendWrappersKt.Skie_Suspend__3__bar(dispatchReceiver: self, suspendHandler: $0)
                    `- error: value of type 'Foo' has no member '__SkieSuspendWrappersKt'
11 |         }
12 |     }

Fixes I can imagine with my limited knowledge of Swift or how SKIE works internally:

  1. By some mechanism disambiguate the reference to be shared-the-module as opposed to shared-the-static-member. It's not clear to me that this is actually possible in Swift, though.
  2. Remove the ambiguous module qualifier and just refer to __SkieSuspendWrappersKt instead of naming it via shared. Presumably the module is specified explicitly for good reasons, though, so this may not be possible in the general case.
  3. Only drop those module qualifiers if the module is named shared. This is worse, and it may still not work depending on the nature of the problems that the module qualifiers are there to fix.
  4. Emit a Gradle error from SKIE directly if the framework is named shared and SuspendInterop is enabled by default. If this error cannot be fixed except by renaming the framework, I'd rather rename the framework early and then never run into this error.
  5. Emit a Gradle error from SKIE directly if the framework is named shared and an object has a suspend fun with SuspendInterop enabled. At the very least, this error message could be more informative than it currently is.

When does the problem occur?

During Swift compilation (when trying to use the generated Kotlin Framework)

How do we reproduce the issue?

build.gradle.kts:

kotlin {
    listOf(
        iosX64(),
        iosArm64(),
        iosSimulatorArm64()
    ).forEach {
        it.binaries.framework {
            baseName = "shared"
        }
    }
}

src/commonMain/kotlin/Foo.kt:

object Foo {
    suspend fun bar() {}
}

What has changed since the last time SKIE worked in your project?

I added a suspend fun to a companion object in a Kotlin Multiplatform project that uses the default structure.

What versions of SKIE, Kotlin, and Gradle do you use?

SKIE 0.10.0, Kotlin 2.1.0, Gradle 8.9.

I'm also using Xcode 16.2, which might be interpreting Swift code that used to work correctly in a different way now, although my environment variables for the Gradle build step include SWIFT_VERSION=5.0 and I'd expect that to be a Swift 6 thing if it was really what was happening.

What is your SKIE Gradle configuration?

(This issue can be reproduced with the default SKIE settings.)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions