Summary
Type annotations in pattern matching have been restricted in Scala 3.3 as part of PR #16150. This causes source-code incompatibility vs 3.2 for statements like this:
case h *: _: *:[?, ?] => h
As I understand, this is seen as an easy-to-fix, syntax-only change.
I believe, that when match types are involved, this restriction effectively precludes certain solutions, which were possible in Scala 3.2.
I would like to restore type annotation to the form available in Scala 3.2.
Or, if at all possible, enhance match types to work with patterns without type annotations.
Context
Please see this code snippet:
type Key = String with Singleton
type Select[K <: Key, KS <: Tuple, VS <: Tuple] = KS match
case K *: t => SelectH[VS]
case h *: t => SelectT[K, t, VS]
type SelectT[K <: Key, KS <: Tuple, VS <: Tuple] = VS match
case ? *: tv => Select[K, KS, tv]
type SelectH[VS <: Tuple] = VS match
case h *: ? => h
def get[K <: Key, KS <: Tuple, VS <: Tuple](key: K, keys: KS, values: VS): Select[K, KS, VS] =
(keys: @unchecked) match
case `key` *: _: *:[K @unchecked, ?] => getH(values) // not achievable in Scala 3.3
case _ *: tk: *:[?, ?] => getT(key, tk, values)
def getT[K <: Key, KS <: Tuple, VS <: Tuple](key: K, keys: KS, values: VS): SelectT[K, KS, VS] =
(values: @unchecked) match
case _ *: t: *:[?, ?] => get(key, keys, t)
def getH[VS <: Tuple](values: VS): SelectH[VS] =
(values: @unchecked) match
case h *: _: *:[?, ?] => h
val keys: ("x", "y") = ("x", "y")
val values = (1, "a")
val v: String = get("y", keys, values)
println(v)
This prints a
while executed with Scala 3.2 and doesn’t compile with 3.3.
Most of the code may be adjusted to 3.3, except for
case `key` *: _: *:[K @unchecked, ?] => getH(values)
Before I found out that this was a planned change, I opened issue #17289, with a simplified code example. It was really quickly addressed, with an explanation and proposed solution. Unfortunately, the proposed solution doesn’t cover all cases.
Thank you in advance for taking this request into account.