在嵌套在对象中的trait中混合时的AbstractMethodError - 仅在编译和导入时 [英] AbstractMethodError when mixing in trait nested in object - only when compiled and imported

查看:92
本文介绍了在嵌套在对象中的trait中混合时的AbstractMethodError - 仅在编译和导入时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑以下代码:

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

When I paste the above code in the REPL, or run it in a worksheet, and then try the expression -- no problem, it prints res0: Int = 1, as expected.

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

When I put the code in a file, compile it with scalac, and then use the compiled class files from the REPL in the same directory, I get the same result.

然而,当我使用编译的文件,然后从REPL说

However, when I use the compiled files, and then say from the REPL

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

它抛出

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

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

If I paste all code in the REPL, and use the import variant, this does not happen.

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

What is happening here? Is this even expected behaviour? If relevant, I am using

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$1.foo()I
  ... 33 elided

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

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

It doesn't have a foo with result type Int.

副手,我无法想象REPL的差异,但我们即将看电影......不过你可以在Ammonite中尝试。

Offhand, I can't imagine the difference in the REPL, but we're about to watch a movie... You can try it in Ammonite, however.

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

Most such bugs are due to the fact that REPL is a resident compiler, but it's not obvious how that affects compilation with existing class files.

编辑:

它第一次使用完全限定名称,但在出现失败后,完全合格的失败了。

It works the first time using fully-qualified names, but then after exhibiting the failure, fully-qualified fails again.

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$1.foo()I
  ... 33 elided

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

这显然是常驻编译器错误。 (这里的类在包中。)

That's clearly a resident compiler bug. (The classes are in package p here.)

编辑:实际上 SI-9689

这篇关于在嵌套在对象中的trait中混合时的AbstractMethodError - 仅在编译和导入时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