Skip to content

reject unsupported tuple components#750

Merged
ktoso merged 1 commit into
swiftlang:mainfrom
nerzh:fix/unsupported-tuple
May 15, 2026
Merged

reject unsupported tuple components#750
ktoso merged 1 commit into
swiftlang:mainfrom
nerzh:fix/unsupported-tuple

Conversation

@nerzh
Copy link
Copy Markdown
Contributor

@nerzh nerzh commented May 14, 2026

I noticed that jextract allowed multielement swift tuples in places where the JNI bridge later requires a concrete JavaBoxable type. Swift tuples cannot conform to protocols, so the generated code could fail to compile. I fixed it by rejecting unsupported tuple components during translation 🫣

ObertonWalletCore/destination/JExtractSwiftPlugin/Sources/BindingStore+SwiftJava.swift:24:41: error: type 'BindingStore.RawResponse' (aka '(requestId: UInt32, stringResponse: String, responseType: TSDKBindingResponseType, finished: Bool)') cannot conform to 'JavaBoxable' [#ProtocolTypeNonConformance]
22 | @_cdecl("Java_com_custwallet_core_BindingStore__00024getCompleteResponses__")
23 | public func Java_com_custwallet_core_BindingStore__00024getCompleteResponses__(environment: UnsafeMutablePointer<JNIEnv?>!, thisClass: jclass) -> jlong {
24 |   return BindingStore.completeResponses.dictionaryGetJNIValue(in: environment)
   |                                         |- error: type 'BindingStore.RawResponse' (aka '(requestId: UInt32, stringResponse: String, responseType: TSDKBindingResponseType, finished: Bool)') cannot conform to 'JavaBoxable' [#ProtocolTypeNonConformance]
   |                                         `- note: only concrete types such as structs, enums and classes can conform to protocols
25 | } // printCDecl(_:javaMethodName:parentName:parameters:resultType:_:) @ JExtractSwiftLib/JNISwift2JavaGenerator+SwiftThunkPrinting.swift:751
26 | 

/oberton-wallet-core/.build/checkouts/swift-java/Sources/SwiftJava/BridgedValues/JavaValue+Dictionary.swift:20:1: note: required by referencing instance method 'dictionaryGetJNIValue(in:)' on 'Dictionary' where 'Value' = 'BindingStore.RawResponse' (aka '(requestId: UInt32, stringResponse: String, responseType: TSDKBindingResponseType, finished: Bool)')
18 | // MARK: Dictionary extension for JNI bridging
19 | 
20 | extension Dictionary where Key: JavaBoxable & Hashable, Value: JavaBoxable {
   | `- note: required by referencing instance method 'dictionaryGetJNIValue(in:)' on 'Dictionary' where 'Value' = 'BindingStore.RawResponse' (aka '(requestId: UInt32, stringResponse: String, responseType: TSDKBindingResponseType, finished: Bool)')
21 |   /// Box this dictionary and return a jlong pointer for passing across JNI.
22 |   /// The dictionary is retained on the Swift heap; Java holds the pointer.

@nerzh nerzh requested a review from ktoso as a code owner May 14, 2026 19:35
Copy link
Copy Markdown
Collaborator

@ktoso ktoso left a comment

Choose a reason for hiding this comment

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

Hmmm, I see -- we'll have to make those work eventually I think. I'll make an issue, meanwhile this is ok

@ktoso ktoso merged commit dd03b67 into swiftlang:main May 15, 2026
73 checks passed
@ktoso
Copy link
Copy Markdown
Collaborator

ktoso commented May 15, 2026

#753

@nerzh
Copy link
Copy Markdown
Contributor Author

nerzh commented May 15, 2026

@ktoso yes, I understand that my solutions may be temporary, because your library is very large and complex, and it is difficult to fully understand it right away. I completely understand that later you may replace this with approaches that fit better within the patterns and architecture adopted in the library 🤝

@ktoso
Copy link
Copy Markdown
Collaborator

ktoso commented May 15, 2026

No problem, thanks a lot for the contribution! Let me know if you need a tagged release, we could do a 0.3.1 at any time

@sidepelican
Copy link
Copy Markdown
Contributor

Beyond tuples, most non-primitive types aren't usable in Dictionaries.
I'm currently working on a PR to address this.

@nerzh
Copy link
Copy Markdown
Contributor Author

nerzh commented May 15, 2026

@ktoso Thank you for the offer, I can wait until the next full release. For now, I’m using my own branch where I merged all 3 of my PRs, because I really needed these basic fixes to comfortably and lazily develop a cross-platform library with shared logic for iOS and Android applications.

At this point, everything I wrote has finally been built into a single cross-platform Swift library together with all dependencies from other dynamic libraries built in Rust and C++. And it successfully runs on Android. The first test flight went well — hopefully everything will continue to be fine :)

Thank you for your huge amount of work and for such an interesting approach, which saved me from the enormous effort of writing JNI wrappers manually. You guys are awesome 👍

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.

3 participants