Scala 2.11.5类型别名和清单的编译器崩溃 [英] Scala 2.11.5 compiler crash with type aliases and manifests

查看:273
本文介绍了Scala 2.11.5类型别名和清单的编译器崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

看起来,将一个别名加入到一个疯狂的参数化类型中,试图为这个类型获取隐式的 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?
编译时:< console>
阶段:globalPhase =擦除,进入阶段=后期改变
库版本:版本2.11.5
编译器版本:版本2.11.5
重构参数:

最后树到typer:输入$ iw
树位置:< console>的第9行
tree tpe:< notype>
symbol:object $ iw
符号定义:class $ iw extends Object(a ModuleClassSymbol)
符号包:$ line10
符号所有者:object $ iw - > object $ iw - > object $ read
call site:object $ iw in package $ line10

有几种情况为这次崩溃。类型 C 必须参数化。别名必须使用通配符( C [_] )。这个调用必须使用一个类型别名,只需调用 f [C [_]] 就可以正常工作。



程序的情况要复杂得多,我发现的唯一解决方案是让方法不接受 Manifest ,但只需要一个 Class 参数代替,这是丑陋的。



我做错了什么?任何建议更好的解决方法?我没有在Scala bug跟踪器中看到一个bug,所以如果这看起来合法,我会继续并报告它。

解决方案

使用 scala.reflect.runtime.universe.TypeTag (或 scala.reflect.ClassTag 因为你提到了 Class 作为选项,它可能是)而不是 Manifest 。它们以编译器的隐含参数插入,与 Manifest s相同。请参阅 http://docs.scala-lang.org/overviews/reflection/ typetags-manifests.html 以获取更多信息。在Scala 2.10中,不推荐使用scala.reflect.ClassManifests,并且计划在scala.reflect.Manifest中弃用scala.reflect.Manifest。在即将到来的发布版本中支持TypeTags和ClassTag。

您应该仍然可以报告错误;即使它被标记为无法修复,它也会帮助那些在未来遇到此问题的人。


It appears that passing an alias to a wild-carded parameterized type to a function that tries to get an implicit Manifest for the type will crash the Scala 2.11.5 compiler.

The following can be pasted in the 2.11.5 REPL to reproduce the crash:

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

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

The crash output is very verbose, but contains this info:

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

There are several conditions for this crash. The type C must be parameterized. The alias must use a wildcard (C[_]). The call must use a type alias, just calling f[C[_]] works fine.

In my program the case is far more complex, and the only solution I've found is to have the method not accept a Manifest, but just take a Class parameter instead, which is ugly.

Am I doing something wrong? Any suggestions for better workaround? I didn't see a bug in the Scala bug tracker, so if this seems legit, I'll go ahead and report it.

解决方案

Use scala.reflect.runtime.universe.TypeTag (or scala.reflect.ClassTag if it's sufficient; since you mention taking Class as an option, it may be) instead of Manifest. They are inserted as implicit arguments by the compiler in the same way as Manifests are. See http://docs.scala-lang.org/overviews/reflection/typetags-manifests.html for more. In particular, note

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.

You probably should still report the bug; even if it's marked as wont-fix, it'll help people who stumble over this in the future.

这篇关于Scala 2.11.5类型别名和清单的编译器崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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