简体   繁体   English

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

[英]Are type-projection still unsound in scala3?

Scala3 has dropped general type projection because it was unsound: Scala3 放弃了通用类型投影,因为它不可靠:
It was possible to compile code which was failing at runtime.可以编译在运行时失败的代码。

(question edited to reflect comments) (编辑问题以反映评论)

Consider the following scala3 code: scastie考虑以下 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

Code compiles, but fails at runtime with "class B cannot be cast to class C".代码编译,但在运行时失败,“B 类无法转换为 class C”。

The compiler considers C#X and B#X erasures to be A#X , so that case cx:C#X branch matches.编译器将C#XB#X擦除视为A#X ,因此case cx:C#X分支匹配。 From there, it is legitimate to consider cx.outer to be a C (which is wrong), hence the exception.从那里开始,将C视为cx.outer是合法的(这是错误的),因此例外。

No warning is issued.不发出警告。 No TypeTest is involved.不涉及类型测试。

When looking into the bytecode of projectionTypeMatch , the test of all 3 branches is strictly identical.查看projectionTypeMatch的字节码时,所有 3 个分支的测试完全相同。

In type-patterns :类型模式中

(A type-pattern T is...) a reference to a class C , p.C , or T#C . (类型模式 T 是...)对 class Cp.CT#C的引用。 This type pattern matches any non-null instance of the given class. Note that the prefix of the class, if it exists, is relevant for determining class instances.此类型模式匹配给定 class 的任何非空实例。请注意,class 的前缀(如果存在)与确定 class 实例相关。

Indeed, when the match is done against path-dependent types , the behavior is the expected one ( pathTypeMatch is b1.x ).实际上,当针对路径相关类型进行匹配时,行为是预期的行为( pathTypeMatchb1.x )。 In particular, the compiler had to take X outer into account in the match.特别是,编译器必须在匹配中考虑 X outer。

One would expect the match against projection-types to be consistent, isn't it?人们会期望与投影类型的匹配是一致的,不是吗?

What is the intention?意图何在?

It seems the restriction of type projections to concrete types in scala3 would allow a consistent behavior.似乎将类型投影限制为 scala3 中的具体类型将允许一致的行为。 Is it so?是这样吗?

See https://github.com/lampepfl/dotty/issues/16728 .请参阅https://github.com/lampepfl/dotty/issues/16728

The observed behavior does not reflect the intention: scala3 compiler is currently being fixed.观察到的行为并不反映意图: scala3编译器当前正在修复。 Target release is unknown at time of writing.在撰写本文时,目标版本未知。

Note the faulty behavior may be seen as a flavor of general type projection unsoundness, and cannot be fixed in scala2 .请注意,错误行为可能被视为一般类型投影不健全的一种风格,并且无法在scala2中修复。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM