Skip to content
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

Scala3: findValues fails to compile in nested sealed trait hierarchy #368

Closed
desavitsky opened this issue Jul 11, 2023 · 1 comment · Fixed by #371
Closed

Scala3: findValues fails to compile in nested sealed trait hierarchy #368

desavitsky opened this issue Jul 11, 2023 · 1 comment · Fixed by #371

Comments

@desavitsky
Copy link

desavitsky commented Jul 11, 2023

Example:

import enumeratum.values.StringEnum
import enumeratum.values.StringEnumEntry

sealed trait FirstLevel extends StringEnumEntry

object FirstLevel extends StringEnum[FirstLevel] {

  case object One extends FirstLevel {
    val value = "one"
  }
  case object Two extends FirstLevel {
    val value = "two"
  }

  sealed trait SecondLevel extends FirstLevel

  case object Three extends SecondLevel {
    val value = "three"
  }

  override def values: IndexedSeq[FirstLevel] = findValues

}

https://scastie.scala-lang.org/qpDNUwqAT4m4ovmn4EySgg

Error:
Exception occurred while executing macro expansion.
scala.MatchError: Type.of[...] (of class scala.quoted.runtime.impl.TypeImpl)

@lloydmeta
Copy link
Owner

Interesting... looks like the collect method is missing this possible case for tupleTpe:

tupleTpe match {
case '[TakeHead[h, tail]] => {
val htpr = TypeRepr.of[h]
(for {
vof <- Expr.summon[ValueOf[h]]
constValue <- htpr.typeSymbol.tree match {
case ClassDef(_, _, spr, _, rhs) => {
val fromCtor = spr
.collectFirst {
case Apply(Select(New(id), _), args) if id.tpe <:< repr =>
args
}
.flatMap(_.lift(valueParamIndex).collect { case ConstVal(const) =>
const
})
fromCtor
.orElse(rhs.collectFirst { case ConstVal(v) => v })
.flatMap { const =>
cls.unapply(const.value)
}
}
case _ =>
Option.empty[ValueType]
}
} yield Tuple3(TypeRepr.of[h], '{ ${ vof }.value: A }, constValue)) match {
case Some((tpr, instance, value)) =>
collect[tail](instance :: instances, values + (tpr -> value))
case None =>
report.errorAndAbort(
s"Fails to check value entry ${htpr.show} for enum ${repr.show}"
)
}
}
case '[EmptyTuple] => {
val allowAlias = repr <:< TypeRepr.of[AllowAlias]
if (!allowAlias && values.values.toSet.size < values.size) {
val details = values
.map { case (sub, value) =>
s"${sub.show} = $value"
}
.mkString(", ")
Left(s"Values for ${valueField.name} are not discriminated subtypes: ${details}")
} else {
Right(Expr ofList instances.reverse)
}
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants