bug icon indicating copy to clipboard operation
bug copied to clipboard

Mixin forwarders can illegally access package-private methods

Open lrytz opened this issue 4 years ago • 2 comments

package p

package u {
  trait T {
    private[u] def f = 1
  }
}

package v {
  class C extends u.T
}

generates, after mixin:

[[syntax trees at end of                     mixin]] // Test.scala
package p {
  ...
  package v {
    class C extends Object with p.u.T {
      private[u] def f(): Int = C.super.f();

private[u] is wrong (u is not in scope), and C.super.f is an illegal access. So this code should be rejected.

This doesn't result in invalid bytecode, everything will be public anyway.

lrytz avatar Sep 09 '21 07:09 lrytz

In fact, enforcing this would be wrong, we don't want to disallow extending T outside u just because it has a private[u] member.

In bytecode, the mixin method in C actually calls the compiler-generated static method T.f$ (invokestatic, no invokespecial to the private[u] method in T).

So this the issue here is purely cosmetic

  • the mixin forwarder should be public (private[u] is weird as u is not in scope)
  • we cannot really create a better AST than C.super.f(), because the static f$ method is only created during code generation, there's no symbol for it

lrytz avatar Sep 09 '21 13:09 lrytz

In bytecode, the mixin method in C actually calls the compiler-generated static method T.f$ (invokestatic, no invokespecial to the private[u] method in T).

Can we make private[u] def f() public directly? I have tried it, and It seems wrong when emitting. 😄

jxnu-liguobin avatar Sep 23 '22 14:09 jxnu-liguobin