无法覆盖具有非易失性上限的类型 [英] Cannot override a type with non-volatile upper bound
问题描述
我在 Scala 中有一个编译器错误,我不知道它指的是什么:
假设这些声明:
I have a compiler error in scala and I don't know what does it refer to:
Assume these declarations:
trait Abstract {
type MyType
}
trait AInner
trait A extends Abstract{
type MyType <: AInner
}
trait BInner {
def bMethod : Int
}
trait B extends Abstract with A{
override type MyType <: BInner with A#MyType
}
我在这里试图实现的(在特征 B
中)是进一步限制在 Abstract
中声明的类型 MyType
,因此任何类型的值MyType
必须扩展 mixin 树中的所有 MyType
.
编译器给了我这个消息(如标题所示):type MyType 是一个 volatile 类型;不能覆盖具有非易失性上限的类型.我明白,类型波动在这里发生是因为类型结合with A#MyType
,错误的一部分:type with non-volatile upper bound 可能是指类型声明 type MyType <: AInner
,其中 AInner
不是抽象类型,因此是非易失性的.
What I'm trying to achieve here(in trait B
) is to further restrict the type MyType
declared in Abstract
, so any value of type MyType
must extend all the MyType
s in the mixin tree.
The compiler is giving me this message(as in title):
type MyType is a volatile type; cannot override a type with non-volatile upper bound. I understand, that type volatility is happening here because of type conjuction with A#MyType
, the part of the error: type with non-volatile upper bound probably refers to the type declaration type MyType <: AInner
, where AInner
is not an abstract type thus non-volatile.
推荐答案
在编译器中移除这个检查让我们发现不健全的可能性.
Removing this check in the compiler lets us shine a light on the potential for unsoundness.
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 37a7e3c..78a8959 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -5128,8 +5128,7 @@ trait Typers extends Adaptations with Tags {
def typedSelectFromTypeTree(tree: SelectFromTypeTree) = {
val qual1 = typedType(tree.qualifier, mode)
- if (qual1.tpe.isVolatile) TypeSelectionFromVolatileTypeError(tree, qual1)
- else typedSelect(tree, qual1, tree.name)
+ typedSelect(tree, qual1, tree.name)
}
def typedTypeBoundsTree(tree: TypeBoundsTree) = {
然后,从编译器测试用例中运行代码,以进行 volatile 类型的非法类型选择:
Then, running the code from a compiler test case for illegal type selection for volatile types:
scala> class A; class B extends A
defined class A
defined class B
scala> trait C {
| type U
| trait D { type T >: B <: A }
| val y: (D with U)#T = new B
| }
defined trait C
scala> class D extends C {
| trait E
| trait F { type T = E }
| type U = F
| def frob(arg : E) : E = arg
| frob(y)
| }
defined class D
scala> new D
java.lang.ClassCastException: B cannot be cast to D$E
据我所知,问题源于 Scala 没有真正的交集类型.
As I understand it, the issue stems from the fact that Scala doesn't have true intersection types.
scala> type A = { type T = Int }
defined type alias A
scala> type B = { type T = String }
defined type alias B
scala> "": (A with B)#T
res16: String = ""
scala> 0: (A with B)#T
<console>:37: error: type mismatch;
found : Int(0)
required: String
0: (A with B)#T
^
如果对相关对象类型 (DOT) 的研究结果可行,这在未来可能会发生变化水果.
This might change in the future, if the research into Dependent Object Types (DOT) bears fruit.
这篇关于无法覆盖具有非易失性上限的类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!