Skip to content

Conversation

@soc
Copy link
Contributor

@soc soc commented Dec 2, 2011

Not sure if this is completely fixed, because the compiler complains much earlier,
but I guess it cannot hurt to have it in place and recognize it early when this
starts moving again.

Not sure if this is completely fixed, because the compiler complains much earlier,
but I guess it cannot hurt to have it in place and recognize it early when this
starts moving again.
@paulp paulp closed this Dec 2, 2011
heathermiller pushed a commit to heathermiller/scala that referenced this pull request Oct 11, 2012
retronym referenced this pull request in retronym/scala Jul 31, 2015
Calls to synthetic case class apply methods are inlined to the
underlying constructor invocation in refchecks.

However, this can lead to accessibility errors if the constructor
is private.

This commit ensures that the constructor is at least as accessible
as the apply method before performing this tranform.

I've manually checked that other the optimization still works in other
cases:

scala> class CaseApply { Some(42)  }
defined class CaseApply

    scala> :javap -c CaseApply
    Compiled from "<console>"
    public class CaseApply {
      public CaseApply();
        Code:
           0: aload_0
           1: invokespecial #9                  // Method java/lang/Object."<init>":()V
           4: new           #11                 // class scala/Some
           7: dup
           8: bipush        42
          10: invokestatic  #17                 // Method scala/runtime/BoxesRunTime.boxToInteger:(I)Ljava/lang/Integer;
          13: invokespecial #20                 // Method scala/Some."<init>":(Ljava/lang/Object;)V
          16: pop
          17: return
    }
retronym referenced this pull request in retronym/scala Jul 31, 2015
Calls to synthetic case class apply methods are inlined to the
underlying constructor invocation in refchecks.

However, this can lead to accessibility errors if the constructor
is private.

This commit ensures that the constructor is at least as accessible
as the apply method before performing this tranform.

I've manually checked that other the optimization still works in other
cases:

scala> class CaseApply { Some(42)  }
defined class CaseApply

    scala> :javap -c CaseApply
    Compiled from "<console>"
    public class CaseApply {
      public CaseApply();
        Code:
           0: aload_0
           1: invokespecial #9                  // Method java/lang/Object."<init>":()V
           4: new           #11                 // class scala/Some
           7: dup
           8: bipush        42
          10: invokestatic  #17                 // Method scala/runtime/BoxesRunTime.boxToInteger:(I)Ljava/lang/Integer;
          13: invokespecial #20                 // Method scala/Some."<init>":(Ljava/lang/Object;)V
          16: pop
          17: return
    }
lrytz pushed a commit to lrytz/scala that referenced this pull request May 20, 2016
And use this as the target of the default methods or
statically resolved super or $init calls.

The call-site change is predicated on `-Yuse-trait-statics`
as a stepping stone for experimentation / bootstrapping.

I have performed this transformation in the backend,
rather than trying to reflect this in the view from
Scala symbols + ASTs.

Once we commit to this change, we can remove the
`lateInterfaces` bookkeeping from the backend, as we no
long will need to add ancestor interfaces as direct
parents to allow use of invokespecial for super calls.

```
> ;scalac sandbox/test.scala ; scala Test

[info] Running scala.tools.nsc.MainGenericRunner -usejavacp Test
T
C
[success] Total time: 2 s, completed 04/05/2016 11:07:13 AM
> eval "javap -classpath . -c -private C".!!
[info] ans: String = Compiled from "test.scala"
[info] public class C implements T {
[info]   public C();
[info]     Code:
[info]        0: aload_0
[info]        1: invokespecial scala#14                 // Method java/lang/Object."<init>":()V
[info]        4: aload_0
[info]        5: invokespecial scala#17                 // Method T.$init$:()V
[info]        8: getstatic     scala#23                 // Field scala/Predef$.MODULE$:Lscala/Predef$;
[info]       11: ldc           scala#24                 // String C
[info]       13: invokevirtual scala#28                 // Method scala/Predef$.println:(Ljava/lang/Object;)V
[info]       16: aload_0
[info]       17: invokespecial scala#32                 // Method T.foo:()I
[info]       20: pop
[info]       21: return
[info] }
> ;scalac -Yuse-trait-statics sandbox/test.scala ; scala Test

[info] Running scala.tools.nsc.MainGenericRunner -usejavacp Test
T
C
[success] Total time: 2 s, completed 04/05/2016 11:07:39 AM
> eval "javap -classpath . -c -private C".!!
[info] ans: String = Compiled from "test.scala"
[info] public class C implements T {
[info]   public C();
[info]     Code:
[info]        0: aload_0
[info]        1: invokespecial scala#14                 // Method java/lang/Object."<init>":()V
[info]        4: aload_0
[info]        5: invokestatic  scala#18                 // Method T.$init$:(LT;)V
[info]        8: getstatic     scala#24                 // Field scala/Predef$.MODULE$:Lscala/Predef$;
[info]       11: ldc           scala#25                 // String C
[info]       13: invokevirtual scala#29                 // Method scala/Predef$.println:(Ljava/lang/Object;)V
[info]       16: aload_0
[info]       17: invokestatic  scala#33                 // Method T.foo:(LT;)I
[info]       20: pop
[info]       21: return
[info] }
> eval "javap -classpath . -c -private T".!!
[info] ans: String = Compiled from "test.scala"
[info] public interface T {
[info]   public static int foo(T);
[info]     Code:
[info]        0: iconst_0
[info]        1: ireturn
[info]
[info]   public int foo();
[info]     Code:
[info]        0: aload_0
[info]        1: invokestatic  scala#15                 // Method foo:(LT;)I
[info]        4: ireturn
[info]
[info]   public static void $init$(T);
[info]     Code:
[info]        0: getstatic     scala#24                 // Field scala/Predef$.MODULE$:Lscala/Predef$;
[info]        3: ldc           scala#25                 // String T
[info]        5: invokevirtual scala#29                 // Method scala/Predef$.println:(Ljava/lang/Object;)V
[info]        8: return
[info]
[info]   public void $init$();
[info]     Code:
[info]        0: aload_0
[info]        1: invokestatic  scala#32                 // Method $init$:(LT;)V
[info]        4: return
[info] }
```
lrytz pushed a commit to lrytz/scala that referenced this pull request May 25, 2016
And use this as the target of the default methods or
statically resolved super or $init calls.

The call-site change is predicated on `-Yuse-trait-statics`
as a stepping stone for experimentation / bootstrapping.

I have performed this transformation in the backend,
rather than trying to reflect this in the view from
Scala symbols + ASTs.

Once we commit to this change, we can remove the
`lateInterfaces` bookkeeping from the backend, as we no
long will need to add ancestor interfaces as direct
parents to allow use of invokespecial for super calls.

```
> ;scalac sandbox/test.scala ; scala Test

[info] Running scala.tools.nsc.MainGenericRunner -usejavacp Test
T
C
[success] Total time: 2 s, completed 04/05/2016 11:07:13 AM
> eval "javap -classpath . -c -private C".!!
[info] ans: String = Compiled from "test.scala"
[info] public class C implements T {
[info]   public C();
[info]     Code:
[info]        0: aload_0
[info]        1: invokespecial scala#14                 // Method java/lang/Object."<init>":()V
[info]        4: aload_0
[info]        5: invokespecial scala#17                 // Method T.$init$:()V
[info]        8: getstatic     scala#23                 // Field scala/Predef$.MODULE$:Lscala/Predef$;
[info]       11: ldc           scala#24                 // String C
[info]       13: invokevirtual scala#28                 // Method scala/Predef$.println:(Ljava/lang/Object;)V
[info]       16: aload_0
[info]       17: invokespecial scala#32                 // Method T.foo:()I
[info]       20: pop
[info]       21: return
[info] }
> ;scalac -Yuse-trait-statics sandbox/test.scala ; scala Test

[info] Running scala.tools.nsc.MainGenericRunner -usejavacp Test
T
C
[success] Total time: 2 s, completed 04/05/2016 11:07:39 AM
> eval "javap -classpath . -c -private C".!!
[info] ans: String = Compiled from "test.scala"
[info] public class C implements T {
[info]   public C();
[info]     Code:
[info]        0: aload_0
[info]        1: invokespecial scala#14                 // Method java/lang/Object."<init>":()V
[info]        4: aload_0
[info]        5: invokestatic  scala#18                 // Method T.$init$:(LT;)V
[info]        8: getstatic     scala#24                 // Field scala/Predef$.MODULE$:Lscala/Predef$;
[info]       11: ldc           scala#25                 // String C
[info]       13: invokevirtual scala#29                 // Method scala/Predef$.println:(Ljava/lang/Object;)V
[info]       16: aload_0
[info]       17: invokestatic  scala#33                 // Method T.foo:(LT;)I
[info]       20: pop
[info]       21: return
[info] }
> eval "javap -classpath . -c -private T".!!
[info] ans: String = Compiled from "test.scala"
[info] public interface T {
[info]   public static int foo(T);
[info]     Code:
[info]        0: iconst_0
[info]        1: ireturn
[info]
[info]   public int foo();
[info]     Code:
[info]        0: aload_0
[info]        1: invokestatic  scala#15                 // Method foo:(LT;)I
[info]        4: ireturn
[info]
[info]   public static void $init$(T);
[info]     Code:
[info]        0: getstatic     scala#24                 // Field scala/Predef$.MODULE$:Lscala/Predef$;
[info]        3: ldc           scala#25                 // String T
[info]        5: invokevirtual scala#29                 // Method scala/Predef$.println:(Ljava/lang/Object;)V
[info]        8: return
[info]
[info]   public void $init$();
[info]     Code:
[info]        0: aload_0
[info]        1: invokestatic  scala#32                 // Method $init$:(LT;)V
[info]        4: return
[info] }
```
lrytz pushed a commit to lrytz/scala that referenced this pull request Jun 6, 2016
And use this as the target of the default methods or
statically resolved super or $init calls.

