Skip to content

Commit

Permalink
Add check for parents in Quotes (#i19842)
Browse files Browse the repository at this point in the history
  • Loading branch information
hamzaremmal committed Mar 5, 2024
1 parent 469c980 commit deaec4b
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 22 deletions.
6 changes: 6 additions & 0 deletions compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,12 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler
(cdef.name.toString, cdef.constructor, cdef.parents, cdef.self, rhs.body)

def module(module: Symbol, parents: List[Tree /* Term | TypeTree */], body: List[Statement]): (ValDef, ClassDef) = {
xCheckMacroAssert(parents.nonEmpty && !parents.head.tpe.dealias.classSymbol.is(dotc.core.Flags.Trait), "First parent must be a class")
xCheckMacroAssert(
module.moduleClass.asClass.classInfo.parents.map(_.dealias.typeSymbol)
==
parents.map(_.tpe.dealias.typeSymbol),
"Parents in the symbol are not compatible with the provided parents")
val cls = module.moduleClass
val clsDef = ClassDef(cls, parents, body)
val newCls = Apply(Select(New(TypeIdent(cls)), cls.primaryConstructor), Nil)
Expand Down
24 changes: 3 additions & 21 deletions tests/neg-macros/i19842.check → tests/neg-macros/i19842-a.check
Original file line number Diff line number Diff line change
@@ -1,28 +1,10 @@
-- Error: tests/neg-macros/i19842/Test.scala:9:50 ----------------------------------------------------------------------
9 |@main def Test = summon[Serializer[ValidationCls]] // error
| ^
|Malformed tree was found while expanding macro with -Xcheck-macros.
|The tree does not conform to the compiler's tree invariants.
| Exception occurred while executing macro expansion.
| java.lang.AssertionError: First parent must be a class
| at Macros$.makeSerializer(Macro.scala:24)
|
|Macro was:
|scala.quoted.runtime.Expr.splice[Serializer[ValidationCls]](((contextual$2: scala.quoted.Quotes) ?=> Macros.makeSerializer[ValidationCls](scala.quoted.Type.of[ValidationCls](contextual$2), contextual$2)))
|
|The macro returned:
|{
| object objectSerializer$macro$1 extends Serializer[ValidationCls] { this: objectSerializer$macro$1.type =>
|
| }
| objectSerializer$macro$1
|}
|
|Error:
|assertion failed: Parents of class symbol differs from the parents in the tree for object objectSerializer$macro$1
|
|Parents in symbol: [class Object, trait Serializer]
|Parents in tree: [trait Serializer]
|
|
|stacktrace available when compiling with `-Ydebug`
|---------------------------------------------------------------------------------------------------------------------
|Inline stack trace
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ object Macros {
name,
Flags.Implicit,
Flags.EmptyFlags,
// Without TypeRep.of[Object] it would fail with java.lang.AssertionError: assertion failed: First parent must be a class
List(TypeRepr.of[Object], TypeRepr.of[Serializer[T]]),
_ => Nil,
Symbol.noSymbol
Expand Down
File renamed without changes.
14 changes: 14 additions & 0 deletions tests/neg-macros/i19842-b.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
-- Error: tests/neg-macros/i19842-b/Test.scala:9:50 --------------------------------------------------------------------
9 |@main def Test = summon[Serializer[ValidationCls]] // error
| ^
| Exception occurred while executing macro expansion.
| java.lang.AssertionError: Parents in the symbol are not compatible with the provided parents
| at Macros$.makeSerializer(Macro.scala:26)
|
|---------------------------------------------------------------------------------------------------------------------
|Inline stack trace
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|This location contains code that was inlined from Test.scala:5
5 | implicit inline def implicitMakeSerializer[T]: Serializer[T] = ${ Macros.makeSerializer[T] }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
---------------------------------------------------------------------------------------------------------------------
30 changes: 30 additions & 0 deletions tests/neg-macros/i19842-b/Macro.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@

import scala.annotation.{experimental, targetName}
import scala.quoted.*
import scala.util.Try

trait Foo

object Macros {
def makeSerializer[T: Type](using Quotes): Expr[Serializer[T]] = {
import quotes.reflect.*

val tpe: TypeRepr = TypeRepr.of[T]
val name: String = Symbol.freshName("objectSerializer")

val modSym: Symbol = Symbol.newModule(
Symbol.spliceOwner,
name,
Flags.Implicit,
Flags.EmptyFlags,
List(TypeRepr.of[Object], TypeRepr.of[Serializer[T]]),
_ => Nil,
Symbol.noSymbol
)

val (modValDef: ValDef, modClassDef: ClassDef) =
ClassDef.module(modSym, List(TypeTree.of[Object], TypeTree.of[Serializer[T]], TypeTree.of[Foo]), Nil)

Block(List(modValDef, modClassDef), Ref(modSym)).asExprOf[Serializer[T]]
}
}
9 changes: 9 additions & 0 deletions tests/neg-macros/i19842-b/Test.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@

trait Serializer[@specialized T]

object Serializer:
implicit inline def implicitMakeSerializer[T]: Serializer[T] = ${ Macros.makeSerializer[T] }

case class ValidationCls(string: String)

@main def Test = summon[Serializer[ValidationCls]] // error

0 comments on commit deaec4b

Please sign in to comment.