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

Bad bridge methods for f-bound traits (?) #6414

Open
scabug opened this issue Sep 21, 2012 · 5 comments
Open

Bad bridge methods for f-bound traits (?) #6414

scabug opened this issue Sep 21, 2012 · 5 comments

Comments

@scabug
Copy link

scabug commented Sep 21, 2012

When using traits that are F-bounded:

trait A[This <: A[This]] {
  def copy(): This
  def a(): This = copy()
}

trait B[This <: B[This]] extends A[This] {
  def b(): This = copy()
}

class C extends A[C] with B[C] {
  def copy() = this
}

The bridge methods generated in C are:

// class version 49.0 (49)
// access flags 0x21
// signature Ljava/lang/Object;LA<LC;>;LB<LC;>;Lscala/ScalaObject;
// declaration: C implements A<C>, B<C>, scala.ScalaObject
public class C implements A B scala/ScalaObject  {


  @Lscala/reflect/ScalaSignature;(bytes="\u0006\u0001\u00052A!\u0001\u0002\u0001\u000b\u0009\u00091IC\u0001\u0004\u0003\u001daT-\u001c9usz\u001a\u0001aE\u0003\u0001\r9\u0019b\u0003\u0005\u0002\u0008\u00195\u0009\u0001B\u0003\u0002\n\u0015\u0005!A.\u00198h\u0015\u0005Y\u0011\u0001\u00026bm\u0006L!!\u0004\u0005\u0003\r=\u0013'.Z2u!\ry\u0001CE\u0007\u0002\u0005%\u0011\u0011C\u0001\u0002\u0002\u0003B\u0011q\u0002\u0001\u0009\u0004\u001fQ\u0011\u0012BA\u000b\u0003\u0005\u0005\u0011\u0005CA\u000c\u001b\u001b\u0005A\"\"A\r\u0002\u000bM\u001c\u0017\r\\1\n\u0005mA\"aC*dC2\u000cwJ\u00196fGRDQ!\u0008\u0001\u0005\u0002y\u0009a\u0001P5oSRtD#\u0001\n\u0009\u000b\u0001\u0002A\u0011\u0001\u0010\u0002\u0009\r|\u0007/\u001f")

  ATTRIBUTE ScalaSig : unknown

  // access flags 0x41
  public volatile bridge b()LB;
    ALOAD 0
    INVOKESTATIC B$class.b (LB;)LB;
    ARETURN
    MAXSTACK = 1
    MAXLOCALS = 1

  // access flags 0x41
  public volatile bridge a()LA;
    ALOAD 0
    INVOKESTATIC A$class.a (LA;)LA;
    ARETURN
    MAXSTACK = 1
    MAXLOCALS = 1

  // access flags 0x1
  public copy()LC;
    ALOAD 0
    ARETURN
    MAXSTACK = 1
    MAXLOCALS = 1

  // access flags 0x41
  public volatile bridge copy()LA;
    ALOAD 0
    INVOKEVIRTUAL C.copy ()LC;
    ARETURN
    MAXSTACK = 1
    MAXLOCALS = 1

  // access flags 0x1
  public <init>()V
    ALOAD 0
    INVOKESPECIAL java/lang/Object.<init> ()V
    ALOAD 0
    INVOKESTATIC A$class.$init$ (LA;)V
    ALOAD 0
    INVOKESTATIC B$class.$init$ (LB;)V
    RETURN
    MAXSTACK = 1
    MAXLOCALS = 1
}

Note that these are typed returning A and B objects instead of C. This makes it impossible to write, in Java:

class Foo {
  static {
    C c = new C();
    c = c.b().a();
  }
}

Though it works in Scala (I suspect due to ScalaSigs).

However, when a throwaway type parameter is introduced on each method:

trait A[This <: A[This]] {
  def copy(): This
  def a[SADPANDA](): This = copy()
}

trait B[This <: B[This]] extends A[This] {
  def b[SADPANDA](): This = copy()
}

class C extends A[C] with B[C] {
  def copy() = this
}

It works, I suspect due to the fact that this furnishes the bridges with java signatures:

