scala / bug

Scala 2 bug reports only. Please, no questions — proper bug reports only.
https://scala-lang.org
232 stars 21 forks source link

AbstractMethodError when base class method overloads generic method from trait #8681

Open scabug opened 10 years ago

scabug commented 10 years ago

Repro steps:

Welcome to Scala version 2.10.3 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_25).
Type in expressions to have them evaluated.
Type :help for more information.

scala> :paste
// Entering paste mode (ctrl-D to finish)

trait SimpleTrait[T] {
  def myMethod(t: T): Int
  def doIt(t: T): Unit = {
    myMethod(t)
 }
}

abstract class SimpleClass[T] extends SimpleTrait[T] {
  def myMethod(t: String): Int = 5
}

class BadClass extends SimpleClass[String]

(new BadClass).doIt("foobar")

// Exiting paste mode, now interpreting.

java.lang.AbstractMethodError: BadClass.myMethod(Ljava/lang/Object;)I
    at SimpleTrait$class.doIt(<console>:13)
    at SimpleClass.doIt(<console>:17)
...
scabug commented 10 years ago

Imported From: https://issues.scala-lang.org/browse/SI-8681?orig=1 Reporter: Jason Liszka (jliszka) Affected Versions: 2.10.3, 2.11.1

scabug commented 10 years ago

@retronym said (edited on Jun 26, 2014 7:58:07 AM UTC): The analagous Java code compiles and runs successfully. Crucially, a bridge method is added to BadClass.

public class Test {
    interface SimpleTrait<T> {
      int myMethod(T t);
      default void doIt(T t) {
        myMethod(t);
      }
    }

    static abstract class SimpleClass<T> implements SimpleTrait<T> {
      public int myMethod(String t) { return 5; }
    }

    static class BadClass extends SimpleClass<String> {}

    public static void main(String... args) {
        new BadClass().doIt("");
    }
}
% javap -v -classpath . 'Test$BadClass'
...
  public int myMethod(java.lang.Object);
    descriptor: (Ljava/lang/Object;)I
    flags: ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
    Code:
      stack=2, locals=2, args_size=2
         0: aload_0
         1: aload_1
         2: checkcast     #2                  // class java/lang/String
         5: invokespecial #3                  // Method Test$SimpleClass.myMethod:(Ljava/lang/String;)I
         8: ireturn
      LineNumberTable:
        line 13: 0
SethTisue commented 6 years ago

same in 2.12.4

SethTisue commented 3 years ago

Not fixed in Scala 2.13.5, and not fixed in Scala 3.0.0-RC1 either.

joroKr21 commented 3 years ago

Possibly related to #12209 and lampepfl/dotty#10079 see for another case where variance causes confusion of this kind. I think it's a conceptual problem - we check for overriding pairs on method definition but both this and the ticket I linked show that we may have to do it also in subclasses. But I can't tell if that is practical.