The call-site change is predicated on `-Yuse-trait-statics`
as a stepping stone for experimentation / bootstrapping.

I have performed this transformation in the backend,
rather than trying to reflect this in the view from
Scala symbols + ASTs.

```
> ;scalac sandbox/test.scala ; scala Test

[info] Running scala.tools.nsc.MainGenericRunner -usejavacp Test
T
C
[success] Total time: 2 s, completed 04/05/2016 11:07:13 AM
> eval "javap -classpath . -c -private C".!!
[info] ans: String = Compiled from "test.scala"
[info] public class C implements T {
[info]   public C();
[info]     Code:
[info]        0: aload_0
[info]        1: invokespecial scala#14                 // Method java/lang/Object."<init>":()V
[info]        4: aload_0
[info]        5: invokespecial scala#17                 // Method T.$init$:()V
[info]        8: getstatic     scala#23                 // Field scala/Predef$.MODULE$:Lscala/Predef$;
[info]       11: ldc           scala#24                 // String C
[info]       13: invokevirtual scala#28                 // Method scala/Predef$.println:(Ljava/lang/Object;)V
[info]       16: aload_0
[info]       17: invokespecial scala#32                 // Method T.foo:()I
[info]       20: pop
[info]       21: return
[info] }
> ;scalac -Yuse-trait-statics sandbox/test.scala ; scala Test

[info] Running scala.tools.nsc.MainGenericRunner -usejavacp Test
T
C
[success] Total time: 2 s, completed 04/05/2016 11:07:39 AM
> eval "javap -classpath . -c -private C".!!
[info] ans: String = Compiled from "test.scala"
[info] public class C implements T {
[info]   public C();
[info]     Code:
[info]        0: aload_0
[info]        1: invokespecial scala#14                 // Method java/lang/Object."<init>":()V
[info]        4: aload_0
[info]        5: invokestatic  scala#18                 // Method T.$init$:(LT;)V
[info]        8: getstatic     scala#24                 // Field scala/Predef$.MODULE$:Lscala/Predef$;
[info]       11: ldc           scala#25                 // String C
[info]       13: invokevirtual scala#29                 // Method scala/Predef$.println:(Ljava/lang/Object;)V
[info]       16: aload_0
[info]       17: invokestatic  scala#33                 // Method T.foo:(LT;)I
[info]       20: pop
[info]       21: return
[info] }
> eval "javap -classpath . -c -private T".!!
[info] ans: String = Compiled from "test.scala"
[info] public interface T {
[info]   public static int foo(T);
[info]     Code:
[info]        0: iconst_0
[info]        1: ireturn
[info]
[info]   public int foo();
[info]     Code:
[info]        0: aload_0
[info]        1: invokestatic  scala#15                 // Method foo:(LT;)I
[info]        4: ireturn
[info]
[info]   public static void $init$(T);
[info]     Code:
[info]        0: getstatic     scala#24                 // Field scala/Predef$.MODULE$:Lscala/Predef$;
[info]        3: ldc           scala#25                 // String T
[info]        5: invokevirtual scala#29                 // Method scala/Predef$.println:(Ljava/lang/Object;)V
[info]        8: return
[info]
[info] }
```
OlivierBlanvillain pushed a commit to OlivierBlanvillain/scala that referenced this pull request Jun 27, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants