Scala 3 Migration Guide

Macro Libraries

Language

The Scala 2.13 macro API is closely tied to the Scala 2.13 compiler internals. Therefore the Scala 3 compiler cannot expand Scala 2.13 macros.

Macro Dependencies

A Scala 3 module can depend on a Scala 2.13 artifact that contains macro definitions, but the compiler cannot expand those macros. Calling one is an error:

 -- Error: /src/main/scala/example/Example.scala:10:45
 10 |  val documentFormat = Json.format[Document]
    |                            ^
    |Scala 2 macro cannot be used in Scala 3. See https://docs.scala-lang.org/scala3/reference/dropped-features/macros.html
    |To turn this error into a warning, pass -Xignore-scala2-macros to the compiler

When the macro provides an implicit value, the error does not mention macros: it says the implicit was not found. Examples are shapeless Lazy (used by circe-generic’s deriveEncoder) and scalactic Position (used by ScalaTest’s assert).

-Xignore-scala2-macros lets the code type check, but the macro calls throw an exception at run time.

The solution is to use a version of the library that is published for Scala 3.

Porting a Macro Library

Scala 3 macros are written from scratch, using the new metaprogramming features: inline methods, compile-time operations, quoted code and reflection. The Macros in Scala 3 tutorial explains them.

To publish a macro library for both Scala 2.13 and Scala 3, there are two techniques:

Contributors to this page: