Open
Description
The last good compiler version 3.4.2-RC1-bin-20240229-9fe0111-NIGHTLY
There are 2 issues related to the same reproducer
Reproducer
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)) // error: issue 2
m.fromProduct(Tuple.fromArray(vals.toArray)) // error: issue 1
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
Outputs
Issue 1
[error] -- [E172] Type Error: /Users/wmazur/projects/community-build3/repo/src/main/scala/info/fingo/spata/schema/TypedRecord.scala:93:46
[error] 93 | m.fromProduct(Tuple.fromArray(vals.toArray))
[error] | ^
[error] |No ClassTag available for T
[error] |
[error] |where: T is a type variable with constraint >: info.fingo.spata.schema.TypedRecord.SelectH[VS] | info.fingo.spata.schema.TypedRecord.SelectT[String, t, VS]
Introduced in #19761 and described in #20972 (comment)
Before that change, the toArray
was inferred to be toArray[Any]
which even though it allowed for compilation it was probably incorrect, but I'd like to request confirmation.
Issue 2
After using explicit `toArray[Any] to mitigate issue 1 in some later versions of compiler
Last good release: 3.4.2-RC1-bin-20240302-c7a0459-NIGHTLY
First bad release: 3.4.2-RC1-bin-20240305-beba585-NIGHTLY
No exact bisect result due to issues with the compiler builds
-- [E057] Type Mismatch Error: /Users/wmazur/projects/dotty/bisect/test.scala:28:12
28 | val vals = labels.map(l => get(l, keys, values))
| ^
|Type argument String does not conform to upper bound Key in subpart TypedRecord.SelectT[String, t, VS] of inferred type List[TypedRecord.SelectH[VS] | TypedRecord.SelectT[String, t, VS]]
or with later versions
-- [E007] Type Mismatch Error: /Users/wmazur/projects/dotty/bisect/test.scala:28:34
28 | val vals = labels.map(l => get(l, keys, values))
| ^^^^^^^^^^^^^^^^^^^^
| Found: TypedRecord.Select[(l : String), KS, VS]
| Required: KS match {
| case ? <: String *: _ => TypedRecord.SelectH[VS]
| case h *: t => TypedRecord.SelectT[String, t, VS]
| } <: TypedRecord.SelectH[VS] | TypedRecord.SelectT[String, t², VS]
|
| where: KS is a type in class TypedRecord with bounds <: Tuple
| VS is a type in class TypedRecord with bounds <: Tuple
| t is a type variable with constraint <: Tuple
| t² is a type in type Select with bounds <: Tuple
|
|
| Note: a match type could not be fully reduced:
|
| trying to reduce TypedRecord.Select[(l : String), KS, VS]
| failed since selector KS
| does not match case (l : String) *: _ => TypedRecord.SelectH[VS]
| and cannot be shown to be disjoint from it either.
| Therefore, reduction cannot advance to the remaining case
|
| case h *: t => TypedRecord.SelectT[(l : String), t, VS]
|