-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
cats 2.7.0 broke binary compatibility for Scala 3 (because mima wasn't run) #4062
Comments
It should be possible to introduce an implicit with a different type without breaking BC by doing something like: @deprecated("retained for binary compatibility")
private[cats] def catsInstancesForId: Distributive[Id] with Comonad[Id] = cats.catsInstancesForId
implicit def catsInstancesForId2
: Distributive[Id] with Bimonad[Id] with CommutativeMonad[Id] with NonEmptyTraverse[Id] =
cats.catsInstancesForId |
Might not want to make it |
We generally don't consider implicits to be part of source compatibility, so IMO this is something we can (and should) do in 2.7.1 |
|
I guess we were unlucky that |
Type erasure in Scala 3 is commutative: the erasure of A & B when A and B are unrelated traits is based on their lexicographic ordering
Not in Scala 3 where the erasure of an intersection is computed from the erasure of each operand of the intersection. (As an aside, the Scala 3 intersection type erasure algorithm is still not as good as I wish it was: it turned out to not be associative due to an oversight, I have an alternative proposal in http://guillaume.martres.me/pathless-scala.pdf (section 5.1) but that'll have to wait for Scala 4 😬 ) |
Seems
|
Those seem to be |
Alternatively, does Scala 3 treat |
Not as far as I know, it all gets erased to public methods. |
Yes it's very strange. That was my PR #3987 btw, and I had to add some filters but not for those. In any case should be safe to filter them on Scala 3. |
That's correct. I parse Scala annotations from Scala 2's pickle and Scala 3's tasty, but only parse the package private information from Scala 2's pickle. Not for any true reason, it's work just waiting for a motivating case to arise. But I must be blind this morning because I can't for the life of me see those unsafeApply and ks methods in the sources... |
Thanks for the confirmation. These methods were removed in #3987 |
Interesting, thanks for chiming in, is this a (relatively) new feature? I feel like I've had to add filters for package privates in the recent past, but maybe I'm confused :) |
Yeah. I've added so many filters for tweaking |
Maybe a similar feature is needed for sealed traits 🤔 |
For new methods? That might be a good idea. Open a Mima issue if you want to record your thoughts. |
I think this is a really important change, far more than the nuisance factor. It always seemed dangerous to me that:
But, now that MiMa natively understands package private, those filters wouldn't be necessary in ordinary use, thus disabling the footgun. So I think it would be excellent if Scala 3 can get this feature as well. |
Oh that's a good point - if we're using this trick of making something package private that was public before, then we can't expect to be able to change package private methods willy nilly (change their signature, make them abstract, etc.) 🤔 |
So I guess in this case checking both against old and new versions with MiMa makes sense. |
WDYM by this? |
I mean checking against cats 1.0, 1.1, 1.2, etc. instead of just the latest version - i.e. transitivity doesn't apply without caveats |
I'm not sure we are talking about the same thing. But I could be confused. In theory, I don't think checking against old versions is necessary at all. Since binary-compatible changes can only add to the public binary API, there should never be a situation where M.N has something that that M.(N+1) doesn't. So checking against M.(N+1) should be sufficient. OTOH, I'm talking about adding MiMa filters. When you do that, you are effectively telling MiMa "I am taking full responsibility the bincompat of this code." So if in M.(N+100) you do add a filter for a method that you thought was always package private, but was actually public in M.N and everyone forgot, it doesn't matter if you check M.(N+100) against M.N because you just told MiMa that you know best. Ideally, the only time we should have to add filters is when we are in fact breaking public APIs (in the Scala not Java sense). Which should be exceedingly rare. |
Yes but if MiMa knows about sealed traits and package private methods it should let you do those changes without adding a filter. And then it matters whether you check with the older version or not. |
Ahhh. Yes, you are absolutely right :)
Now I get this 😆 |
Sorry, I'm not completely catching this... The possibility to make some obsolete methods package private is one of vital features that allow us to add new features while maintaining the binary compatibility with older versions. So I'm wondering – will such a possibility still be preserved? |
Yes but it shouldn't come at cost of being able to change library internals. So we just have to be careful. |
Is there an ETA for a version of cats with this fix in? |
Personally, I'm hoping sometime in the next few weeks, pressure is mounting to release on Scala 3 + Native. There are snapshots available of the bincompat fix for anyone in a pinch. |
As discovered by @xuwei-k, see https://gist.github.com/xuwei-k/afe78856f95124c6ca5323beb7b32b5c from argonaut-io/argonaut#476
Seems like mima isn't setup for scala 3:
(it needs to use cats-core_3:2.6.1 since that's the only previously published version for Scala 3).
Note that this is absolutely not a bug in Scala 3: we intentionally use a different type erasure algorithm for intersection/compound types, because the Scala 2 algorithm was not commutative but also because it was dependent on compiler implementation details so we couldn't fully reproduce it even if we tried, cf https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Erasure.scala, scala/scala3#5139.
The text was updated successfully, but these errors were encountered: