Short Answer
1. TASTy does not touch the JVM bytecode. It is a separate metadata format used by the Scala 3 compiler for incremental compilation, IDE tooling, and linking between Scala 3 modules. The actual class files produced by both Scala 2.13 and Scala 3 are standard Java bytecode, so the JVM’s name‑mangling rules are identical for both. Any differences you see in binary compatibility stem from the Scala‑specific compiler rules for generating symbols, not from TASTy.
2. To link a Scala 3 project against a Scala 2.13 library (or vice‑versa) you must:
- Keep the public API free of Scala 3‑only language features (opaque types, union types, match types, given/using, etc.).
- Target the same JVM version (e.g.,
-release:8 or -target:jvm-1.8) in both projects.
- Use the same version of the Scala standard library that the consumer expects, or bundle the library’s stdlib in a shaded JAR.
- Avoid exposing Scala‑3‑only annotations or traits in the public signature.
- Verify the resulting bytecode with
javap -public to confirm that exposed methods and fields have plain JVM‑compatible signatures.
Detailed Explanation
TASTy and Name Mangling
TASTy is a binary format that stores a typed abstract syntax tree. It is used by the Scala 3 compiler for separate compilation and IDE support. The TASTy file is never loaded by the JVM at runtime; it is only read by the compiler. Therefore, TASTy has no effect on the JVM’s name‑mangling rules or on the actual binary interface that the class files expose.
When a Scala 2.13 trait or case class is compiled, the compiler emits a JVM class with a name that follows Scala 2’s mangling rules (e.g., scala/collection/immutable/List$). A Scala 3 compiler will emit a class with the same fully‑qualified name for the same type, because the target bytecode is the same. The only difference is that Scala 3 may apply different rules for generating synthetic members (e.g., for default parameters or extension methods), but those are still normal JVM members and are visible to Scala 2.13 consumers.
Constraints for Scala 3 ↔ Scala 2.13 Linking
- Public API Compatibility
If a Scala 3 library exposes a type or method that uses a Scala 3‑only construct, a Scala 2.13 consumer will fail with NoSuchMethodError or ClassCastException. Keep the API limited to types that exist in Scala 2.13 (e.g., Int, String, scala.collection.immutable.List, etc.).
- Standard Library Version
Scala 2.13 and Scala 3 use different standard library artifacts (scala-library_2.13 vs scala3-library_3). Mixing them on the same classpath can cause class‑loading conflicts. Either depend on the consumer’s stdlib or shade the library’s stdlib into a separate package.
- JVM Target
Both projects should compile with the same JVM target. For example, -release:8 in sbt or --release 8 in scalac. Mixing JVM targets can lead to unsupported bytecode features.
- Annotation Compatibility
Scala 3 introduces new annotations (e.g., scala.annotation.unchecked.uncheckedVariance) that are not present in Scala 2.13. If you use such annotations in public signatures, the Scala 2.13 compiler will not recognise them. Prefer annotations that exist in the Scala 2.13 stdlib.
- Testing and Verification
After publishing a library, run a quick test from the other language:
scalac -classpath lib.jar -Xsource:2 Test.scala
javap -public lib.jar | grep -i myMethod
This ensures that the symbol names match what the consumer expects.
Verification Checklist
- Compile the library with
-Xsource:2 (if using Scala 3) to avoid Scala 3‑only syntax in the public API.
- Run
javap -public on the compiled classes and compare the signatures with those generated by a Scala 2.13 compiler.
- Add a dummy Scala 2.13 project that depends on the library and run a simple unit test to confirm runtime behaviour.
- Use
scalafmt or scalastyle to enforce that no Scala 3‑only features leak into the API.
Missing Diagnostic Detail
To refine the recommendation for your specific project, could you confirm whether the Scala 3 library exposes any Scala 3‑only types (e.g., opaque types, union types, or given/using parameters) in its public API?