swiftlang / swiftlang/swift-java
Compilation error for default protocol function implementation: "invalid redeclaration of..."
Nobody has claimed this yet.
- Dominant language
- Swift
- Stars
- 1.2k
- Forks
- 123
- Avg merge
- 1d 7h
- Merged PRs (30d)
- 16
Description
Commit hash: 0dd772b8fcae9efd5bda701f1a0be95f9deb2836
Context:
While testing swiftly's support of existing Swift code, noticed that a protocol with default implementation results in generated Java code that is not compiling due to a duplicate Java_com_example_swiftexamplelib_TestBox__00024action_1__JJ symbol.
import Foundation
public protocol Test {
func action()
}
public extension Test {
func action() { }
}
Results in the following compilation error:
.../.build/plugins/outputs/lib/SwiftTestLib/destination/JExtractSwiftPlugin/Sources/Sample+SwiftJava.swift:54:13: error: invalid redeclaration of 'Java_com_example_swiftexamplelib_TestBox__00024action_1__JJ(environment:thisClass:selfPointer:selfTypePointer:)'
26 | #endif
27 | @_cdecl("Java_com_example_swiftexamplelib_TestBox__00024action_1__JJ")
28 | public func Java_com_example_swiftexamplelib_TestBox__00024action_1__JJ(environment: UnsafeMutablePointer<JNIEnv?>!, thisClass: jclass, selfPointer: jlong, selfTypePointer: jlong) {
| `- note: 'Java_com_example_swiftexamplelib_TestBox__00024action_1__JJ(environment:thisClass:selfPointer:selfTypePointer:)' previously declared here
29 | guard let selfPointerTypeMetadataPointer$ = UnsafeRawPointer(bitPattern: Int(Int64(fromJNI: selfTypePointer, in: environment))) else {
30 | fatalError("selfTypePointer memory address was null")
:
52 | #endif
53 | @_cdecl("Java_com_example_swiftexamplelib_TestBox__00024action_1__JJ")
54 | public func Java_com_example_swiftexamplelib_TestBox__00024action_1__JJ(environment: UnsafeMutablePointer<JNIEnv?>!, thisClass: jclass, selfPointer: jlong, selfTypePointer: jlong) {
| `- error: invalid redeclaration of 'Java_com_example_swiftexamplelib_TestBox__00024action_1__JJ(environment:thisClass:selfPointer:selfTypePointer:)'
55 | guard let selfPointerTypeMetadataPointer$ = UnsafeRawPointer(bitPattern: Int(Int64(fromJNI: selfTypePointer, in: environment))) else {
56 | fatalError("selfTypePointer memory address was null")
Generated Java file:
// ==== --------------------------------------------------
// Thunks for Test
// Generated by swift-java
#if hasFeature(InternalImportsByDefault)
public import SwiftJava
public import SwiftJavaJNICore
public import SwiftJavaRuntimeSupport
#else
import SwiftJava
import SwiftJavaJNICore
import SwiftJavaRuntimeSupport
#endif
import Foundation
import SwiftJava
import SwiftJavaRuntimeSupport
#if compiler(>=6.3)
@used
#endif
#if compiler(>=6.4)
@diagnose(DeprecatedDeclaration, as: ignored)
#endif
@_cdecl("Java_com_example_swiftexamplelib_TestBox__00024action_1__JJ")
public func Java_com_example_swiftexamplelib_TestBox__00024action_1__JJ(environment: UnsafeMutablePointer<JNIEnv?>!, thisClass: jclass, selfPointer: jlong, selfTypePointer: jlong) {
guard let selfPointerTypeMetadataPointer$ = UnsafeRawPointer(bitPattern: Int(Int64(fromJNI: selfTypePointer, in: environment))) else {
fatalError("selfTypePointer memory address was null")
}
let selfPointerDynamicType$: Any.Type = unsafeBitCast(selfPointerTypeMetadataPointer$, to: Any.Type.self)
guard let selfPointerRawPointer$ = UnsafeMutableRawPointer(bitPattern: Int(Int64(fromJNI: selfPointer, in: environment))) else {
fatalError("selfPointer memory address was null")
}
#if hasFeature(ImplicitOpenExistentials)
let selfPointerExistential$ = selfPointerRawPointer$.load(as: selfPointerDynamicType$) as! (any Test)
#else
func selfPointerDoLoad<Ty>(_ ty: Ty.Type) -> (any Test) {
selfPointerRawPointer$.load(as: ty) as! (any Test)
}
let selfPointerExistential$ = _openExistential(selfPointerDynamicType$, do: selfPointerDoLoad)
#endif
selfPointerExistential$.action()
} // printCDecl(_:javaMethodName:parentName:parameters:resultType:_:) @ JExtractSwiftLib/JNISwift2JavaGenerator+SwiftThunkPrinting.swift:893
#if compiler(>=6.3)
@used
#endif
#if compiler(>=6.4)
@diagnose(DeprecatedDeclaration, as: ignored)
#endif
@_cdecl("Java_com_example_swiftexamplelib_TestBox__00024action_1__JJ")
public func Java_com_example_swiftexamplelib_TestBox__00024action_1__JJ(environment: UnsafeMutablePointer<JNIEnv?>!, thisClass: jclass, selfPointer: jlong, selfTypePointer: jlong) {
guard let selfPointerTypeMetadataPointer$ = UnsafeRawPointer(bitPattern: Int(Int64(fromJNI: selfTypePointer, in: environment))) else {
fatalError("selfTypePointer memory address was null")
}
let selfPointerDynamicType$: Any.Type = unsafeBitCast(selfPointerTypeMetadataPointer$, to: Any.Type.self)
guard let selfPointerRawPointer$ = UnsafeMutableRawPointer(bitPattern: Int(Int64(fromJNI: selfPointer, in: environment))) else {
fatalError("selfPointer memory address was null")
}
#if hasFeature(ImplicitOpenExistentials)
let selfPointerExistential$ = selfPointerRawPointer$.load(as: selfPointerDynamicType$) as! (any Test)
#else
func selfPointerDoLoad<Ty>(_ ty: Ty.Type) -> (any Test) {
selfPointerRawPointer$.load(as: ty) as! (any Test)
}
let selfPointerExistential$ = _openExistential(selfPointerDynamicType$, do: selfPointerDoLoad)
#endif
selfPointerExistential$.action()
} // printCDecl(_:javaMethodName:parentName:parameters:resultType:_:) @ JExtractSwiftLib/JNISwift2JavaGenerator+SwiftThunkPrinting.swift:893
Environment: Swift 6.3.3 on macOS.
$ swiftly run swift --version
Apple Swift version 6.3.3 (swift-6.3.3-RELEASE)
Target: arm64-apple-macosx26.0
$ uname -a
Darwin it-C01241 25.6.0 Darwin Kernel Version 25.6.0: Sat Jul 11 15:26:21 PDT 2026; root:xnu-12377.161.13~4/RELEASE_ARM64_T6000 arm64
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the protocol default-implementation case and inspect the generated Sample+SwiftJava.swift output. Start in JNISwift2JavaGenerator+SwiftThunkPrinting.swift around printCDecl at line 893, then trace why the same JNI symbol is emitted twice. Done means the generated Swift compiles without an invalid redeclaration and the reproduction case still calls the default implementation.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java, swift
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 58/100