Scala Programming Language
  1. Scala Programming Language
  2. SI-6443

AbstractMethodError with dependent method types and generics

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Critical Critical
    • Resolution: Fixed
    • Affects Version/s: Scala 2.10.0-M7
    • Fix Version/s: Scala 2.10.1
    • Component/s: Compiler Backend
    • Environment:

      Linux 3.2.0-23-generic #36-Ubuntu SMP Tue Apr 10 20:39:51 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux
      OpenJDK Runtime Environment (IcedTea6 1.11.4) (6b24-1.11.4-1ubuntu0.12.04.1)
      OpenJDK 64-Bit Server VM (build 20.0-b12, mixed mode)

      Description

      object Test extends App {
        trait A {
          type D <: C
          def foo(d: D)(x: X[d.type]): Unit
          trait C { this: D =>
            def bar(x: X[D]): Unit = foo(this)(x)
          }
          class X[-F <: D]
        }
        class B extends A {
          def foo(d: D)(x: X[d.type]): Unit = ()
          class D() extends C
          new D().bar(new X[D])
        }
        new B
      }
      

      produces the following at runtime:

      java.lang.AbstractMethodError: Test$B.foo(LTest$A$C;LTest$A$X;)V
              at Test$A$C$class.bar(forms.scala:6)
              at Test$B$D.bar(forms.scala:13)
              at Test$B.<init>(forms.scala:14)
              at Test$.<init>(forms.scala:16)
              at Test$.<clinit>(forms.scala)
              at Test.main(forms.scala)
              at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
              at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
              at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
              at java.lang.reflect.Method.invoke(Method.java:616)
              at scala.tools.nsc.util.ScalaClassLoader$$anonfun$run$1.apply(ScalaClassLoader.scala:71)
              at scala.tools.nsc.util.ScalaClassLoader$class.asContext(ScalaClassLoader.scala:31)
              at scala.tools.nsc.util.ScalaClassLoader$URLClassLoader.asContext(ScalaClassLoader.scala:139)
              at scala.tools.nsc.util.ScalaClassLoader$class.run(ScalaClassLoader.scala:71)
              at scala.tools.nsc.util.ScalaClassLoader$URLClassLoader.run(ScalaClassLoader.scala:139)
              at scala.tools.nsc.CommonRunner$class.run(ObjectRunner.scala:28)
              at scala.tools.nsc.ObjectRunner$.run(ObjectRunner.scala:45)
              at scala.tools.nsc.CommonRunner$class.runAndCatch(ObjectRunner.scala:35)
              at scala.tools.nsc.ObjectRunner$.runAndCatch(ObjectRunner.scala:45)
              at scala.tools.nsc.MainGenericRunner.runTarget$1(MainGenericRunner.scala:74)
              at scala.tools.nsc.MainGenericRunner.process(MainGenericRunner.scala:96)
              at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:105)
              at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)
      

      This is probably a duplicate of, or at least related to, https://issues.scala-lang.org/browse/SI-6135.

        Issue Links

          Activity

          Hide
          Jason Zaugg added a comment -

          Reduced a little:

          trait A {
            type D >: Null <: C
            def foo(d: D)(d2: d.type): Unit
            trait C {
              def bar: Unit = foo(null)(null)
            }
          }
          object B extends A {
            class D extends C
          
            def foo(d: D)(d2: d.type): Unit = ()
          }
          
          object Test extends App {
            new B.D().bar
          }
          
          scala> :javap -private A
          Compiled from "t6443.scala"
          public interface A{
              public abstract void foo(A$C, A$C);
          }
          
          
          scala> :javap -private B$
          Compiled from "t6443.scala"
          public final class B$ extends java.lang.Object implements A{
              public static final B$ MODULE$;
              public static {};
              public void foo(B$D, B$D);
              private B$();
          }
          

          We're missing a bridge method in B$ with the signature public void foo(A$C, A$C).

          Show
          Jason Zaugg added a comment - Reduced a little: trait A { type D >: Null <: C def foo(d: D)(d2: d.type): Unit trait C { def bar: Unit = foo(null)(null) } } object B extends A { class D extends C def foo(d: D)(d2: d.type): Unit = () } object Test extends App { new B.D().bar } scala> :javap -private A Compiled from "t6443.scala" public interface A{ public abstract void foo(A$C, A$C); } scala> :javap -private B$ Compiled from "t6443.scala" public final class B$ extends java.lang.Object implements A{ public static final B$ MODULE$; public static {}; public void foo(B$D, B$D); private B$(); } We're missing a bridge method in B$ with the signature public void foo(A$C, A$C) .
          Show
          Jason Zaugg added a comment - https://github.com/scala/scala/pull/1696
          Show
          Jason Zaugg added a comment - https://github.com/scala/scala/pull/1857

            People

            • Assignee:
              Jason Zaugg
              Reporter:
              Jon Pretty
            • Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Development