scala/scala3

cached derived instance loses refinements

Open

#10.031 aperta il 18 ott 2020

Vedi su GitHub
 (9 commenti) (0 reazioni) (0 assegnatari)Scala (1159 fork)batch import
help wanteditype:bugitype:enhancement

Metriche repository

Star
 (6247 star)
Metriche merge PR
 (Merge medio 18g 14h) (133 PR mergiate in 30 g)

Descrizione

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

Guida contributor