-
Notifications
You must be signed in to change notification settings - Fork 71
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
Scala 2.12 support #78
Comments
Hi Seth, could you describe what the issue is? I had a quick look at the conversation you linked, but it's not apparent to me what is the problem, and how you plan on fixing it. I'd appreciate if this ticket could contain these information. |
The issue is that MiMa reports many more spurious incompatibility errors related to anonymous functions. scalac 2.12 generates one (private but public-ized) method in the enclosing class for the body of every anonymous function. If you add, move, or remove anonymous functions within a method, scalac will now produce a different set of such methods, and those produce binary incompatibilities as identified by MiMa. Although, in fact, we know they cannot be called from anywhere but the method body, since they have been generated by scalac. Unlike other sources of synthetic-method-causes-bin-incompat issues, this one produces so many false positives that humanly sorting through those (to whitelist them) is impractical. See the gist with the reported errors. As of now, I am not 100% sure where the responsibilities to fix this lie. It might be scalac's fault, or MiMa's fault, or they might have shared responsibilities in the problem. An obvious (but not well thought-about; might be too permissive) fix with the way 2.12.0-M2 emits lambdas would be to blindly ignore any method containing |
What I don't get is why these synthetic methods aren't private in the bytecode. If they are non-public, then they might be accessed in other places, which could lead to binary incompatibilities. Do you guys really feel confident this eventuality isn't possible (now and in the future)? |
I'd still appreciate if someone could provide a small class snippet with an example of the generated synthetic method so that I can get up to speed on what has changed in Scala 2.12 :-) |
I think because it is actually called by the |
I see. I'm wondering if having Scala generating these methods as private package, and then adding in MiMa an option for ignoring private package binary incompatibilities might be a better solution. The advantages I see are:
|
@dotta you asked for an example. if you compile e.g.: class C {
var a = 5
def foo() {
val f1 = () => a.toString
val f2 = (x: Int) => x * a
val f3 = (z: String) => s"$z$a$z"
}
} it's crucial here that the lambdas close over something from the enclosing class, otherwise the generated compiled with 2.12.0-M2, you get (javap): public class C {
...
public final java.lang.String C$$$anonfun$1();
public final int C$$$anonfun$2(int);
public final java.lang.String C$$$anonfun$3(java.lang.String);
...
} and the @retronym @adriaanm can you weigh in on whether you advocate fixing it on the compiler side with Mirco's private or package-private suggestion, or whether you think it would be better for MiMa to just ignore anything with |
Can we make them private without hurting the inliner? This would mean you cannot inline code that calls an anonfun unless you have access to that anonfun method. I'm not sure either we can ignore anonfun methods unless we are sure they are never referenced from outside the compilation unit that defines them, but that seems to contradict the assumption of my previous concern. |
hmm, inliner, so maybe we need @lrytz |
The areas to consider are deserialization and the inliner. For deserialization, I had originally thought that we would need to make them public to support our strategy of using generic code (LambdaDeserializer) to deserialize all lambdas. Java does it differently, and embeds custom deserialization code into each class that hosts lambdas for serializable functional interfaces. However, after working out the the details of the implementation, I found that we needed to pass a However, I didn't revert the decision to make them uniformly public. Interaction with inlining was part of the reason, but I recall that the change to make the public simplified other parts of the indylamnda implementation, too. I can't recall the details right now, but can dig it up if you're interested. Would it be possible for MiMa to turn a blind eye to
Note that wouldn't exclude
Bytecode ACC_SYNTHETIC, meaning: "invisible to Java source", corresponds to Scala's |
That's actually an area that we ought to improve on a little. Tracking as scala/scala-dev#43 |
@retronym I can't find where it is said in the JVM spec that members with the
But that doesn't clarify its visibility. If |
@SethTisue Thanks for the example! |
ACC_SYNTHETIC is used for things like the static accessor methods that Java generates to expose private methods to in nested classes. Java doesn't do any boilerplate method generation (like Scala case classes), so "not present in the source code" ends up meaning the same as "not callable from source code". |
@retronym Great, then I think we are good. Ignoring |
sounds good to me, but maybe do a test run over some sample jars, a line of debugging output every time it ignores an |
@SethTisue I was under the impression one of you would do the work ;-) |
heh. OK, yes, I will do it. |
@SethTisue Feel free to roll out a release (version numbers are cheap). |
I Looking forward to a release so we can re-enable MiMa checking in our build for the 2.12 artifacts. |
MiMa 0.1.8 fixes the issue lightbend-labs/mima#78 which was responsible for the high level of noise in 2.12 artifacts.
MiMa 0.1.8 fixes the issue lightbend-labs/mima#78 which was responsible for the high level of noise in 2.12 artifacts.
@sjrd reports that MiMa is just about useless with 2.12.0-M2.
for now, 2.12 is very much a moving target and the way lambdas and other things are encoded in bytecode is still changing. so it may or may not make sense for someone to attempt to tackle this right now, but obviously it will need tackling eventually.
The text was updated successfully, but these errors were encountered: