Closed
Description
Minimized code
First, let's implement a really simple type derivation that just prints something for every given type in a product/coproduct
object EnumerateNames {
inline def summonNext[T] =
summonFrom {
case en: EnumerateNames[T] => en
}
inline def walkThrough[Types <: Tuple]: List[String] =
inline erasedValue[Types] match
case _: (tpe *: tpes) =>
summonNext[tpe].apply +: walkThrough[tpes]
case _: EmptyTuple =>
Nil
inline def derived[T]: EnumerateNames[T] =
summonFrom {
case ev: Mirror.Of[T] =>
new EnumerateNames[T] {
def apply =
inline ev match
case m: Mirror.ProductOf[T] => walkThrough[m.MirroredElemTypes].mkString(", ")
case m: Mirror.SumOf[T] => walkThrough[m.MirroredElemTypes].mkString(", ")
}
}
}
trait EnumerateNames[T] {
def apply: String
}
Then let's create a class that defines an enum and an automatic derivation for types:
class MainClass {
enum Shape:
case Square(width: Int, height: Int) extends Shape
case Circle(radius: Int) extends Shape
given EnumerateNames[Int] with {
def apply: String = "int"
}
inline given auto[T]:EnumerateNames[T] = EnumerateNames.derived
def deriveEnumerateNames[T](using en: EnumerateNames[T]) = en.apply
def run: Unit = println( deriveEnumerateNames[Shape] )
}
Then let's call that class:
object Main {
def main(args: Array[String]) = {
new MainClass().run
}
}
Output
A very large error happens:
exception while typing MainClass.this.Shape$.this of class class dotty.tools.dotc.ast.Trees$This # -1
exception while typing MainClass.this.Shape$.this.Square of class class dotty.tools.dotc.ast.Trees$Select # -1
exception while typing MainClass.this.Shape$.this.Square:
(
deriving.Mirror{
MirroredType = io.getquill.MainClass.Shape.Square;
MirroredMonoType = io.getquill.MainClass.Shape.Square
; MirroredElemTypes <: Tuple
}
&
scala.deriving.Mirror.Product{
MirroredMonoType = io.getquill.MainClass.Shape.Square;
MirroredType = io.getquill.MainClass.Shape.Square
; MirroredLabel = ("Square" : String)
}
){
...
java.lang.AssertionError: assertion failed: failure to construct path from value ev/value elem$1/method apply/anonymous class Object with io.getquill.EnumerateNames {...}/method run/class MainClass/package io.getquill/package io/package <root> to `this` of object Shape in class MainClass;
class MainClass in package io.getquill does not have an outer accessor while compiling /Users/aleiof/git/enum_summon/src/main/scala/io/getquill/Example.scala, /Users/aleiof/git/enum_summon/src/main/scala/io/getquill/Main.scala
[error] ## Exception when compiling 2 sources to /Users/aleiof/git/enum_summon/target/scala-3.0.0-M3/classes
[error] java.lang.AssertionError: assertion failed: failure to construct path from value ev/value elem$1/method apply/anonymous class Object with io.getquill.EnumerateNames {...}/method run/class MainClass/package io.getquill/package io/package <root> to `this` of object Shape in class MainClass;
[error] class MainClass in package io.getquill does not have an outer accessor
[error] scala.runtime.Scala3RunTime$.assertFailed(Scala3RunTime.scala:8)
[error] dotty.tools.dotc.transform.ExplicitOuter$OuterOps$.loop$1(ExplicitOuter.scala:410
[error] dotty.tools.dotc.transform.ExplicitOuter$OuterOps$.path$extension(ExplicitOuter.scala:429)
[error] dotty.tools.dotc.transform.Erasure$Typer.typedThis(Erasure.scala:750)
[error] dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:2529)
[error] dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2590)
[error] dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:118)
[error] dotty.tools.dotc.typer.Typer.typed(Typer.scala:2659)
[error] dotty.tools.dotc.typer.Typer.typed(Typer.scala:2663)
[error] dotty.tools.dotc.transform.Erasure$Typer.typedSelect(Erasure.scala:641)
[error] dotty.tools.dotc.typer.Typer.typedNamed$1(Typer.scala:2498)
[error] dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2589)
[error] dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:118)
[error] dotty.tools.dotc.typer.Typer.typed(Typer.scala:2659)
[error] dotty.tools.dotc.typer.Typer.typed(Typer.scala:2663)
[error] dotty.tools.dotc.transform.Erasure$Typer.typedTyped(Erasure.scala:603)
[error] dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:2533)
[error] dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2590)
[error] dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:118)
[error] dotty.tools.dotc.typer.Typer.typed(Typer.scala:2659)
[error] dotty.tools.dotc.typer.Typer.typed(Typer.scala:2663)
[error] dotty.tools.dotc.typer.Typer.typedExpr(Typer.scala:2779)
[error] dotty.tools.dotc.transform.Erasure$Typer.typedTypeApply(Erasure.scala:767)
[error] dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:2547)
[error] dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2590)
[error] dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:118)
[error] dotty.tools.dotc.typer.Typer.typed(Typer.scala:2659)
...
[error] (Compile / compileIncremental) java.lang.AssertionError: assertion failed: failure to construct path from value ev/value elem$1/method apply/anonymous class Object with io.getquill.EnumerateNames {...}/method run/class MainClass/package io.getquill/package io/package <root> to `this` of object Shape in class MainClass;
[error] class MainClass in package io.getquill does not have an outer accessor
[error] Total time: 1 s, completed Jan 20, 2021 2:24:19 AM
Expectation
Compilation should work and "int, int, int" should be returned.
Workaround
Moving the enum to a static place (e.g. into an object) seems to solve the problem.
Repo
Repository with code sample can be found here:
https://github.com/deusaquilus/enum_summon