-
-
Save MateuszKubuszok/2723c2842b8bf969618f4bd751ba3041 to your computer and use it in GitHub Desktop.
Reproduction for Scala 3 macro bug
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Test2 { | |
def test(): Unit = { | |
println(scala.compiletime.testing.typeCheckErrors("Macro.subtypes[fixture.Shape]")) | |
} | |
} | |
package fixture { | |
case class Point(x: Double, y: Double) | |
sealed trait Shape | |
case class Triangle(p1: Point, p2: Point, p3: Point) extends Shape | |
case class Rectangle(p1: Point, p2: Point) extends Shape | |
case class Circle(center: Point, rad: Double) extends Shape | |
object Inner { | |
case class Triangle(p1: Point, p2: Point, p3: Point) extends Shape | |
case class Rectangle(p1: Point, p2: Point) extends Shape | |
case class Circle(center: Point, rad: Double) extends Shape | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
object Macro { | |
import scala.quoted.* | |
def subtypesImpl[A: Type](using quotes: Quotes): Expr[String] = { | |
import quotes.*, quotes.reflect.* | |
def isSealed: Boolean = { | |
val flags = TypeRepr.of[A].typeSymbol.flags | |
flags.is(Flags.Enum) || flags.is(Flags.Sealed) | |
} | |
def extractSubclasses(sym:Symbol):List[Symbol]= | |
if sym.flags.is(Flags.Sealed) then sym.children.flatMap(extractSubclasses) | |
else if sym.flags.is(Flags.Enum) then List(sym.typeRef.typeSymbol) | |
else if sym.flags.is(Flags.Module) then List(sym.typeRef.typeSymbol.moduleClass) | |
else List(sym) | |
def subtypeName(subtype:Symbol):String = { | |
val n = subtype.name | |
if n.endsWith("$") then n.substring(0, n.length-1 ) else n | |
} | |
val names = if (isSealed) { | |
extractSubclasses(TypeRepr.of[A].typeSymbol).distinct.map(subtypeName) | |
} else Nil | |
Expr(names.mkString(", ")) | |
} | |
inline def subtypes[A]: String = ${ subtypesImpl[A] } | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Expects
Actual result
children of trait Shape were already queried before class Triangle was discovered
error