Prepare for Scala 3 While Still on 2.13

Once you've reached the 2.13 bridge, don't rush to Scala 3 immediately. There are "pre-migration" steps you can take while still on the stable 2.13 compiler that will eliminate 50% of your future Scala 3 errors.

The Magic Flag: -Xsource:3

Scala 2.13.x includes a special compiler flag: -Xsource:3. This flag makes the Scala 2 compiler act like the Scala 3 compiler in specific ways (e.g., stricter shadowing, different implicit resolution rules).

Real-World Example: Detecting Shadowing

In Scala 2, you might have nested variables with the same name. Scala 3 is stricter about this. By enabling -Xsource:3 in your 2.13 build, the compiler will warn you about these "quiet" changes before they become hard errors in Scala 3.

Refactoring Implicits to "Givens-Ready" Code

Scala 3 replaces implicit with given and using. While you can't use these keywords in 2.13 yet, you can structure your implicits to be compatible.

  1. Avoid "Implicit Conversions": Scala 3 requires an explicit import for conversions. Start replacing them with extension methods (implicit classes in 2.13).
  2. Explicit Return Types: Always provide explicit return types for implicit vals/defs. Scala 3's type inference works differently, and missing types are a common source of "Implicit not found" errors during migration.

Macro Isolation

Macros are the biggest "blockers" in any migration. Scala 2 macros are fundamentally incompatible with Scala 3.

Strategy: The Macro Wrapper

If you use a custom macro for JSON serialization or logging:

  1. Isolate the macro into its own sub-module.
  2. Provide a fallback or a "dummy" implementation for Scala 3.
  3. Real-World Example: Many teams switch from simulacrum or custom boilerplate macros to standard Scala features or Magnolia, which has versions for both 2.13 and 3.

Tooling: Scala 3 Migrate

There is a dedicated tool called scala3-migrate (an sbt plugin). Use it while still on 2.13 to:

  • Check dependency compatibility.
  • Automatically migrate sbt settings.
  • Preview source code changes.
sbt "scala3MigrateDependencies"
sbt "scala3MigrateSettings"

Summary

Preparation is 90% of the battle. By using -Xsource:3 and isolating your macros while still on 2.13, you ensure that the final step to Scala 3.3 is just a version change, not a rewrite.