AbstractMethodError 混入嵌套在对象中的特征时 - 仅在编译和导入时

AbstractMethodError when mixing in trait nested in object - only when compiled and imported

考虑以下代码:

object Impls {
  trait ConcreteImpl {
    type Foo = Int
    def foo = 1
  }
}

trait Base {
  type Foo
  def foo: Foo
}

我对表达式感兴趣

(new Base with Impls.ConcreteImpl).foo

当我将上面的代码粘贴到 REPL 中,或将其 运行 粘贴到工作表中,然后尝试表达式时——没问题,它会按预期打印 res0: Int = 1

当我把代码放在一个文件中,用 scalac 编译它,然后在同一目录中使用 REPL 中编译的 class 文件时,我得到了相同的结果。

但是,当我使用编译文件的时候,再说从REPL

import Impls._
(new Base with ConcreteImpl).foo

它抛出

java.lang.AbstractMethodError: $anon.foo()I

如果我将所有代码粘贴到 REPL 中,并使用导入变体,不会 发生这种情况。

这里发生了什么?这甚至是预期的行为吗?如果相关,我正在使用

Scala version 2.11.5 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_45)

这显然是一个错误。

如果你:

java.lang.AbstractMethodError: $line13.$read$$iw$$iw$$iw$$iw$$iw$$iw$$anon.foo()I
  ... 33 elided

scala> :javap -p $line13.$read$$iw$$iw$$iw$$iw$$iw$$iw$$anon
Compiled from "<console>"
public final class $line13.$read$$iw$$iw$$iw$$iw$$iw$$iw$$anon implements p.Base,p.Impls$ConcreteImpl {
  public java.lang.Object foo();
  public $line13.$read$$iw$$iw$$iw$$iw$$iw$$iw$$anon();
}

它没有结果类型为 Int 的 foo。

顺便说一句,我无法想象 REPL 中的差异,但我们正要看电影...不过,您可以在 Ammonite 中尝试一下。

大多数此类错误是由于 REPL 是常驻编译器这一事实造成的,但这对现有 class 文件的编译有何影响并不明显。

编辑:

它第一次使用完全限定名称时有效,但在显示失败后,完全限定名称再次失败。

scala> (new p.Base with p.Impls.ConcreteImpl).foo // show
//works
res0: Int = 1

scala> import p._
import p._

scala> import Impls._
import Impls._

scala> (new Base with ConcreteImpl).foo // show
// fails
java.lang.AbstractMethodError: $anon.foo()I
  ... 33 elided

scala> (new p.Base with p.Impls.ConcreteImpl).foo // show
// also fails
java.lang.AbstractMethodError: $anon.foo()I
  ... 33 elided

这显然是一个常驻编译器错误。 (classes 在此处的包 p 中。)

编辑:实际上 SI-9689