-
Notifications
You must be signed in to change notification settings - Fork 21
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
foldRight override on indexedSeqOps is forward incompatible #12137
Comments
I would like to ask Michael Pilquist @mpilquist, as maintaner/developer of |
To lay out what's going on: every concrete trait method gets a static method on the side trait T {
def f = 1
// static def f$ = invokespecial f
} This allows invoking the specific implementation class C extends T {
override def f = T.f$
} This means that adding a new override to a trait is not forwards binary compatible: new subclasses will refer to the static forwarder of the new override. Even though this situation is the same since 2.12.0, I think we were not aware of how it impacts binary compatibility. |
Does overriding the overridden method again sound like a plausible workaround for scodec-bits? |
Yes, but a simple |
Echoing a comment I made elsewhere: "fixing" the incompatibility by reverting 2.13.4 back to the binary format of 2.13.0 is most likely a worse choice than doing nothing. A library compiled against 2.13.3 may include a reference to the new static super accessor, and therefore not work with a 2.13.2 standard library. However, if we remove the override in 2.13.4, that library build will also not work on 2.13.4. The latter, a library compiled with 2.13.x used with 2.13.(x+n), is quite certainly much more common. |
Dotty used to have a different encoding for traits which didn't require static forwarders and so might not have the same compat issue (not sure, I haven't checked): scala/scala3#5928, but we recently switched to the 2.13 encoding to stay binary-compatible with it. |
Yeah, with |
Could 2.13.4 keep the static method for bc with 2.13.3 but make sure calls to it never get emitted for bc with 2.13.2- ? |
Yes, we can internalize the known binary incompatibilities (https://github.com/scala/scala/pull/9197/files). We could then also add an annotation like |
New overrides added to traits are not forwards binary compatible (scala/bug#12137). For those overrides that were added since 2.12.0, a new special case in Mixin avoids generating the mixin forwarder, so compiling with 2.12.13 will emit code that is binary compatible with 2.12.0. Tested with this code: ``` object A extends scala.math.Ordering.IntOrdering // `reverse` override was added object B extends scala.math.Ordering.FloatOrdering // `reverse` override was removed object Test { def main(args: Array[String]): Unit = { println(A.reverse) println(B.reverse) } } ``` Code compiled with 2.12.13 (qsc/qs) works with all 2.12 libraries thanks to this fix. ``` qsc Test.scala && sv 2.12.0 Test && sv 2.12.12 Test && qs Test ``` Code compiled with 2.12.0 fails on 2.12.12. The super call in the generated mixin forwarder `B.reverse` invokes the static method `FloatOrdering.reverse$` that no longer exists. This will be the same in 2.12.13. ``` scv 2.12.0 Test.scala && sv 2.12.12 Test ```
New overrides added to traits are not forwards binary compatible (scala/bug#12137). For those overrides that were added since 2.12.0, a new special case in Mixin avoids generating the mixin forwarder, so compiling with 2.12.13 will emit code that is binary compatible with 2.12.0. Tested with this code: ``` object A extends scala.math.Ordering.IntOrdering // `reverse` override was added object B extends scala.math.Ordering.FloatOrdering // `reverse` override was removed object Test { def main(args: Array[String]): Unit = { println(A.reverse) println(B.reverse) } } ``` Code compiled with 2.12.13 (qsc/qs) works with all 2.12 libraries thanks to this fix. ``` qsc Test.scala && sv 2.12.0 Test && sv 2.12.12 Test && qs Test ``` Code compiled with 2.12.0 fails on 2.12.12. The super call in the generated mixin forwarder `B.reverse` invokes the static method `FloatOrdering.reverse$` that no longer exists. This will be the same in 2.12.13. ``` scv 2.12.0 Test.scala && sv 2.12.12 Test java.lang.NoSuchMethodError: scala.math.Ordering$FloatOrdering.reverse$ ```
The downside of this is that it introduces serialization incompatibilities, see scala/scala#9263 (comment). |
Current:
Option 1 - Excluding the forwarders:
Option 2 - Including the forwarders but point to the old impl:
So Option 1 looks better than Option 2 and the status quo. |
New overrides added to traits are not forwards binary compatible (scala/bug#12137). For those overrides that were added since 2.12.0, a new special case in Mixin avoids generating the mixin forwarder, so compiling with 2.12.13 will emit code that is binary compatible with 2.12.0. Tested with this code: ``` object A extends scala.math.Ordering.IntOrdering // `reverse` override was added object B extends scala.math.Ordering.FloatOrdering // `reverse` override was removed object Test { def main(args: Array[String]): Unit = { println(A.reverse) println(B.reverse) } } ``` Code compiled with 2.12.13 (qsc/qs) works with all 2.12 libraries thanks to this fix. ``` qsc Test.scala && sv 2.12.0 Test && sv 2.12.12 Test && qs Test ``` Code compiled with 2.12.0 fails on 2.12.12. The super call in the generated mixin forwarder `B.reverse` invokes the static method `FloatOrdering.reverse$` that no longer exists. This will be the same in 2.12.13. ``` scv 2.12.0 Test.scala && sv 2.12.12 Test java.lang.NoSuchMethodError: scala.math.Ordering$FloatOrdering.reverse$ ```
reproduction steps
as reported by @diesalbla on gitter: https://gitter.im/scala/scala?at=5f4e88c49566774dfe49860c
using scodec-bits 1.1.19 and scala 2.13.2
problem
scodec-bits 1.1.19 is compiled against scala 2.13.3 which introduced an override on
IndexedSeqOps
forfoldRight
in scala/scala#8929toIndexedSeq
is defined asfoldRight
apparently links to the overload which doesn't exist on 2.13.2I don't see any mima warnings on that PR.
The text was updated successfully, but these errors were encountered: