在scala3中类型投影仍然不健全吗?



Scala3已经放弃了一般类型投影,因为它不可靠:
编译运行时失败的代码是可能的。

(问题经过编辑以反映评论)

考虑以下scala3代码:scastie

class A:
class X:
def outer : A.this.type = A.this

class B extends A
class C extends A
val b0 = new B
val b1 = b0
val b2 = new B
val c0 = new C
val c1 = c0
val c2 = new C
val b0x : A#X = new b0.X
val pathTypeMatch = b0x match
case _ : c2.X => "c2.X"
case _ : c1.X => "c1.x"
case _ : c0.X => "c0.X"
case _ : b2.X => "b2.X"
case _ : b1.X => "b1.X"
case _ : b0.X => "b0.X"
case _        => "ELSE"
pathTypeMatch // "b1.x" 
val projectionTypeMatch = b0x match
case _ : C#X => "C#X"
case _ : B#X => "B#X"
case _ : A#X => "A#X"
case _       => "ELSE"
projectionTypeMatch // "C#X" !!!
val failingTypeMatch = b0x match
case cx : C#X =>
val c : C = cx.outer // Fails at runtime

代码可以编译,但在运行时失败,因为"类B"不能强制转换为"类c"。

编译器认为C#XB#X擦除为A#X,因此case cx:C#X分支匹配。从这里,可以合理地认为cx.outerC(这是错误的),因此出现了例外。

未发出警告。不涉及TypeTest。

当查看projectionTypeMatch的字节码时,所有3个分支的测试都是严格相同的。

在type-patterns:

(类型模式T是…)对类Cp.CT#C的引用。此类型模式匹配给定类的任何非空实例。注意,类的前缀(如果存在)与确定类实例。

实际上,当对路径依赖类型进行匹配时,行为是预期的(pathTypeMatchb1.x)。特别是,编译器必须在匹配中考虑X outer。

对于投影类型的匹配应该是一致的,不是吗?

目的是什么?

似乎在scala3中将类型投射限制为具体类型将允许一致的行为。是这样吗?

参见https://github.com/lampepfl/dotty/issues/16728.

修复https://github.com/lampepfl/dotty/pull/17136

观察到的行为不反映意图。scala3编译器已经修复:3.3.1-RC1-bin-20230327-a569057-NIGHTLY的行为符合预期。

注意,错误行为可能被视为一般类型投影不健全的一种味道,并且不能在scala2中修复。.

相关内容

  • 没有找到相关文章

最新更新