scala/scala3

cached derived instance loses refinements

Open

#10,031 创建于 2020年10月18日

在 GitHub 查看
 (9 评论) (0 反应) (0 负责人)Scala (1,159 fork)batch import
help wanteditype:bugitype:enhancement

仓库指标

Star
 (6,247 star)
PR 合并指标
 (平均合并 18天 14小时) (30 天内合并 133 个 PR)

描述

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

贡献者指南