// class version 49.0 (49)
// access flags 0x21
// signature Ljava/lang/Object;LA<LC;>;LB<LC;>;Lscala/ScalaObject;
// declaration: C implements A<C>, B<C>, scala.ScalaObject
public class C implements A B scala/ScalaObject  {


  @Lscala/reflect/ScalaSignature;(bytes="\u0006\u0001\u00052A!\u0001\u0002\u0001\u000b\u0009\u00091IC\u0001\u0004\u0003\u001daT-\u001c9usz\u001a\u0001aE\u0003\u0001\r9\u0019b\u0003\u0005\u0002\u0008\u00195\u0009\u0001B\u0003\u0002\n\u0015\u0005!A.\u00198h\u0015\u0005Y\u0011\u0001\u00026bm\u0006L!!\u0004\u0005\u0003\r=\u0013'.Z2u!\ry\u0001CE\u0007\u0002\u0005%\u0011\u0011C\u0001\u0002\u0002\u0003B\u0011q\u0002\u0001\u0009\u0004\u001fQ\u0011\u0012BA\u000b\u0003\u0005\u0005\u0011\u0005CA\u000c\u001b\u001b\u0005A\"\"A\r\u0002\u000bM\u001c\u0017\r\\1\n\u0005mA\"aC*dC2\u000cwJ\u00196fGRDQ!\u0008\u0001\u0005\u0002y\u0009a\u0001P5oSRtD#\u0001\n\u0009\u000b\u0001\u0002A\u0011\u0001\u0010\u0002\u0009\r|\u0007/\u001f")

  ATTRIBUTE ScalaSig : unknown

  // access flags 0x41
  // signature <SADPANDA:Ljava/lang/Object;>()LC;
  // declaration: C b<SADPANDA>()
  public volatile bridge b()LB;
    ALOAD 0
    INVOKESTATIC B$class.b (LB;)LB;
    ARETURN
    MAXSTACK = 1
    MAXLOCALS = 1

  // access flags 0x41
  // signature <SADPANDA:Ljava/lang/Object;>()LC;
  // declaration: C a<SADPANDA>()
  public volatile bridge a()LA;
    ALOAD 0
    INVOKESTATIC A$class.a (LA;)LA;
    ARETURN
    MAXSTACK = 1
    MAXLOCALS = 1

  // access flags 0x1
  public copy()LC;
    ALOAD 0
    ARETURN
    MAXSTACK = 1
    MAXLOCALS = 1

  // access flags 0x41
  public volatile bridge copy()LA;
    ALOAD 0
    INVOKEVIRTUAL C.copy ()LC;
    ARETURN
    MAXSTACK = 1
    MAXLOCALS = 1

  // access flags 0x1
  public <init>()V
    ALOAD 0
    INVOKESPECIAL java/lang/Object.<init> ()V
    ALOAD 0
    INVOKESTATIC A$class.$init$ (LA;)V
    ALOAD 0
    INVOKESTATIC B$class.$init$ (LB;)V
    RETURN
    MAXSTACK = 1
    MAXLOCALS = 1
}

Producing divergent java signatures, and so attempting to actually run the above code (which now compiles) results in a runtime error:

Exception in thread "main" java.lang.NoSuchMethodError: C.b()LC;
	at Foo.main(x.java:4)
@scabug
Copy link
Author

scabug commented Sep 21, 2012

Imported From: https://issues.scala-lang.org/browse/SI-6414?orig=1
Reporter: marius a. eriksen (mariusae)
Affected Versions: 2.9.1, 2.10.0-M7
See #3452

@scabug
Copy link
Author

scabug commented Sep 22, 2012

marius a. eriksen (mariusae) said:
This is x.java:

class Foo {
  public static void main(String[] args) {
    C c = new C();
    c = c.b().a();
  }
}

@scabug
Copy link
Author

scabug commented Sep 22, 2012

@paulp said:
This is a variation of #3452.

@SethTisue
Copy link
Member

closing stale backend tickets; comment/reopen if you have evidence this is still applicable

@lrytz
Copy link
Member

lrytz commented Mar 2, 2018

No more crash at least, both cases the java code no longer compiles.

@lrytz lrytz reopened this Mar 2, 2018
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

4 participants