-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Backport "Approximate MatchTypes with lub of case bodies, if non-recursive" to LTS #20972
Conversation
No regressions detected in the community build up to lts-19921. |
Due to problems with OpenCB infrastructure, we have not received information about regression in the https://github.com/fingo/spata - a match types heavy library which fails to build since import scala.deriving.Mirror
import scala.annotation.unused
import scala.compiletime.{constValue, erasedValue, *}
type Key = String & Singleton
trait StringParser[+A]
private inline def getLabels[T <: Tuple]: List[String] = inline erasedValue[T] match
case _: EmptyTuple => Nil
case _: (t *: ts) => constValue[t].toString :: getLabels[ts]
private inline def getTypes[T <: Tuple]: List[StringParser[?]] = inline erasedValue[T] match
case _: EmptyTuple => Nil
case _: (t *: ts) => summonInline[StringParser[t]] :: getTypes[ts]
import TypedRecord.*
final class TypedRecord[KS <: Tuple, VS <: Tuple](
keys: KS,
values: VS,
)(using @unused ev1: Tuple.Size[KS] =:= Tuple.Size[VS], @unused ev2: Tuple.Union[KS] <:< Key):
inline def to[P <: Product](using
m: Mirror.ProductOf[P],
ev: Tuple.Union[Tuple.Zip[m.MirroredElemLabels, m.MirroredElemTypes]] <:< Tuple.Union[Tuple.Zip[KS, VS]]
): P =
val labels = getLabels[m.MirroredElemLabels]
val vals = labels.map(l => get(l, keys, values))
m.fromProduct(Tuple.fromArray(vals.toArray)) // error here
private def get[K <: Key, KS <: Tuple, VS <: Tuple](key: K, keys: KS, values: VS): Select[K, KS, VS] =
val selected = (keys: @unchecked) match
case `key` *: _ => getH(values)
case _ *: tk => getT(key, tk, values)
selected.asInstanceOf[Select[K, KS, VS]]
private def getT[K <: Key, KS <: Tuple, VS <: Tuple](key: K, keys: KS, values: VS): SelectT[K, KS, VS] =
(values: @unchecked) match
case vs: (h *: t) => get(key, keys, vs.tail[h *: t])
private def getH[VS <: Tuple](values: VS): SelectH[VS] =
(values: @unchecked) match
case vs: *:[h, t] => vs.head[h *: t]
object TypedRecord:
type Select[K <: Key, KS <: Tuple, VS <: Tuple] = KS match
case K *: ? => 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
This PR (both original and backport) made it fail with -- [E172] Type Error: /Users/wmazur/projects/lts-scripts/test.scala:54:46 ------
54 | m.fromProduct(Tuple.fromArray(vals.toArray))
| ^
|No ClassTag available for T
|
|where: T is a type variable with constraint >: TypedRecord.SelectH[VS] | TypedRecord.SelectT[String, t, VS] The code can be tested using nightly version Before that change, the Keeping this change would fix the LTS regression (since 3.3.1) #19710 but it would introduce new one |
Backports #19761 to the LTS branch.
PR submitted by the release tooling.
[skip ci]