Skip to content

Regression for frugalmechanic/fm-serializer in quotes-reflect + -Xcheck-macros  #19842

Closed
@WojciechMazur

Description

@WojciechMazur

Based on OpenCB failure of frugalmechanic/fm-serializer - build logs
Under -Xcheck-macros flag we get an error about different sets of parents - the parents of tree don't include class Object which is present in parents of symbol being created. Removing the class Object from list of parents leads to assertion error in the compiler, becouse it requires the first param to be a class, not a trait.

Compiler version

3.4.nightly
Last good release: 3.4.1-RC1-bin-20240210-6efcdba-NIGHTLY
First bad release: 3.4.1-RC1-bin-20240212-c529a48-NIGHTLY
Bisect points to aa5492f

Minimized code

// main.scala
trait Serializer[@specialized T]// extends RawSerializer[T] with NestedSerializer[T] with FieldSerializer[T]
object Serializer{
    implicit inline def implicitMakeSerializer[T]: Serializer[T] = ${ Macros.makeSerializer[T] }
}
case class ValidationCls(string: String)

@main def Test = summon[Serializer[ValidationCls]]
// macros.scala
//> using options -Xcheck-macros
import scala.annotation.{experimental, targetName}
import scala.quoted.*
import scala.util.Try

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,
      // 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
    )

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

    Block(List(modValDef, modClassDef), Ref(modSym)).asExprOf[Serializer[T]]
  }
}

Output

-- Error: /Users/wmazur/projects/dotty/bisect/main.scala:7:50 ------------------
7 |@main def Test = summon[Serializer[ValidationCls]]
  |                                                  ^
  |Malformed tree was found while expanding macro with -Xcheck-macros.
  |The tree does not conform to the compiler's tree invariants.
  |
  |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
  |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  |This location contains code that was inlined from main.scala:3
3 |    implicit inline def implicitMakeSerializer[T]: Serializer[T] = ${ Macros.makeSerializer[T] }
  |                                                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   -----------------------------------------------------------------------------
1 error found
Compilation failed

Expectation

Probably should not couse comilation error.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions