-
Couldn't load subscription status.
- Fork 1.1k
Closed
Labels
area:metaprogramming:reflectionIssues related to the quotes reflection APIIssues related to the quotes reflection APIitype:bugitype:crash
Milestone
Description
Compiler version
3.3.1
Minimized code
This is a slightly changed code from https://github.com/lampepfl/dotty-macro-examples/tree/main/defaultParamsInference, two files as in the example:
macro.scala:
package dummy
import scala.quoted.*
trait Defaults[A]:
def defaults: Map[String, Any]
object Defaults:
inline def derived[A <: Product]: Defaults[A] = ${ defaultsImpl[A] }
def defaultsImpl[A <: Product: Type](using Quotes): Expr[Defaults[A]] =
'{
new Defaults[A]:
def defaults: Map[String, Any] = ${ defaultParmasImpl[A] }
}
inline def defaultParams[T]: Map[String, Any] = ${ defaultParmasImpl[T] }
def defaultParmasImpl[T](using quotes: Quotes, tpe: Type[T]): Expr[Map[String, Any]] =
import quotes.reflect.*
TypeRepr.of[T].classSymbol match
case None => '{ Map.empty[String, Any] }
case Some(sym) =>
val comp = sym.companionClass
val mod = Ref(sym.companionModule)
val names =
for p <- sym.caseFields if p.flags.is(Flags.HasDefault)
yield p.name
val namesExpr: Expr[List[String]] =
Expr.ofList(names.map(Expr(_)))
val body = comp.tree.asInstanceOf[ClassDef].body
val idents: List[Ref] =
for
case deff @ DefDef(name, _, _, _) <- body
if name.startsWith("$lessinit$greater$default")
yield mod.select(deff.symbol)
val typeArgs = TypeRepr.of[T].typeArgs
val identsExpr: Expr[List[Any]] =
if typeArgs.isEmpty then Expr.ofList(idents.map(_.asExpr))
else Expr.ofList(idents.map(_.appliedToTypes(typeArgs).asExpr))
'{ $namesExpr.zip($identsExpr).toMap }dummy.scala:
package dummy
case class Person(name: String, address: String = "Zuricch", foo: Int, age: Int = 26)
case class Test3[A, B](as: List[A], bs: List[B] = List.empty)
object Person:
val x = 10
class Outer:
case class Inner(a: String, b: Int = 23) derives Defaults
@main def test(): Unit =
val p1 = Person("John", foo = 10)
val t1 = Test3(List("string"), List(23.0))
println(p1)
println(t1)
println(defaultParams[Person])
println(defaultParams[Test3[String, Double]])
assert(defaultParams[Person] == Map("address" -> "Zuricch", "age" -> 26))
val outer = Outer()
println(summon[Defaults[outer.Inner]].defaults)How to run:
- place both files in an empty directory
- run
scala-cli run . -S 3.3.1 --server=false
For some reason this does not happen when using the defaultParams macro directly but does happen if the same macro is executed via macro called by derives. Only happens for inner classes, other cases seem to work fine.
Output (click arrow to expand)
-- Error: /Users/lbialy/Projects/foss/tmp/macros/dummy.scala:10:51 -------------
10 | case class Inner(a: String, b: Int = 23) derives Defaults
| ^
|Exception occurred while executing macro expansion.
|java.lang.ClassCastException: class dotty.tools.dotc.ast.Trees$This cannot be cast to class dotty.tools.dotc.ast.Trees$RefTree (dotty.tools.dotc.ast.Trees$This and dotty.tools.dotc.ast.Trees$RefTree are in unnamed module of loader 'app')
| at scala.quoted.runtime.impl.QuotesImpl.scala$quoted$runtime$impl$QuotesImpl$reflect$Ref$$$_$apply$$anonfun$6(QuotesImpl.scala:445)
| at scala.quoted.runtime.impl.QuotesImpl$reflect$.scala$quoted$runtime$impl$QuotesImpl$reflect$$$withDefaultPos(QuotesImpl.scala:2997)
| at scala.quoted.runtime.impl.QuotesImpl$reflect$Ref$.apply(QuotesImpl.scala:445)
| at scala.quoted.runtime.impl.QuotesImpl$reflect$Ref$.apply(QuotesImpl.scala:443)
| at dummy.macro$package$.defaultParmasImpl(macro.scala:25)
| at dummy.Defaults$.defaultsImpl$$anonfun$1(macro.scala:14)
| at dummy.Defaults$.defaultsImpl$$anonfun$adapted$1(macro.scala:14)
| at dotty.tools.dotc.quoted.PickledQuotes$$anon$1.transform(PickledQuotes.scala:110)
| at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1538)
| at dotty.tools.dotc.quoted.PickledQuotes$$anon$1.transform(PickledQuotes.scala:135)
| at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1570)
| at dotty.tools.dotc.quoted.PickledQuotes$$anon$1.transform(PickledQuotes.scala:135)
| at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform$$anonfun$1(Trees.scala:1605)
| at scala.collection.immutable.List.mapConserve(List.scala:472)
| at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1605)
| at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transformStats(Trees.scala:1601)
| at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1574)
| at dotty.tools.dotc.quoted.PickledQuotes$$anon$1.transform(PickledQuotes.scala:135)
| at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1572)
| at dotty.tools.dotc.quoted.PickledQuotes$$anon$1.transform(PickledQuotes.scala:135)
| at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform$$anonfun$1(Trees.scala:1605)
| at scala.collection.immutable.List.mapConserve(List.scala:472)
| at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1605)
| at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transformStats(Trees.scala:1601)
| at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transformBlock(Trees.scala:1603)
| at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1518)
| at dotty.tools.dotc.quoted.PickledQuotes$$anon$1.transform(PickledQuotes.scala:135)
| at dotty.tools.dotc.quoted.PickledQuotes$.spliceTerms(PickledQuotes.scala:152)
| at dotty.tools.dotc.quoted.PickledQuotes$.unpickleTerm(PickledQuotes.scala:88)
| at scala.quoted.runtime.impl.QuotesImpl.unpickleExprV2(QuotesImpl.scala:3143)
| at dummy.Defaults$.defaultsImpl(macro.scala:14)
|
|----------------------------------------------------------------------------
|Inline stack trace
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|This location contains code that was inlined from macro.scala:9
9 | inline def derived[A <: Product]: Defaults[A] = ${ defaultsImpl[A] }
| ^^^^^^^^^^^^^^^^^^^^
----------------------------------------------------------------------------
1 error found
Compilation failed
Metadata
Metadata
Assignees
Labels
area:metaprogramming:reflectionIssues related to the quotes reflection APIIssues related to the quotes reflection APIitype:bugitype:crash