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?
编译时:< 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 Manifest
s 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屋!