Improving Scala 3 forward compatibility

outputScalaVersion is much easier to understand IMO.

2 Likes

After some more discussions (including the core compiler team) here’s my suggestion how to make the naming (in the compiler and in sbt, but also potentially in other build tools) consistent and less cryptic. If multiple entries exist in the same cell then they’re interchangeable (that’s in order not to break compatibility).


compiler (current) compiler (suggested) sbt (current) sbt (suggested)
compiler version
(e.g. for `sbt compile` or `sbt test:compile`)
scalac -version scalac -version scalaVersion := "3.1.2-RC1"

++3.1.2-RC1
scalaVersion := "3.1.2-RC1"

++3.1.2-RC1
version of produced TASTy files
(expressed with corresponding scala version;
validates references to scala stdlib API)
-Yscala-release 3.0 -scala-output-version 3.0 scalaVersion := "3.1.2-RC1"

++3.1.2-RC1
scalaOutputVersion := "3.0.2"
stdlib version used at runtime
(e.g. for `sbt run` or `sbt test`)
scala -version scala -version scalaVersion := "3.1.2-RC1"

++3.1.2-RC1
scalaOutputVersion := "3.0.2"
stdlib version declared as transitive dependency
in Ivy and POM files
(for compile time and runtime of dependent projects)
- - scalaVersion := "3.1.2-RC1"

++3.1.2-RC1
scalaOutputVersion := "3.0.2"
version of produced JVM bytecode
(validates references to JDK API)
-release 8 -java-output-version 8


-release 8
scalacOptions ++= Seq(
"java-output-version", "8")

scalacOptions ++= Seq(
"release", "8")
scalacOptions ++= Seq(
"-java-output-version", "8")

scalacOptions ++=
Seq("-release", "8")
version of produced JVM bytecode
(doesn't validate references to JDK API;
discouraged)
-Xtarget 8 -Xunchecked-java-output-version 8


-Xtarget 8
scalacOptions ++= Seq(
"-Xunchecked-java-output-version", "8")

scalacOptions ++= Seq(
"-Xtarget", "8")
scalacOptions ++= Seq(
"-Xunchecked-java-output-version", "8")

scalacOptions ++=
Seq("-Xtarget", "8")
7 Likes

Hopefully a more readable version as an image

3 Likes

Thanks for the update. This looks good to me.

3 Likes

I was randomly skimming through my GitHub notifications and came across an interesting pull request by Paweł https://github.com/scala/scala-lang/pull/1387.

More importantly, during work on 3.2, we realized that maintaining this flag may be more challenging than anticipated. With time, it will be increasingly harder to be sure that our handling of it is correct. Thus we have decided to remove the possibility of configuring the output version altogether in Scala 3.2.

I wish you well for the LTS / Next approach, but in the meantime, should I remove the newly added settings from sbt since I’ve only released a milestone thus far?

Yes, feel free to remove it. We were going to make a PR reverting support for the flag as soon as we deal with the communication of the decision.

Besides directly supporting -scala-output-version that PR also added a more general possibility to use different versions of Scala for compilation and for running the code. I’m still wondering whether someone might find this part useful in some situations so maybe the PR should be reverted only partially?

I am sympathetic to keeping working code, but I’m not convinced if it’s worth keeping it around. For one, the triggering mechanism hinges on having scalaOutputVersion being different and dependency graph having different scala-library.jar in Runtime. The problem is, without the compiler actually supporting forward compatibility someone compiling with 3.2.0 etc and declaring it at 3.1.2 in POM is unsafe. One potential use as a library author might be to use a nightly compiler to circumvent @experimental :slightly_smiling_face:, but I don’t know if you y’all want ppl doing that.

In general, we should try to make illegal states unrepresentable, and that applies to builds as well.