scala/scala3

cached derived instance loses refinements

Open

#10.031 aberto em 18 de out. de 2020

Ver no GitHub
 (9 comments) (0 reactions) (0 assignees)Scala (1.159 forks)batch import
help wanteditype:bugitype:enhancement

Métricas do repositório

Stars
 (6.247 stars)
Métricas de merge de PR
 (Mesclagem média 18d 14h) (133 fundiu PRs em 30d)

Description

Minimized code

package example

trait Sealed[A] {
  type NumCases <: Int
}

object Sealed {
  import quoted._

  transparent inline def derived[A]: Sealed[A] = ${ deriveSealed[A] }

  def deriveSealed[A: Type](using Quotes): Expr[Sealed[A]] =
    import quotes.reflect._

    val tpe = TypeRepr.of[A]

    val sym = tpe.classSymbol match
      case Some(sym) => sym
      case _         => report.throwError(s"${tpe.show} is not a class type")

    val numCases = ConstantType(IntConstant(sym.children.length)).asType.asInstanceOf[quoted.Type[Int]]

    '{
      new {
        type NumCases = numCases.Underlying
      }
    }
}
// second source

import example._

enum MyEnum derives Sealed { case A, B, C }

val fromDerived = summon[Sealed[MyEnum]] // : example.Sealed[MyEnum]
val manual = Sealed.derived[MyEnum] // : example.Sealed[MyEnum]{NumCases = 3}

Expectation

I would expect the cached values to remember type refinements, so e.g. the derived Sealed instance can be used in further type class derivation to extract the NumCases type

Guia do colaborador