Skip to content

Commit 984284d

Browse files
committed
Add check for parents in Quotes (#i19842)
1 parent 2cd5721 commit 984284d

File tree

4 files changed

+52
-0
lines changed

4 files changed

+52
-0
lines changed

compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,7 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler
253253
(cdef.name.toString, cdef.constructor, cdef.parents, cdef.self, rhs.body)
254254

255255
def module(module: Symbol, parents: List[Tree /* Term | TypeTree */], body: List[Statement]): (ValDef, ClassDef) = {
256+
xCheckMacroAssert(parents.nonEmpty && !parents.head.tpe.dealias.classSymbol.is(dotc.core.Flags.Trait), "First parent must be a class")
256257
val cls = module.moduleClass
257258
val clsDef = ClassDef(cls, parents, body)
258259
val newCls = Apply(Select(New(TypeIdent(cls)), cls.primaryConstructor), Nil)

tests/neg-macros/i19842.check

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
-- Error: tests/neg-macros/i19842/Test.scala:9:50 ----------------------------------------------------------------------
2+
9 |@main def Test = summon[Serializer[ValidationCls]] // error
3+
| ^
4+
| Exception occurred while executing macro expansion.
5+
| java.lang.AssertionError: First parent must be a class
6+
| at Macros$.makeSerializer(Macro.scala:24)
7+
|
8+
|---------------------------------------------------------------------------------------------------------------------
9+
|Inline stack trace
10+
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
11+
|This location contains code that was inlined from Test.scala:5
12+
5 | implicit inline def implicitMakeSerializer[T]: Serializer[T] = ${ Macros.makeSerializer[T] }
13+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
14+
---------------------------------------------------------------------------------------------------------------------

tests/neg-macros/i19842/Macro.scala

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
2+
import scala.annotation.{experimental, targetName}
3+
import scala.quoted.*
4+
import scala.util.Try
5+
6+
object Macros {
7+
def makeSerializer[T: Type](using Quotes): Expr[Serializer[T]] = {
8+
import quotes.reflect.*
9+
10+
val tpe: TypeRepr = TypeRepr.of[T]
11+
val name: String = Symbol.freshName("objectSerializer")
12+
13+
val modSym: Symbol = Symbol.newModule(
14+
Symbol.spliceOwner,
15+
name,
16+
Flags.Implicit,
17+
Flags.EmptyFlags,
18+
List(TypeRepr.of[Object], TypeRepr.of[Serializer[T]]),
19+
_ => Nil,
20+
Symbol.noSymbol
21+
)
22+
23+
val (modValDef: ValDef, modClassDef: ClassDef) =
24+
ClassDef.module(modSym, List(TypeTree.of[Serializer[T]]), Nil)
25+
26+
Block(List(modValDef, modClassDef), Ref(modSym)).asExprOf[Serializer[T]]
27+
}
28+
}

tests/neg-macros/i19842/Test.scala

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
2+
trait Serializer[@specialized T]
3+
4+
object Serializer:
5+
implicit inline def implicitMakeSerializer[T]: Serializer[T] = ${ Macros.makeSerializer[T] }
6+
7+
case class ValidationCls(string: String)
8+
9+
@main def Test = summon[Serializer[ValidationCls]] // error

0 commit comments

Comments
 (0)