Scala 2.11.5 编译器因类型别名和清单而崩溃

Scala 2.11.5 compiler crash with type aliases and manifests

似乎将通配符参数化类型的别名传递给试图为该类型获取隐式 Manifest 的函数会使 Scala 2.11.5 编译器崩溃。

可以将以下内容粘贴到 2.11.5 REPL 中以重现崩溃:

class C[T]
def f[T](implicit m: Manifest[T]) = 0

type CAlias = C[_]
val x = f[CAlias]

崩溃输出非常详细,但包含以下信息:

scala.reflect.internal.FatalError:
  ?MethodType?
     while compiling: <console>
        during phase: globalPhase=erasure, enteringPhase=posterasure
     library version: version 2.11.5
    compiler version: version 2.11.5
  reconstructed args:

  last tree to typer: type $iw
       tree position: line 9 of <console>
            tree tpe: <notype>
              symbol: object $iw
   symbol definition: class $iw extends Object (a ModuleClassSymbol)
      symbol package: $line10
       symbol owners: object $iw -> object $iw -> object $read
           call site: object $iw in package $line10

这次崩溃有几个条件。类型 C 必须参数化。别名必须使用通配符 (C[_])。该调用必须使用类型别名,只需调用 f[C[_]] 即可。

在我的程序中,情况要复杂得多,我找到的唯一解决方案是让该方法不接受 Manifest,而只接受 Class 参数,这很丑

我是不是做错了什么?有更好的解决方法的建议吗?我没有在 Scala 错误跟踪器中看到错误,所以如果这看起来合理,我会继续报告它。

使用 scala.reflect.runtime.universe.TypeTag(或 scala.reflect.ClassTag,如果足够;既然你提到将 Class 作为一个选项,它可能是)而不是 Manifest。编译器将它们作为隐式参数以与 Manifests 相同的方式插入。有关更多信息,请参阅 http://docs.scala-lang.org/overviews/reflection/typetags-manifests.html。特别注意

In Scala 2.10, scala.reflect.ClassManifests are deprecated, and it is planned to deprecate scala.reflect.Manifest in favor of TypeTags and ClassTags in an upcoming point release.

您可能仍然应该报告该错误;即使它被标记为不会修复,它也会帮助以后遇到这个问题的人。