Skip to content

Instantly share code, notes, and snippets.

@MateuszKubuszok
Created August 29, 2023 17:50
Show Gist options
  • Save MateuszKubuszok/2723c2842b8bf969618f4bd751ba3041 to your computer and use it in GitHub Desktop.
Save MateuszKubuszok/2723c2842b8bf969618f4bd751ba3041 to your computer and use it in GitHub Desktop.
Reproduction for Scala 3 macro bug
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
}
}
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] }
}
@MateuszKubuszok
Copy link
Author

MateuszKubuszok commented Aug 29, 2023

scala-cli compile --scala-version 3.3.0 . 

Expects

  • for code to compile

Actual result

  • children of trait Shape were already queried before class Triangle was discovered error

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