Skip to content
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

separate accessibility and lifting #7085

Open
scabug opened this issue Feb 6, 2013 · 7 comments
Open

separate accessibility and lifting #7085

scabug opened this issue Feb 6, 2013 · 7 comments
Milestone

Comments

@scabug
Copy link

scabug commented Feb 6, 2013

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:

trait A {
  def foo: Long
}
 
object Main {
  def a(): A = new A {
    var foo: Long = 1000L
 
    val test = () => {
      foo = 28
    }
  }
  def main(args: Array[String]) {
    println(a().foo)
  }
}

which, as reported in #6387 (now marked as a duplicate), gives an AbstractMethodError

@scabug
Copy link
Author

scabug commented Feb 6, 2013

@scabug
Copy link
Author

scabug commented Feb 6, 2013

@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.

@scabug
Copy link
Author

scabug commented Feb 6, 2013

@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

@scabug
Copy link
Author

scabug commented Sep 23, 2013

@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.

@scabug
Copy link
Author

scabug commented Dec 6, 2013

@adriaanm said:
see also #6387

@scabug
Copy link
Author

scabug commented May 7, 2015

Guillaume Martres (Smarter) said:
Was this closed intentionally?

@scabug
Copy link
Author

scabug commented May 8, 2015

@retronym said:
Nope, I think I mentioned it in a commit comment and JIRA thought I fixed it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants