Skip to content

Macro dependencies are tracked incorrectly in some cases #16420

@makkarpov

Description

@makkarpov

Compiler version

3.2.0

Minimized code

Bug reproduces only when two files are in different source sets (i.e. Directive is in main and Meow is in test).

SBT project that reproduces this problem is prepared here. Clone it and do sbt root/test:compile.

directive.scala:

import scala.quoted.{Expr, Quotes, Type}

object Converter {
  private def handleUnit[R](f: Expr[Int ?=> R])(using q: Quotes, rt: Type[R]): Expr[Unit] = ???

  class UnitConverter[R] extends Converter[EmptyTuple, R, Int ?=> R] {
    inline def convert(inline f: Int ?=> R): Unit = ${ handleUnit[R]('f) }
  }

  inline given unitHandler[R]: UnitConverter[R] = new UnitConverter[R]
}


trait Converter[T <: Tuple, R, F] {
  inline def convert(inline fn: F): Unit
}

abstract class Directive[R <: Tuple] {
  inline def apply[O, F](using inline c: Converter[R, O, F])(inline fn: F): Unit =
    c.convert(fn)
}

meow.scala:

object Meow extends App {
  case class Meow(s: String, i: Int)
  
  val dir: Directive[EmptyTuple] = ???
  dir {
    Meow("asd", 123)
  }
}

Output

[error] -- Error: Meow.scala:5:6 
[error]  5 |  dir {
[error]    |  ^
[error]    |  Cannot call macro class Meow defined in the same source file
[error]  6 |    Meow("asd", 123)
[error]  7 |  }
[error]    |----------------------------------------------------------------------------
[error]    |Inline stack trace
[error]    |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[error]    |This location contains code that was inlined from Directive.scala:20
[error] 20 |    c.convert(fn)
[error]    |    ^^^^^^^^^^^^^
[error]    |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[error]    |This location contains code that was inlined from Directive.scala:20
[error] 20 |    c.convert(fn)
[error]    |    ^^^^^^^^^^^^^
[error]     ----------------------------------------------------------------------------

In other circumstances, it does not fails with "Cannot call macro class ... defined in same source file", but fails with "Cyclic macro dependencies in Meow.scala", implying that Meow depends on itself.

Expectation

Code should compile and run

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions