Skip to content

JNI: fix non-compiling async thunks for protocol boxes and generic types - #905

Merged
ktoso merged 2 commits into
swiftlang:mainfrom
Flatout73:bugfix/dollar-sign
Aug 25, 2026
Merged

JNI: fix non-compiling async thunks for protocol boxes and generic types#905
ktoso merged 2 commits into
swiftlang:mainfrom
Flatout73:bugfix/dollar-sign

Conversation

@Flatout73

@Flatout73 Flatout73 commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Motivation

Async methods in JNI mode capture self into the Task via nonisolated(unsafe)
bindings. The capture always referenced <param>$, but that binding only exists for
class/actor lowering (.extractSwiftValue). Protocol boxes load self into
<param>Existential$, and generic-Self downcalls render inside the opener extension
where selfTypePointer is never bound — so the generated Swift referenced unbound
identifiers and failed to compile.

Changes

  • Capture the binding the self lowering actually produced: <param>$ for
    classes/actors, <param>Existential$ for protocol boxes.
  • Stop capturing the type-metadata parameter; the opener thunk neither receives
    nor binds it, and the task body never uses it.

Testing

New JNIAsyncSelfCaptureTests pin the generated captures for all three self
shapes (class, protocol box, generic class); the generic and protocol tests fail
without this change. Full test suite passes (654 tests).

🤖 Fixed with help of Claude Code

#865

@Flatout73 Flatout73 changed the title Bugfix/dollar sign JNI: fix non-compiling async thunks for protocol boxes and generic types Aug 23, 2026
@Flatout73
Flatout73 marked this pull request as ready for review August 23, 2026 16:12
@Flatout73
Flatout73 requested a review from ktoso as a code owner August 23, 2026 16:12
"""
@_cdecl("Java_com_example_swift_WorkerBox__00024work__JJLjava_util_concurrent_CompletableFuture_2")
...
nonisolated(unsafe) let selfPointerExistentialSendable$ = selfPointerExistential$

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Heh, re-reading these now I guess we should be naming them selfPointerExistentialUnsafeSendable$ tbh; It's just generated code but it'll be better to get the point across also for us reading the code that these are not actually safe "Sendable" -- I know this term was here before, would you mind changing those names to UnsafeSendable though please?

Comment thread Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+NativeTranslation.swift Outdated
Comment thread Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+NativeTranslation.swift Outdated
Comment thread Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+NativeTranslation.swift Outdated
@ktoso

ktoso commented Aug 24, 2026

Copy link
Copy Markdown
Collaborator

Looks good, let's adjust the naming though while we're here (and run the formatter please).

@Flatout73

Copy link
Copy Markdown
Contributor Author

Fixed

@Flatout73
Flatout73 requested a review from ktoso August 24, 2026 13:41
@ktoso

ktoso commented Aug 25, 2026

Copy link
Copy Markdown
Collaborator

Neat, thanks!

@ktoso
ktoso merged commit a736a64 into swiftlang:main Aug 25, 2026
82 of 84 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants