Skip to content

Mixing macros doesn't work if the scala 2 macro needs a WeakTypeTag of a type parameter to an enclosing class #16630

Closed
@coreywoodfield

Description

@coreywoodfield

Compiler version

3.2.1

Minimized code

import scala.language.experimental.macros
import scala.quoted.{Quotes, Expr, Type}

class Foo[A]
object Foo {
  def apply[A] = new Foo[A]
}

trait TraitWithTypeParam[A] {
  protected inline def foo: Foo[A] = ${ MacrosImpl.fooImpl[A] }
  protected def foo: Foo[A] = macro MacrosImpl.compatFooImpl[A]
}

object MacrosImpl {
  def fooImpl[A: Type](using quotes: Quotes): Expr[Foo[A]] = '{new Foo[A]}

  def compatFooImpl[A: c.WeakTypeTag](c: scala.reflect.macros.blackbox.Context): c.Tree = {
    import c.universe._
    TypeApply(
      Select(
        Ident(c.mirror.staticModule(classOf[Foo[A]].getName)),
        TermName("apply")
      ),
      List(TypeTree(weakTypeOf[A])),
    )
  }
}

build.sbt:

lazy val macroImpl = project.in(file("macro-impl"))
  .settings(
    scalaVersion := "3.2.1",
    libraryDependencies ++= Seq(
      "org.scala-lang" % "scala-reflect" % "2.13.10",
      "org.scala-lang" %% "scala3-compiler" % scalaVersion.value % Provided,
    )
  )

Output

[error] -- Error: /home/cwoodfield/lucid/macrotest/macro-impl/src/main/scala/location/Location.scala:11:25 
[error] 11 |trait TraitWithTypeParam[A] {
[error]    |                         ^
[error]    |                Something's wrong: missing original symbol for type tree
[error] -- Error: /home/cwoodfield/lucid/macrotest/macro-impl/src/main/scala/location/Location.scala:12:61 
[error] 12 |  protected inline def foo: Foo[A] = ${ MacrosImpl.fooImpl[A] }
[error]    |                                                             ^
[error]    |No given instance of type quoted.Type[A] was found for an implicit parameter of method fooImpl in object MacrosImpl
[error]    |
[error]    |where:    A is a type in trait TraitWithTypeParam which is an alias of <error Something's wrong: missing original symbol for type tree>
[error] two errors found

Expectation

This should compile and work as described in https://docs.scala-lang.org/scala3/guides/migration/tutorial-macro-mixing.html. Instead it doesn't compile.

Note that moving the [A] type parameter to the methods (i.e.

trait TraitWithTypeParam {
  protected inline def foo[A]: Foo[A] = ${ MacrosImpl.fooImpl[A] }
  protected def foo[A]: Foo[A] = macro MacrosImpl.compatFooImpl[A]
}

) or commenting out the scala 2 macro results in the code compiling. So it seems like attempting to call a scala 2 macro that takes a WeakTypeTag for a type that's a parameter to a class messes up the type tree for the class type parameter somehow

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions