Open scabug opened 11 years ago
Imported From: https://issues.scala-lang.org/browse/SI-7085?orig=1 Reporter: @gkossakowski
@retronym said:
as the static accessor is synthetic, it doesn't affect binary compatibility
Could you elaborate on that point?
I thought that any method can be called from a different compilation unit affect BC. So the specific case of private
(visible to the companion class) would be okay, as would private[enclObject]
, but private[enclPackage]
or protected[anything]
would not.
@adriaanm said: my understanding was that introducing new methods is fine as long as we don't let anyone call them, which would be the case since they're synthetic -- calls to them are only emitted by the compiler, and in this case I was thinking (but didn't specify, sorry) of lambdalifted methods that become visible when they start to be used from an under-privileged scope
@retronym said:
One difference between Java and Scala that we have to consider is that we allow private access outside of the current compilation unit. So we have a few different scenarios wrt separate compilation. e.g. changing a member from public to private[pack] is currently binary compatible for call sites in that pack
. (Admittedly, it is also BC for call sites outside of the package, so we have no runtime enforcement of access.)
% qbin/scalac sandbox/{A,B}.scala
% qbin/scalac sandbox/A-pack-private.scala
% qbin/scala p.Test
% qbin/scala
scala> :javap -public p.C
Compiled from "A-pack-private.scala"
public class p.C extends java.lang.Object{
public int foo();
public p.C();
}
If we compiled foo
as private and provided an accessor, this would no longer be the case.
In addition, we would need to generate stable names for the accessors (rather than java's acesssNNN
). But this could be done easily enough in the same manner as the current mangling.
So perhaps we need to consider the scheme used for package-qualified access separately from other cases.
Another tricky aspect of Java's approach to access is constructors. It creates 'access constructors' with an extra dummy parameter. The type of the parameter was used to uniquely distinguish the constructors, and was chosen to be the type of the inner class that needed to access the constructor.
@adriaanm said: see also #6387
Guillaume Martres (Smarter) said: Was this closed intentionally?
@retronym said: Nope, I think I mentioned it in a commit comment and JIRA thought I fixed it.
when java needs to give access to an inaccessible method, it doesn't change the method itself, but generates a synthetic static accessor that takes the same arguments, plus the this pointer for that method
this scheme makes it easier to stay binary compatible in the presence of changing access patterns, because it doesn't involve making private, non-synthetic, methods public when the need arises for them to be accessible from somewhere
as the static accessor is synthetic, it doesn't affect binary compatibility
This might give us a chance at fixing:
which, as reported in #6387 (now marked as a duplicate), gives an
AbstractMethodError