You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Scala3中的类型投影是否仍存在不健全问题?

Scala3 类型投影的不健全问题与设计意图分析

Scala3 已移除通用类型投影(general type-projection),因其存在不健全问题——可编译通过的代码会在运行时失败。

示例代码

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

问题现象

上述代码可正常编译,但运行时会抛出class B cannot be cast to class C异常。

原因分析

编译器认为C#X和B#X的擦除类型均为A#X,因此case cx:C#X分支会被匹配。此时编译器推断cx.outer的类型为C(实际是错误的),进而引发类型转换异常。

编译过程中无任何警告,也未涉及TypeTest。查看projectionTypeMatch的字节码可以发现,三个分支的测试逻辑完全一致。

规范与行为对比

根据Scala类型模式规范:

(类型模式T是……)对类C、p.C或T#C的引用。该类型模式匹配给定类的任何非空实例。注意,类的前缀(若存在)对确定类实例至关重要。

事实上,针对路径依赖类型的匹配符合预期(pathTypeMatch的结果为b1.x),编译器在匹配时会考虑X的外部实例。

我们有理由预期针对投影类型的匹配行为保持一致,不是吗?

核心疑问

  • 这种设计的意图是什么?
  • Scala3中对类型投影仅允许具体类型的限制是否能实现一致的行为?

内容的提问来源于stack exchange,提问作者Jean-Jacques Lecler

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 13:25:16