Skip to content

strange behavior in macro when using default argument #10132

Open
@scabug

Description

@scabug

sample project : https://github.com/seraphr/scala-macro-strange-behavior

./sbt uses/clean uses/run

macro

when this macro is defined

import scala.language.experimental.macros
import scala.reflect.macros.whitebox.Context

object Members {
  def apply[A]: List[String] = macro macroImpl[A]

  def macroImpl[A: c.WeakTypeTag](c: Context): c.Tree = {
    import c.universe._
    val tType = weakTypeOf[A]
    val tMembers = tType.members.map(_.name.toString).toList

    q"${tMembers}"
  }
}

h3. case 1 - same file

run this code

case class Foo(a: Int, b: Long = 20, c: String = "aaa")

object Main extends App {
  val tFooMembers = Members[Foo]
  val tBarMembers = Members[Bar]
  val tFooCompanionMembers = Members[Foo.type]
  val tBarCompanionMembers = Members[Bar.type]

  println(s"Foo diff Bar = ${tFooMembers diff tBarMembers}")
  println(s"Bar diff Foo = ${tBarMembers diff tFooMembers}")
  println(s"FooCompanion diff BarCompanion = ${tFooCompanionMembers diff tBarCompanionMembers}")
  println(s"BarCompanion diff FooCompanion = ${tBarCompanionMembers diff tFooCompanionMembers}")

}

case class Bar(a: Int, b: Long = 20, c: String = "aaa")

Foo and Bar have same members, but output is

Foo diff Bar = List(copy$default$3, copy$default$2, copy$default$1)
Bar diff Foo = List()
FooCompanion diff BarCompanion = List($lessinit$greater$default$3, $lessinit$greater$default$2)
BarCompanion diff FooCompanion = List()

case 2 - different file

  • Baz.scala
case class Baz(a: Int, b: Long = 20, c: String = "aaa")
  • Qux.scala
case class Qux(a: Int, b: Long = 20, c: String = "aaa")
  • Main.scala
object Main extends App {
  val tBazMembers = Members[Baz]
  val tQuxMembers = Members[Qux]
  val tBazCompanionMembers = Members[Baz.type]
  val tQuxCompanionMembers = Members[Qux.type]

  println(s"Baz diff Qux = ${tBazMembers diff tQuxMembers}")
  println(s"Qux diff Baz = ${tQuxMembers diff tBazMembers}")
  println(s"BazCompanion diff QuxCompanion = ${tBazCompanionMembers diff tQuxCompanionMembers}")
  println(s"QuxCompanion diff BazCompanion = ${tQuxCompanionMembers diff tBazCompanionMembers}")
}

Baz and Qux have same members, but output is

Baz diff Qux = List(copy$default$3, copy$default$2, copy$default$1)
Qux diff Baz = List()
BazCompanion diff QuxCompanion = List(readResolve, apply$default$3, apply$default$2, $lessinit$greater$default$3, $lessinit$greater$default$2)
QuxCompanion diff BazCompanion = List()

this behavior depends on filename.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions