-
Notifications
You must be signed in to change notification settings - Fork 21
Seemingly correct Java generic signature leads to NoSuchMethodError when Java and Scala erase types differently #12300
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
Milestone
Comments
smarter
added a commit
to dotty-staging/dotty
that referenced
this issue
Mar 18, 2021
Thanks to scala#11603, we can now freely how we erase our intersection types without compromising compatibility with Scala 2. We take advantage of this by designing a new erasedGlb algorithm which respects associativity and commutativity and can also erase Java intersections without any special case. This commit also improves the way we handle intersections in Java generic signature to produce more precise types when possible and to ensure that we never emit a type that would lead to javac emitting invalid bytecode (which can happen in Scala 2: scala/bug#12300).
smarter
added a commit
to dotty-staging/dotty
that referenced
this issue
Mar 18, 2021
Thanks to scala#11603, we can now freely decide how we erase our intersection types without compromising compatibility with Scala 2. We take advantage of this by designing a new erasedGlb algorithm which respects associativity and commutativity and can also erase Java intersections without any special case. This commit also improves the way we handle intersections in Java generic signature to produce more precise types when possible and to ensure that we never emit a type that would lead to javac emitting invalid bytecode (which can happen in Scala 2: scala/bug#12300).
smarter
added a commit
to dotty-staging/dotty
that referenced
this issue
Mar 18, 2021
Thanks to scala#11603, we can now freely decide how we erase our intersection types without compromising compatibility with Scala 2. We take advantage of this by designing a new erasedGlb algorithm which respects associativity and commutativity and can also erase Java intersections without any special case. This commit also improves the way we handle intersections in Java generic signature to produce more precise types when possible and to ensure that we never emit a type that would lead to javac emitting invalid bytecode (which can happen with Scala 2: scala/bug#12300).
Fixed in Scala 3 both by aligning Scala erasure with Java erasure and by being more careful about emitting valid generic signatures: scala/scala3#11808. Scala 2 can't change its erasure but the generic signature handling could be reused to fix this issue (it would make the compiler emits a signature equivalent to |
smarter
added a commit
to dotty-staging/dotty
that referenced
this issue
Mar 18, 2021
Thanks to scala#11603, we can now freely decide how we erase our intersection types without compromising compatibility with Scala 2. We take advantage of this by designing a new erasedGlb algorithm which respects associativity and commutativity and can also erase Java intersections without any special case. This commit also improves the way we handle intersections in Java generic signature to produce more precise types when possible and to ensure that we never emit a type that would lead to javac emitting invalid bytecode (which can happen with Scala 2: scala/bug#12300). Fixes scala#5139.
smarter
added a commit
to dotty-staging/dotty
that referenced
this issue
Mar 18, 2021
Thanks to scala#11603, we can now freely decide how we erase our intersection types without compromising compatibility with Scala 2. We take advantage of this by designing a new erasedGlb algorithm which respects associativity and commutativity and can also erase Java intersections without any special case. This commit also improves the way we handle intersections in Java generic signature to produce more precise types when possible and to ensure that we never emit a type that would lead to javac emitting invalid bytecode (which can happen with Scala 2: scala/bug#12300). Fixes scala#5139.
smarter
added a commit
to dotty-staging/dotty
that referenced
this issue
Mar 20, 2021
Thanks to scala#11603, we can now freely decide how we erase our intersection types without compromising compatibility with Scala 2. We take advantage of this by designing a new erasedGlb algorithm which respects associativity and commutativity and can also erase Java intersections without any special case. Incidentally, this lets us reverse a recent change in scala-stm which was previously required due to two equivalent types ending up with different signatures. This commit also improves the way we handle intersections in Java generic signature to produce more precise types when possible and to ensure that we never emit a type that would lead to javac emitting invalid bytecode (which can happen with Scala 2: scala/bug#12300). Fixes scala#5139.
smarter
added a commit
to dotty-staging/dotty
that referenced
this issue
Mar 21, 2021
Thanks to scala#11603, we can now freely decide how we erase our intersection types without compromising compatibility with Scala 2. We take advantage of this by designing a new erasedGlb algorithm which respects associativity and commutativity and can also erase Java intersections without any special case. Incidentally, this lets us reverse a recent change in scala-stm which was previously required due to two equivalent types ending up with different signatures. This commit also improves the way we handle intersections in Java generic signature to produce more precise types when possible and to ensure that we never emit a type that would lead to javac emitting invalid bytecode (which can happen with Scala 2: scala/bug#12300). Fixes scala#5139.
smarter
added a commit
to dotty-staging/dotty
that referenced
this issue
Mar 21, 2021
Thanks to scala#11603, we can now freely decide how we erase our intersection types without compromising compatibility with Scala 2. We take advantage of this by designing a new erasedGlb algorithm which respects associativity and commutativity and can also erase Java intersections without any special case. Incidentally, this lets us reverse a recent change in scala-stm which was previously required due to two equivalent types ending up with different signatures. This commit also improves the way we handle intersections in Java generic signature to produce more precise types when possible and to ensure that we never emit a type that would lead to javac emitting invalid bytecode (which can happen with Scala 2: scala/bug#12300). Fixes scala#5139.
smarter
added a commit
to dotty-staging/dotty
that referenced
this issue
Mar 22, 2021
Thanks to scala#11603, we can now freely decide how we erase our intersection types without compromising compatibility with Scala 2. We take advantage of this by designing a new erasedGlb algorithm which respects associativity and commutativity and can also erase Java intersections without any special case. Incidentally, this lets us reverse a recent change in scala-stm which was previously required due to two equivalent types ending up with different signatures. This commit also improves the way we handle intersections in Java generic signature to produce more precise types when possible and to ensure that we never emit a type that would lead to javac emitting invalid bytecode (which can happen with Scala 2: scala/bug#12300). Fixes scala#5139.
michelou
pushed a commit
to michelou/scala3
that referenced
this issue
Mar 22, 2021
Thanks to scala#11603, we can now freely decide how we erase our intersection types without compromising compatibility with Scala 2. We take advantage of this by designing a new erasedGlb algorithm which respects associativity and commutativity and can also erase Java intersections without any special case. Incidentally, this lets us reverse a recent change in scala-stm which was previously required due to two equivalent types ending up with different signatures. This commit also improves the way we handle intersections in Java generic signature to produce more precise types when possible and to ensure that we never emit a type that would lead to javac emitting invalid bytecode (which can happen with Scala 2: scala/bug#12300). Fixes scala#5139.
michelou
pushed a commit
to michelou/scala3
that referenced
this issue
Mar 22, 2021
Thanks to scala#11603, we can now freely decide how we erase our intersection types without compromising compatibility with Scala 2. We take advantage of this by designing a new erasedGlb algorithm which respects associativity and commutativity and can also erase Java intersections without any special case. Incidentally, this lets us reverse a recent change in scala-stm which was previously required due to two equivalent types ending up with different signatures. This commit also improves the way we handle intersections in Java generic signature to produce more precise types when possible and to ensure that we never emit a type that would lead to javac emitting invalid bytecode (which can happen with Scala 2: scala/bug#12300). Fixes scala#5139.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
reproduction steps
using Scala 2.13.4,
problem
The issue is that
javac
relies on the generic signature to compute the bytecode signature (even though the actual bytecode signature is present in the bytecode), the generic signature matches what we have in source code:... but whereas Scala has some complicated rules to decide how to erase an intersection type, Java always erases them to the erasure of the left most type in the intersection (which is supposed to be a class), so it emits a call to
Scala.foo
with the signature(Ljava/lang/Object;)V
, whereas the actual signature emitted by Scala was(LMyTrait;)V
.Short of changing the rules for Scala erasure to match Java erasure (which can't be done without breaking binary compatibility, and might not be ideal either, cf scala/scala3#5139), the only fix is to not generate Java generic signatures (or generate less precise signatures) in situations where Java and Scala disagree on how to erase a type.
The text was updated successfully, but these errors were encountered: