Skip to content

Calls that rewritten with macros annotation are not applied in runtime #22715

@NikKozh

Description

@NikKozh

Compiler version

3.3.5 (LTS)

Minimized code

I'm afraid there is no way to demonstrate the problem in one snippet or a file, so I created entire repo with reproducible code: https://github.com/NikKozh/error-example/tree/master

Tried to make it as small as possible.

I have described the short essence of the problem in repo's Readme, but also will duplicate it here:

I needed a macros that can rewrite some calls in every method of the annotated class. I made macro annotation for that in Scala 2 and it worked perfectly, but after migrating to Scala 3 I discovered that same macro algorithm doesn't work as expected.

Annotation rewrites methods correctly, I see that in build output. But in runtime app still using old methods, as if macros was never applied. However, I also added new def in macros, and override toString, just to check if macros even worked. And new toString totally was applied in runtime.

So I'm very confused - macros was partly applied? Am I doing something wrong, there is some macros limits in Scala 3 or it's actually a bug?

Build output

New body classDef:

List(@SourceFile("app/src/main/scala/org/error/app/Main.scala") @rewriteDefaultTransactorCalls @experimental class DbService[F[_$9]](database: Database[F], transactor: Transactor[F])(using evidence$1: Sync[F]) extends TransactorSyntax {
  def string$macro$1: String = "macros string"
  override def toString(): String = DbService.this.string$macro$1
  def doAction: F[Unit] = DbService.this.toDefaultTransactionOps[F, Unit](database.run[Unit](database.insert("ValueToInsert"))).transactWithMaster(transactor)
  def doRead: F[String] = DbService.this.toDefaultTransactionOps[F, String](database.run[String](database.read("SomeKey"))).transactWithReplicas(transactor)
})

Everything is ok, old methods was just .transact, now new transact methods are here: .transactWithMaster and .transactWithReplicas, and should be called accordingly in runtime.

Runtime output

ERROR! THERE IS SHOULDN'T BE DEFAULT TRANSACTION CALLS
ERROR! THERE IS SHOULDN'T BE DEFAULT TRANSACTION CALLS
service.toString: macros string
running transaction inside DB
inserting value ValueToInsert in DB
Transacted with master
running transaction inside DB
reading key SomeKey from DB
Transacted with master

But alas, there is output that shouldn't be here if methods would actually rewritten - two errors in the beginning and last "transacted with master" (should be replica). Nevertheless, .toString macro part is here, so macros changes was applied, but only partially. It seems like transact calls wasn't rewritten, despite build output.

Expectation

Runtime output:

service.toString: macros string
running transaction inside DB
inserting value ValueToInsert in DB
Transacted with master
running transaction inside DB
reading key SomeKey from DB
Transacted with replica

So the last "transaction" should be "in replica", according to rewrited transactWithReplicas call.

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