-
Notifications
You must be signed in to change notification settings - Fork 362
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Binary Signature Name #302
Comments
Hello! I have several questions about the proposal:
|
It means that you cannot have, for example,
You cannot currently compile this code on JVM, and you cannot work around the problem with // Compiles fine with this proposal
interface PolynomialRing<C, P> {
@BinarySignatureName("plusCC")
operator fun C.plus(other: C): C = TODO()
@BinarySignatureName("plusCP")
operator fun C.plus(other: P): P = TODO()
@BinarySignatureName("plusPC")
operator fun P.plus(other: C): P = TODO()
@BinarySignatureName("plusPP")
operator fun P.plus(other: P): P = TODO()
} |
How does this feature interact with special bridge methods for builtins with different binary names on the JVM? If I understand the proposal correctly then users will have to add manual bridge methods when changing binary names. E.g., interface A<T> {
fun foo(x: T)
}
class B : A<String> {
@BinarySignatureName("bar")
open fun foo(x: String) {}
@Deprecated("Binary compatibility", level = DeprecationLevel.HIDDEN)
override fun foo(x: String) { this.foo(x) }
} The same issue already exists for Kotlin collection methods on the JVM, where we have Kotlin functions with different names compared to the binary names in (Java) interfaces. In this case we generate such bridge methods implicitly. I think we should disable automatic bridge generation in the presence of For example, In this case there is no way to produce the correct bridge methods manually. Even if it was, these bridges are fragile. For example, in order for the resulting class to be subclassable from Java we need to ensure that we don't generate a generic signature. |
I think there are two ways to deal with renamed declarations from the Kotlin/JVM standard library. In order to allow any signatures on overrides we should add an additional override matching signature corresponding to the binary signature. This has to be present in addition to matching the declarations without signatures which is what we currently do. Now the only choice is whether this becomes a special case on the JVM - which I would strongly prefer - or if we want to have the same corner case on all platforms. For the latter we could just add something like the following text immediately after Objective-C overrides in Kotlin/Native
However, this creates additional implementation concerns for non-JVM platforms for no good reason. Instead I would propose that as part of this KEEP we update
Since |
@sfs Thanks for the notice on special bridges. Indeed, we must take them into account in the However, I don't see how your suggestions on "implicit JvmName" is going to help here. See, the way these special bridges work is through the generation of a bridge. E.g., if you override Can you explain a little bit more here a specific problem with special bridges that you are trying to solve, please? |
@elizarov Maybe I'm reading the specification incorrectly, because from your response it looks like the intention is that declarations with My reading was that you cannot override a specially-bridged declaration with a function with an
The main problem with special bridge methods is that they are generated as final (to avoid users overriding one but not the other from Java). When we migrate existing Java libraries to Kotlin we typically have to avoid binary incompatible changes and changing a method to final is a binary incompatible change. It would be useful to have some mechanism to opt-out of the special bridge machinery for a given class. In KT-52897 I suggested relaxing the restrictions on abstract class A : Collection<String> {
@get:BinarySignatureName("size")
abstract override val size: Int
} The This gets more complicated when we inherit implementations with potentially different names. Consider the following use case. open class A {
@get:BinarySignatureName("size")
val size: Int
get() = ...
}
class B : A(), Collection<String> { ... } At the moment we would have two After bridge generation on the JVM this code would result in a platform declaration clash, since we would try to generate a The first issue here is that outside of the JVM this code is fine and this is the correct behavior. The standard library function in question has a binary name of On the other hand, on the JVM it would be extremely useful to be able to override these standard library methods without introducing additional bridge methods and for that we would need to consider, e.g., a declaration of the form With such an override matching rule in place we would not generate a bridge, because both the declaration in the standard library and its implementation would have the same binary name. |
The problem is more complicated than opting out of special bridge generation. Ideally, you should be able to manipulate those special bridges without any hard-coded compiler magic. That is, all the specially-bridged collection declarations shall be marked with some new kind of JVM-specific annotations that would drive the generation of the special bridges, as opposed to them being hard-coded into the compiler. And their design, indeed, shall also include an ability to opt-out of the final bridge generation to write it manually. |
This proposal introduces
@BinarySignatureName
annotation that serves as a cross-platform variant of@JvmName
annotation that is used in Kotlin/JVM and is designed to solve various library migration and Object-C interoperability use-cases.
This annotation affects overload matching and linking of cross-platform Kotlin libraries.
For convenience of Object-C interoperability, a helper
@ObjCSignature
annotation is introduced that makes Objective-Cinteroperability more straightforward as shown later.
See binary-signature.md for the full text of the proposal, use-cases, detailed design, and open issues. Use PR #303 for minor corrections (like typos and text style) and use this issue for the discussion on the substance of the proposal.
The text was updated successfully, but these errors were encountered: