-
Notifications
You must be signed in to change notification settings - Fork 1.1k
summonInline in an inlined erasedValue match overwrites correct more specific type info #9110
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
Comments
This is a case of #8739, the type If you put your logic within the RHS of enum E:
case A
inline def headLabel[T<:NonEmptyTuple]:String = inline erasedValue[T] match
case _: (t *: _) =>
type MirroredProduct = Mirror.ProductOf[t]
summonFrom {
case mp: MirroredProduct =>
constValue[mp.MirroredLabel]
}
@main def psvm:Unit =
val ms = summonInline[Mirror.SumOf[E]]
println(headLabel[ms.MirroredElemTypes]) |
reopen after offline discussion |
We do this for |
I was playing with this a bit more and the proposed fix almost works - the summoned mirror has a proper type val mirror =
type MPt = Mirror.ProductOf[t]
summonFrom{case m: MPt => m}
val additional:Map[String,E] =
if(constValue[Tuple.Size[mirror.MirroredElemLabels]] == 0)
val value = mirror.fromProduct(Product0).asInstanceOf[E]
Map(key -> value)
else
Map.empty yet the [error] | val mirror:
[error] |
[error] | scala.deriving.Mirror.Product{
[error] | MirroredType =
[error] | (in.vojt.loonyssh.CompressionAlgorithm.zlib :
[error] | in.vojt.loonyssh.CompressionAlgorithm
[error] | )
[error] | ;
[error] | MirroredMonoType =
[error] | (in.vojt.loonyssh.CompressionAlgorithm.zlib :
[error] | in.vojt.loonyssh.CompressionAlgorithm
[error] | )
[error] | ; MirroredElemTypes <: Tuple
[error] | }
....
// yet the size check does not still work
....
[error] | (if
[error] | {
[error] | (???.$asInstanceOf$[Tuple.Size[mirror.MirroredElemLabels]]:
[error] | Tuple.Size[mirror.MirroredElemLabels]
[error] | )
[error] | }.==(0) Is it because, according to the type tree, the mirror type seems to be erased partially? The [error] | MirroredType =
[error] | (in.vojt.loonyssh.CompressionAlgorithm.zlib :
[error] | in.vojt.loonyssh.CompressionAlgorithm
[error] | ) is available, yet
is kind of uinformative ^^ |
Another alternative is to use macros inline def headLabel[T <: NonEmptyTuple]: String =
${ impl[T] }
private def impl[T <: NonEmptyTuple: Type](using Quotes): Expr[String] = {
Type.of[T] match
case '[ head *: tail ] =>
Expr.summon[Mirror.ProductOf[head]] match
case Some('{ type label <: String; $_ : Mirror { type MirroredLabel = `label` } }) =>
Expr(Type.valueOfConstant[label].get)
} |
To fix this we need to fix #8739 |
Minimized code
https://scastie.scala-lang.org/letalvoj/pettT3IoQbGeYB83B4i8iA/12
Output
Expectation
Relevant Type Tree
edit: Is it that the outer type
mp: deriving.Mirror.ProductOf[(E.A : E)]
erases the corect specific type of returnedt
?The text was updated successfully, but these errors were encountered: