Thank you @Kordyjan for writing this detailed plan.
It is not clear to me why the @since
annotation is necessary, though. Is it solely for documentation purposes? Or will some parts of the compiler chain rely on it? If this is just for documentation, what do you think of using the existing @since
Scaladoc tag instead?
The compiler flag --scala-target
seems very promising to me. I believe it will solve most of the issues that the end-users may face in practice. Typically, the ability to upgrade a library (because it has an important fix or feature) without having to upgrade the compiler (because that causes compilation errors that would take a lot of effort to fix). Which corresponds to your goal 1.
I am not sure about the ability to choose the language target per compilation unit. First, the use case of having a library whose some parts use new language features (goal 2 in your post) could already be addressed without special compiler support, by splitting the library into two modules, where the first module targets, say, Scala 3.0, and the second module depends on the first module and targets Scala 3.1.
The only place where we might need such a mechanism is in the scala3-library, which can not be split into several libraries. An alternative solution could be to customize the build of the scala3-library so that it is made of a single jar containing compilation products with TASTy files of various versions. So, in the same jar we would have TASTy files targeting Scala 3.0 whenever possible, and targeting Scala 3.1 or above when necessary. That would also achieve your goal 3.
Last, I believe another item should be part of the plan: the way library management tools resolve the scala3-library should be changed so that in case a project depends on libraries that depend on different versions of scala3-library, we pick the highest one (just like we resolve transitive dependencies). Currently, library management tools resolve the scala3-library version only based on the version of the Scala compiler used in the project.