diff --git a/_scala3-reference/language-versions.md b/_scala3-reference/language-versions.md index a7606d9b2c..46636fb8d2 100644 --- a/_scala3-reference/language-versions.md +++ b/_scala3-reference/language-versions.md @@ -1,36 +1,11 @@ --- title: Language Versions type: chapter -description: This page lists the different flavours of language supported by the Scala 3 compiler. num: 100 -previous-page: overview +previous-page: /scala3/reference/syntax +next-page: /scala3/reference/language-versions/source-compatibility --- -The default Scala language version currently supported by the Dotty compiler is `3.0`. There are also other language versions that can be specified instead: +This chapter explains how different versions of the language interact with each other regarding their inputs and outputs. -- `3.0-migration`: Same as `3.0` but with a Scala 2 compatibility mode that helps moving Scala 2.13 sources over to Scala 3. In particular, it - - - flags some Scala 2 constructs that are disallowed in Scala 3 as migration warnings instead of hard errors, - - changes some rules to be more lenient and backwards compatible with Scala 2.13 - - gives some additional warnings where the semantics has changed between Scala 2.13 and 3.0 - - in conjunction with `-rewrite`, offer code rewrites from Scala 2.13 to 3.0. - -- `future`: A preview of changes introduced in the next versions after 3.0. In the doc pages here we refer to the language version with these changes as `3.1`, but it might be that some of these changes will be rolled out in later `3.x` versions. - -Some Scala-2 specific idioms will be dropped in this version. The feature set supported by this version will be refined over time as we approach its release. - -- `future-migration`: Same as `future` but with additional helpers to migrate from `3.0`. Similarly to the helpers available under `3.0-migration`, these include migration warnings and optional rewrites. - -There are two ways to specify a language version. - -- With a `-source` command line setting, e.g. `-source 3.0-migration`. -- With a `scala.language` import at the top of a source file, e.g: - -```scala -package p -import scala.language.`future-migration` - -class C { ... } -``` - -Language imports supersede command-line settings in the source files where they are specified. Only one language import specifying a source version is allowed in a source file, and it must come before any definitions in that file. +Additional information on interoperability and migration between Scala 2 and 3 can be found [here]({% link _overviews/scala3-migration/compatibility-intro.md %}). diff --git a/_scala3-reference/language-versions/binary-compatibility.md b/_scala3-reference/language-versions/binary-compatibility.md new file mode 100644 index 0000000000..2d1eb6ee89 --- /dev/null +++ b/_scala3-reference/language-versions/binary-compatibility.md @@ -0,0 +1,38 @@ +--- +title: Binary Compatibility +type: section +num: 102 +previous-page: /scala3/reference/language-versions/source-compatibility +--- + +In Scala 2, different minor versions of the compiler were free to change the way how they encoded different language features in JVM bytecode. So each bump of the compiler's minor version resulted in breaking the binary compatibility, and if a project had any Scala dependencies they all needed to be (cross-)compiled to the same minor Scala version that was used in that project itself. On the contrary, Scala 3 has a stable encoding into JVM bytecode. + +In addition to classfiles, the compilation process in Scala 3 also produces files with `.tasty` extension. [TASTy]({% link scala3/guides/tasty-overview.md %}) files represent fully elaborated Scala programs in the sense that they contain all the information that has been inferred by the compiler during the compilation (like contextual parameters and type parameters). Some of this information is lost during the generation of bytecode so Scala 3 compilers read TASTy files during compilation in addition to classfiles to know the exact types of values, methods, etc. in already compiled classes (although compilation from TASTy files only is also possible). TASTy files are also typically distributed together with classfiles in published artifacts. + +TASTy format is extensible but it preserves backward compatibility and the evolution happens between minor releases of the language. This means a Scala compiler in version `3.x1.y1` is able to read TASTy files produced by another compiler in version `3.x2.y2` if `x1 >= x2` (assuming two stable versions of the compiler are considered - `SNAPSHOT` or `NIGHTLY` compiler versions can read TASTy in an older stable format but their TASTY versions are not compatible between each other even if the compilers have the same minor version; also compilers in stable versions cannot read TASTy generated by an unstable version). + +TASTy version number has the format of `.-` and the numbering changes in parallel to language releases in such a way that a bump in language minor version corresponds to a bump in TASTy minor version (e.g. for Scala `3.0.0` the TASTy version is `28.0-0`). Experimental version set to 0 signifies a stable version while others are considered unstable/experimental. TASTy version is not strictly bound to the data format itself - any changes to the API of the standard library also require a change in TASTy minor version. + +Being able to bump the compiler version in a project without having to wait for all of its dependencies to do the same is already a big leap forward when compared to Scala 2. However, we might still try to do better, especially from the perspective of authors of libraries. +If you maintain a library and you would like it to be usable as a dependency for all Scala 3 projects, you would have to always emit TASTy in a version that would be readble by everyone, which would normally mean getting stuck at 3.0.x forever. + +To solve this problem a new experimental compiler flag `-Yscala-release ` (available since 3.1.2-RC1) has been added. Setting this flag makes the compiler produce TASTy files that should be possible to use by all Scala 3 compilers in version `` or newer (this flag was inspired by how `-release` works for specifying the target version of JDK). More specifically this enforces emitting TASTy files in an older format ensuring that: +* the code contains no references to parts of the standard library which were added to the API after `` and would crash at runtime when a program is executed with the older version of the standard library on the classpath +* no dependency found on the classpath during compilation (except for the standard library itself) contains TASTy files produced by a compiler newer than `` (otherwise they could potentially leak such disallowed references to the standard library). + +If any of the checks above is not fulfilled or for any other reason older TASTy cannot be emitted (e.g. the code uses some new language features which cannot be expressed the the older format) the entire compilation fails (with errors reported for each of such issues). + +As this feature is experimental it does not have any special support in build tools yet (at least not in sbt 1.6.1 or lower). +E.g. when a project gets compiled with Scala compiler `3.x1.y1` and `-Yscala-release 3.x2` option and then published using sbt +then the standard library in version `3.x1.y1` gets added to the project's dependencies instead of `3.x2.y2`. +When the dependencies are added to the classpath during compilation with Scala `3.x2.y2` the compiler will crash while trying to read TASTy files in the newer format. +A currently known workaround is to modify the build definition of the dependent project by explicitly overriding the version of Scala standard library in dependencies, e.g. + +```scala +dependencyOverrides ++= Seq( + scalaOrganization.value %% "scala3-library" % scalaVersion.value, + scalaOrganization.value %% "scala3-library_sjs1" % scalaVersion.value // for Scala.js projects +) +``` + +The behaviour of `-Yscala-release` flag might still change in the future, especially it's not guaranteed that every new version of the compiler would be able to generate TASTy in all older formats going back to the one produced by `3.0.x` compiler. diff --git a/_scala3-reference/language-versions/source-compatibility.md b/_scala3-reference/language-versions/source-compatibility.md new file mode 100644 index 0000000000..6ae3cd5fb0 --- /dev/null +++ b/_scala3-reference/language-versions/source-compatibility.md @@ -0,0 +1,38 @@ +--- +title: Source Compatibility +type: section +num: 101 +previous-page: /scala3/reference/language-versions +next-page: /scala3/reference/language-versions/binary-compatibility +--- + +Scala 3 does NOT guarantee source compatibility between different minor language versions (e.g. some syntax valid in 3.x might get deprecated and then phased out in 3.y for y > x). There are also some syntax structures that were valid in Scala 2 but are not anymore in Scala 3. However the compiler provides a possibility to specify the desired version of syntax used in a particular file or globally for a run of the compiler to make migration between versions easier. + +The default Scala language syntax version currently supported by the Dotty compiler is [`3.0`](https://scala-lang.org/api/3.x/scala/runtime/stdLibPatches/language$$3/0$.html). There are also other language versions that can be specified instead: + +- [`3.0-migration`](https://scala-lang.org/api/3.x/scala/runtime/stdLibPatches/language$$3/0-migration$.html): Same as `3.0` but with a Scala 2 compatibility mode that helps moving Scala 2.13 sources over to Scala 3. In particular, it + + - flags some Scala 2 constructs that are disallowed in Scala 3 as migration warnings instead of hard errors, + - changes some rules to be more lenient and backwards compatible with Scala 2.13 + - gives some additional warnings where the semantics has changed between Scala 2.13 and 3.0 + - in conjunction with `-rewrite`, offer code rewrites from Scala 2.13 to 3.0. + +- [`future`](https://scala-lang.org/api/3.x/scala/runtime/stdLibPatches/language$$future$.html): A preview of changes introduced in the next versions after 3.0. In the doc pages here we refer to the language version with these changes as `3.1`, but it might be that some of these changes will be rolled out in later `3.x` versions. + +Some Scala 2 specific idioms will be dropped in this version. The feature set supported by this version will be refined over time as we approach its release. + +- [`future-migration`](https://scala-lang.org/api/3.x/scala/runtime/stdLibPatches/language$$future-migration$.html): Same as `future` but with additional helpers to migrate from `3.0`. Similarly to the helpers available under `3.0-migration`, these include migration warnings and optional rewrites. + +There are two ways to specify a language version : + +- with a `-source` command line setting, e.g. `-source 3.0-migration`. +- with a `scala.language` import at the top of a source file, e.g: + +```scala +package p +import scala.language.`future-migration` + +class C { ... } +``` + +Language imports supersede command-line settings in the source files where they are specified. Only one language import specifying a source version is allowed in a source file, and it must come before any definitions in that file.