Skip to content

Commit b5d4428

Browse files
committed
Add check for parents in Quotes (#i19842)
1 parent 469c980 commit b5d4428

File tree

8 files changed

+73
-33
lines changed

8 files changed

+73
-33
lines changed

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,12 @@ 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")
257+
xCheckMacroAssert(
258+
module.moduleClass.asClass.classInfo.parents.map(_.dealias.typeSymbol)
259+
==
260+
parents.map(_.tpe.dealias.typeSymbol),
261+
"Parents in the symbol are not compatible with the provided parents")
256262
val cls = module.moduleClass
257263
val clsDef = ClassDef(cls, parents, body)
258264
val newCls = Apply(Select(New(TypeIdent(cls)), cls.primaryConstructor), Nil)

tests/neg-macros/i19842-a.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-a/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 renamed to tests/neg-macros/i19842-a/Macro.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ object Macros {
1515
name,
1616
Flags.Implicit,
1717
Flags.EmptyFlags,
18-
// Without TypeRep.of[Object] it would fail with java.lang.AssertionError: assertion failed: First parent must be a class
1918
List(TypeRepr.of[Object], TypeRepr.of[Serializer[T]]),
2019
_ => Nil,
2120
Symbol.noSymbol

tests/neg-macros/i19842-b.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-b/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: Parents in the symbol are not compatible with the provided parents
6+
| at Macros$.makeSerializer(Macro.scala:26)
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-b/Macro.scala

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

tests/neg-macros/i19842-b/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

tests/neg-macros/i19842.check

Lines changed: 0 additions & 32 deletions
This file was deleted.

0 commit comments

Comments
 (0)