rsc icon indicating copy to clipboard operation
rsc copied to clipboard

Super accessors

Open xeno-by opened this issue 7 years ago • 4 comments

Scalac has an obscure feature that synthesizes methods, called super accessors, to bridge certain super calls, e.g.

trait T1 {
  def x: Int = ???
}

trait T2 extends T1 {
  def y: Int = super.x
}
13:31 ~/Projects/2126/sandbox (HEAD)$ s -Xprint:refchecks
[[syntax trees at end of                 refchecks]] // Test.scala
package <empty> {
  abstract trait T1 extends scala.AnyRef {
    def /*T1*/$init$(): Unit = {
      ()
    };
    def x: Int = scala.Predef.???
  };
  abstract trait T2 extends AnyRef with T1 {
    <superaccessor> <artifact> private def super$x: Int;
    def /*T2*/$init$(): Unit = {
      ()
    };
    def y: Int = T2.this.super$x
  }
}

At the moment, mjar can't generate super accessors because they aren't present in SemanticDB and can't be inferred from SemanticDB contents alone. In the future, we may be able to solve this problem via https://github.com/scalameta/scalameta/issues/1648.

xeno-by avatar Jul 07 '18 02:07 xeno-by

As mentioned in https://github.com/scalameta/scalameta/issues/1648, super accessors not only involve super$ methods, but sometimes they also give rise to protected$ methods. I don't fully understand why these methods are created, but figured I'd make a note here anyway.

xeno-by avatar Nov 23 '18 19:11 xeno-by

trait T1 {
  def x: Int = ???
}

trait T2 extends T1 {
  def y: Int = super.x
}
class C extends T2
--- expected
+++ actual
diff --git a/C.class.asm b/C.class.asm
index e42d81e..5ab4b5f 100644
--- a/C.class.asm
+++ b/C.class.asm
@@ -15,14 +15,6 @@
     MAXSTACK = 1
     MAXLOCALS = 1

-  // access flags 0x1001
-  public synthetic T2$$super$x()I
-    ALOAD 0
-    INVOKESTATIC T1$class.x (LT1;)I
-    IRETURN
-    MAXSTACK = 1
-    MAXLOCALS = 1
-
   // access flags 0x1
   public x()I
     ALOAD 0

xeno-by avatar Jan 13 '19 22:01 xeno-by

I've scratched the immediate itch in https://github.com/twitter/rsc/pull/326 by implementing a workaround to nudge Rsc into generating super accessors. This workaround requires users to modify their code, so it doesn't count as a proper fix, but at least now we don't have to fix this ticket right away (which is pretty tricky due to the reasons outlined in the PR).

xeno-by avatar Jan 19 '19 06:01 xeno-by

For reference, the pretty-printed scalasigs which would be required:

  symbols {
    tag: VALsym
    id: <empty>.#T2#super$x().
    flags: PRIVATE | METHOD | SUPERACCESSOR | ARTIFACT
    info {
      tag: POLYtpe
      tpe {
        tag: TYPEREFtpe
        pre {
          tag: THIStpe
          sym: scala.#
        }
        sym: scala.#Int#
      }
    }
    alias: <empty>.#T1#x.
  }

wiwa avatar Jul 31 '19 21:07 wiwa