diff --git a/_overviews/scala3-migration/compatibility-classpath.md b/_overviews/scala3-migration/compatibility-classpath.md index fbe2684dc1..6b25280994 100644 --- a/_overviews/scala3-migration/compatibility-classpath.md +++ b/_overviews/scala3-migration/compatibility-classpath.md @@ -24,15 +24,16 @@ The Scala 3 unpickler has been extensively tested in the community build for man  -As an sbt build it can be illustrated by (sbt 1.5.0 or higher is required): +As an sbt build, it looks like this: ```scala +// build.sbt (sbt 1.5 or higher) lazy val foo = project.in(file("foo")) - .settings(scalaVersion := "3.0.0") + .settings(scalaVersion := "3.3.1") .dependsOn(bar) lazy val bar = project.in(file("bar")) - .settings(scalaVersion := "2.13.6") + .settings(scalaVersion := "2.13.11") ``` Or, in case bar is a published Scala 2.13 library, we can have: @@ -40,7 +41,7 @@ Or, in case bar is a published Scala 2.13 library, we can have: ```scala lazy val foo = project.in(file("foo")) .settings( - scalaVersion := "3.0.0", + scalaVersion := "3.3.1", libraryDependencies += ("org.bar" %% "bar" % "1.0.0").cross(CrossVersion.for3Use2_13) ) ``` @@ -56,13 +57,11 @@ Let's note that the standard library is automatically provided by the build tool ## The Scala 2.13 TASTy Reader -The second piece of good news is that the Scala 2.13 TASTy reader, which enables consuming Scala 3 libraries has been shipped since Scala 2.13.4. - -> The TASTy reader is very new. That's why it is only available under the `-Ytasty-reader` flag. +The second piece of good news is that Scala 2.13 can consume Scala 3 libraries with `-Ytasty-reader`. ### Supported Features -The TASTy reader supports all the traditional language features as well as the following brand-new features: +The TASTy reader supports all the traditional language features as well as the following Scala 3 features: - [Enumerations]({{ site.scala3ref }}/enums/enums.html) - [Intersection Types]({{ site.scala3ref }}/new-types/intersection-types.html) - [Opaque Type Aliases]({{ site.scala3ref }}/other-new-features/opaques.html) @@ -71,11 +70,11 @@ The TASTy reader supports all the traditional language features as well as the f - [Open Classes]({{ site.scala3ref }}/other-new-features/open-classes.html) (and inheritance of super traits) - [Export Clauses]({{ site.scala3ref }}/other-new-features/export.html) -We have limited support on: +It partially supports: - [Top-Level Definitions]({{ site.scala3ref }}/dropped-features/package-objects.html) - [Extension Methods]({{ site.scala3ref }}/contextual/extension-methods.html) -More exotic features are not supported: +It does not support the more advanced features: - [Context Functions]({{ site.scala3ref }}/contextual/context-functions.html) - [Polymorphic Function Types]({{ site.scala3ref }}/new-types/polymorphic-function-types.html) - [Trait Parameters]({{ site.scala3ref }}/other-new-features/trait-parameters.html) @@ -94,18 +93,19 @@ By enabling the TASTy reader with `-Ytasty-reader`, a Scala 2.13 module can depe  -As an sbt build it can be illustrated by: +As an sbt build, it looks like this: ```scala +// build.sbt (sbt 1.5 or higher) lazy val foo = project.in.file("foo") .settings( - scalaVersion := "2.13.6", + scalaVersion := "2.13.11", scalacOptions += "-Ytasty-reader" ) .dependsOn(bar) lazy val bar = project.in(file("bar")) - .settings(scalaVersion := "3.0.0") + .settings(scalaVersion := "3.3.1") ``` Or, in case `bar` is a published Scala 3 library: @@ -113,7 +113,7 @@ Or, in case `bar` is a published Scala 3 library: ```scala lazy val foo = project.in.file("foo") .settings( - scalaVersion := "2.13.6", + scalaVersion := "2.13.11", scalacOptions += "-Ytasty-reader", libraryDependencies += ("org.bar" %% "bar" % "1.0.0").cross(CrossVersion.for2_13Use3) ) @@ -137,7 +137,5 @@ The inverted pattern, with a 2.13 module in the middle, is also possible. > #### Disclaimer for library maintainers > -> Using the interoperability between Scala 2.13 and Scala 3 in a published library is generally not safe for your end-users. -> > Unless you know exactly what you are doing, it is discouraged to publish a Scala 3 library that depends on a Scala 2.13 library (the scala-library being excluded) or vice versa. > The reason is to prevent library users from ending up with two conflicting versions `foo_2.13` and `foo_3` of the same foo library in their classpath, this problem being unsolvable in some cases. diff --git a/_overviews/scala3-migration/compatibility-metaprogramming.md b/_overviews/scala3-migration/compatibility-metaprogramming.md index 6b0e55b537..aae66f0532 100644 --- a/_overviews/scala3-migration/compatibility-metaprogramming.md +++ b/_overviews/scala3-migration/compatibility-metaprogramming.md @@ -14,7 +14,7 @@ Therefore it is not possible for the Scala 3 compiler to expand any Scala 2.13 m In contrast, Scala 3 introduces a new principled approach of metaprogramming that is designed for stability. Scala 3 macros, and inline methods in general, will be compatible with future versions of the Scala 3 compiler. -While this is an uncontested improvement, it also means that all Scala 2.13 macros have to be rewritten from the ground up, by using the new metaprogramming features. +While this is an uncontested improvement, it also means that all Scala 2.13 macros have to be rewritten from the ground up, using the new metaprogramming features. ## Macro Dependencies @@ -54,16 +54,16 @@ They are comprised of: Before getting deep into reimplementing a macro you should ask yourself: - Can I use `inline` and the `scala.compiletime` operations to reimplement my logic? -- Can I use the simpler and safer expression based macros? +- Can I use the simpler and safer expression-based macros? - Do I really need to access the AST? - Can I use a [match type]({{ site.scala3ref }}/new-types/match-types.html) as return type? -You can learn all the new metaprogramming concepts by reading the [Macro Tutorial][scala3-macros]. +You can learn all the new metaprogramming concepts by reading the [Macros in Scala 3][scala3-macros] tutorial. ## Cross-building a Macro Library You have written a wonderful macro library and you would like it to be available in Scala 2.13 and Scala 3. -There are two different approaches, the traditional cross-building technique and the more recent mixing macro technique. +There are two different approaches, the traditional cross-building technique and the more experimental mixing macro technique. You can learn about them by reading these tutorials: - [Cross-Building a Macro Library](tutorial-macro-cross-building.html) - [Mixing Scala 2.13 and Scala 3 Macros](tutorial-macro-mixing.html) diff --git a/_overviews/scala3-migration/external-resources.md b/_overviews/scala3-migration/external-resources.md index 4915537176..9f968c6df9 100644 --- a/_overviews/scala3-migration/external-resources.md +++ b/_overviews/scala3-migration/external-resources.md @@ -1,8 +1,8 @@ --- title: External Resources -type: section +type: chapter description: This section lists external resources about the migration to Scala 3. -num: 27 +num: 28 previous-page: plugin-kind-projector next-page: --- diff --git a/_overviews/scala3-migration/scala3-migrate.md b/_overviews/scala3-migration/scala3-migrate.md index 4a6c0f98bb..554ca5f021 100644 --- a/_overviews/scala3-migration/scala3-migrate.md +++ b/_overviews/scala3-migration/scala3-migrate.md @@ -1,320 +1,443 @@ --- -title: Scala3-migrate plugin (sbt) -type: chapter +title: Porting an sbt Project (using sbt-scala3-migrate) +type: section description: This section shows how to use scala3-migrate to migrate a project -num: 7 -previous-page: tooling-tour -next-page: tooling-migration-mode +num: 10 +previous-page: tutorial-prerequisites +next-page: tutorial-sbt --- -## Context +`sbt-scala3-migrate` is an sbt plugin to assist you during the migration of your sbt project to Scala 3. +It consists of four sbt commands: +- `migrateDependencies` helps you update the list of `libraryDependencies` +- `migrateScalacOptions` helps you update the list of `scalacOptions` +- `migrateSyntax` fixes a number of syntax incompatibilities between Scala 2.13 and Scala 3 +- `migrateTypes` tries to compile your code to Scala 3 by infering types and resolving implicits where needed. -Scala3-migrate tool is part of a series of initiatives to make the migration to Scala 3 as easy as possible. -The goal is to provide a tool that will help you migrate both your build and your code to Scala 3. -The solution consists of 4 independent steps that are packaged into an sbt plugin: - -- **migrate-libs**: helps you update the list of `libraryDependencies` -- **migrate-scalacOptions**: helps you update the list of `scalacOptions` -- **migrate-syntax**: fixes a number of syntax incompatibilities in Scala 2.13 code -- **migrate**: tries to make your code compile with Scala 3 by adding the minimum required inferred types and implicit arguments. - -Each one of these steps is an sbt command that is described in details below. +Each one of these commands is described in details below. > #### Requirements -> - Scala 2.13, preferred 2.13.7 +> - Scala 2.13, preferred 2.13.11 > - sbt 1.5 or higher > - **Disclaimer:** This tool cannot migrate libraries containing macros. +> +> #### Recommendation +> Before the migration, add `-Xsource:3` to your scalac options to enable some Scala 3 syntax and behavior. -## Installation +In this tutorial, we will migrate the project in [scalacenter/scala3-migration-example](https://github.com/scalacenter/scala3-migration-example). +To learn about the migration, and train yourself, you can clone this repository and follow the tutorial steps. -Currently, you can use scala3-migrate via an sbt plugin. You can add it as follows to your build. +## 1. Installation + +Add `sbt-scala3-migrate` in the `project/plugins.sbt` file of your sbt project. ``` scala // project/plugins.sbt -addSbtPlugin("ch.epfl.scala" % "sbt-scala3-migrate" % "0.5.0") +addSbtPlugin("ch.epfl.scala" % "sbt-scala3-migrate" % "0.6.1") ``` -
The latest published version is
- The latest published version is
+
+
+
+
+
+Let's take a closer look at each part of this output message.
+
+### Valid dependencies
+
+Valid dependencies are compatible with Scala 3, either because they are standard Java libraries or because they have been cross-published to Scala 3.
+
+
+sbt:main> migrateDependencies main
+[info]
+[info] Starting migration of libraries and compiler plugins of project main
+[info]
+[info] Valid dependencies:
+[info] "io.github.java-diff-utils" % "java-diff-utils" % "4.12"
+
+[warn]
+[warn] Versions to update:
+[warn] "org.typelevel" %% "cats-core" % "2.6.1" (Other versions: 2.7.0, ..., 2.10.0)
+[warn] "org.scalameta" %% "munit" % "0.7.25" % Test (Other versions: 0.7.26, ..., 1.0.0-M8)
+[warn]
+[warn] For Scala 3 use 2.13:
+[warn] ("org.scalameta" %% "parsers" % "4.8.9").cross(CrossVersion.for3Use2_13)
+[warn]
+[warn] Integrated compiler plugins:
+[warn] addCompilerPlugin(("org.typelevel" %% "kind-projector" % "0.13.2").cross(CrossVersion.full))
+[warn] replaced by scalacOptions += "-Ykind-projector"
+[error]
+[error] Incompatible Libraries:
+[error] "com.softwaremill.scalamacrodebug" %% "macros" % "0.4.1" % Test (Macro Library)
+[error] addCompilerPlugin("com.olegpy" %% "better-monadic-for" % "0.3.1") (Compiler Plugin)
+[info]
+[success] Total time: 0 s, completed Aug 28, 2023 9:18:04 AM
+
+
+
+
+You can keep them as they are.
+
+### Versions to update
+
+These libraries have been cross-published to Scala 3 in later versions.
+You need to update their versions.
+
+
+[info] Valid dependencies:
+[info] "io.github.java-diff-utils" % "java-diff-utils" % "4.12"
+
+
+
+
+In the given example we need to bump the version of cats-core to 2.6.1 and the version of munit to 0.7.25.
+
+> The `Other versions` part of the output message indicates which other versions are available in Scala 3.
+If you wish you can bump to one of the most recent version, but take care of choosing a source compatible version.
+According to [the semantic versionning scheme](https://semver.org/), a patch or minor version bump is safe but not a major version bump.
+
+
+### For Scala 3 use 2.13
+
+These libraries are not yet cross-published to Scala 3 but they are cross-compatible.
+You can use their 2.13 versions to compile to Scala 3.
+
+Add `.cross(CrossVersion.for3Use2_13)` on the libraries to tell sbt to use the `_2.13` suffix, instead of `_3`.
+
+
+[warn] Versions to update:
+[warn] "org.typelevel" %% "cats-core" % "2.6.1" (Other versions: 2.7.0, ..., 2.10.0)
+[warn] "org.scalameta" %% "munit" % "0.7.25" % Test (Other versions: 0.7.26, ..., 1.0.0-M8)
+
+
+
+
+> #### Disclaimer about `CrossVersion.for3Use2_13`:
+- It can cause a conflict on the `_2.13` and `_3` suffixes of a transitive dependency.
+In such situation, sbt will fail to resolve the dependency, with a clear error message.
+- It is generally not safe to publish a Scala 3 library which depends on a Scala 2.13 library.
+Otherwise users of the library can have conflicting `_2.13` and `_3` suffixes on the same dependency.
+
+### Integrated compiler plugins
+
+Some compiler plugins were integrated into the Scala 3 compiler itself.
+In Scala 3 you don't need to resolve them as dependencies but you can activate them with compiler flags.
+
+
+[warn] For Scala 3 use 2.13:
+[warn] ("org.scalameta" %% "parsers" % "4.8.9").cross(CrossVersion.for3Use2_13)
+
+
+
+
+Here for instance you can activate kind-projector by adding `-Ykind-projector` to the list of `scalacOptions`.
+
+During the migration process, it is important to maintain the compatibility with Scala 2.13.
+The later `migrateSyntax` and `migrateTypes` commands will use the Scala 2.13 compilation to rewrite some parts of the code automatically.
+
+You can configure kind-projector in a cross-compatible way like this:
+```scala
+// add kind-projector as a dependency on Scala 2
+libraryDependencies ++= {
+ if (scalaVersion.value.startsWith("3.")) Seq.empty
+ else Seq(
+ compilerPlugin(("org.typelevel" %% "kind-projector" % "0.13.2").cross(CrossVersion.full))
+ )
+},
+// activate kind-projector in Scala 3
+scalacOptions ++= {
+ if (scalaVersion.value.startsWith("3.")) Seq("-Ykind-projector")
+ else Seq.empty
+}
```
-Valid libraries are libraries that can be kept as they are. Those libraries are either already
-compatible with Scala 3, or they are Java libraries.
-
-### Libraries that need to be updated
-```text
-org.typelevel:cats-core:2.2.0 -> "org.typelevel" %% "cats-core" % "2.6.1" : Other versions are avaialble for Scala 3: "2.7.0"
-ch.epfl.scala:scalafix-rules:0.9.26:test -> "ch.epfl.scala" %% "scalafix-rules" % "0.9.26" % "test" cross CrossVersion.for3Use2_13 : It's only safe to use the 2.13 version if it's inside an application.
-```
+### Incompatible libraries
-- For `cats-core` there is a version that has been published for Scala 3
- which is the proposed version `2.6.1`. We can update the build with this new version. There is also
- a more recent version available which is `2.7.0` (but we need to use at least version 2.6.1 to get Scala 3 compatibility).
-
-- For `scalafix-rules`, there is no available version for Scala 3, but the library does not contain macros,
- and therefore the `2.13` version can be used as it is in Scala 3. The syntax still needs to be updated to
- `"ch.epfl.scala" %% "scalafix-rules" % "0.9.26" % "test" cross CrossVersion.for3Use2_13`.
- It’s not recommended to publish a Scala 3 library that depends on a Scala 2.13 library.
- The reason is to prevent library users from ending up with two conflicting versions of
- the same library in their classpath (one for Scala 2.13 and one for Scala 3), this problem can not be solved in some cases.
- Read more about this topic in [the interoperability-overview](compatibility-classpath.html#interoperability-overview).
-
-### Macro library
-```text
-com.softwaremill.scalamacrodebug:macros:0.4.1:test -> X : Contains Macros and is not yet published for Scala 3.
-```
-Scala 2 macros cannot be executed by the Scala 3 compiler.
-So if you depend on a library that relies on macros, you will have to wait until this library is published for Scala 3.
+Some macro libraries or compiler plugins are not compatible with Scala 3.
-### Compiler plugins
-```text
-com.olegpy:better-monadic-for:0.3.1:plugin->default(compile) -> X : Scala 2 compiler plugins are not supported in Scala 3. You need to find an alternative.
-org.typelevel:kind-projector:0.11.0:plugin->default(compile) -> -Ykind-projector : This compiler plugin has a scalacOption equivalent. Add it to your scalacOptions.
-```
+
+[warn] Integrated compiler plugins:
+[warn] addCompilerPlugin(("org.typelevel" %% "kind-projector" % "0.13.2").cross(CrossVersion.full))
+[warn] replaced by scalacOptions += "-Ykind-projector"
+
+
+
-`better-monadic-for` is a Scala 2 compiler plugin.
-As explained in this [section](tutorial-sbt.html#2-choose-a-module), Scala 2 compiler plugins are not
-supported in Scala 3.
-In this case, we need to remove `better-monadic-for` and fix the code manually to make it compile without the compiler plugin.
+To solve these incompatibilities, you can either:
+- Check with the maintainers if they plan to port them to Scala 3, and possibly help them to do so.
+- Remove these dependencies from your build and adapt the code accordingly.
-For `kind-projector`, which is also a Scala 2 compiler plugin, there is an equivalent compiler option, `-Ykind-projector` (as shown in the message), which
-can be added to your `scalacOptions`.
+### The updated build
-### The new build file
-To update the build, for all incompatible settings or libraries, we assign different `scalacOptions` and `libraryDependencies` depending on the `scalaVersion`.
+After you updated the build, it should look like this:
```scala
//build.sbt
lazy val main = project
.in(file("."))
.settings(
- name := "main",
- scalaVersion := "2.13.7",
- semanticdbEnabled := true,
- scalacOptions ++= {
- if (scalaVersion.value.startsWith("3")) Seq("-Werror", "-Ykind-projector")
- else Seq("-Werror", "-Wunused")
- },
- libraryDependencies ++= (
- if (scalaVersion.value.startsWith("3")) Seq()
- else
- Seq(compilerPlugin("org.typelevel" %% "kind-projector" % "0.13.2" cross CrossVersion.full))
- ),
+ scalaVersion := "2.13.11",
libraryDependencies ++= Seq(
- "org.typelevel" %% "cats-core" % "2.6.1",
- "ch.epfl.scala" % "scalafix-interfaces" % "0.9.26",
- "ch.epfl.scala" %% "scalafix-rules" % "0.9.26" % "test" cross CrossVersion.for3Use2_13
- )
+ "org.typelevel" %% "cats-core" % "2.6.1",
+ "io.github.java-diff-utils" % "java-diff-utils" % "4.12",
+ ("org.scalameta" %% "parsers" % "4.8.9").cross(CrossVersion.for3Use2_13),
+ "org.scalameta" %% "munit" % "0.7.25" % Test
+ ),
+ libraryDependencies ++= {
+ if (scalaVersion.value.startsWith("3.")) Seq.empty
+ else Seq(
+ compilerPlugin(("org.typelevel" %% "kind-projector" % "0.13.2").cross(CrossVersion.full))
+ )
+ },
+ scalacOptions ++= {
+ if (scalaVersion.value.startsWith("3.")) Seq("-Ykind-projector")
+ else Seq.empty
+ }
)
```
-## Migrate `scalacOptions`
-**Usage:** `migrate-scalacOptions projectId` where projectId is the name of the module chosen to be migrated.
-
-This command helps with the process of updating the compiler settings. It is based on
-[the Compiler Options Table](options-lookup.html).
-Between Scala 2.13 and Scala 3.1.0, the available compiler options are different:
-- some Scala 2.13 settings have been removed
-- others have been renamed
-- some remain the same.
-
-The previous build file specifies two scalacOptions: `-Werror` and `-Wunused`
-```
-> migrate-scalacOptions main
-[info] X : the option is not available in Scala 3
-[info] Renamed : the option has been renamed
-[info] Valid : the option is still valid
-[info] Plugin : the option is related to a plugin, previously handled by migrate-libs
-[info]
-[info] -Wunused -> X
-[info] -Werror -> -Xfatal-warnings
-
-[info] Plugins options
-[info] -Yrangepos -> X
-[info] -Xplugin:/Users/meriamlachkar/Library/Caches/Coursier/v1/https/repo1.maven.org/maven2/org/typelevel/kind-projector_2.13.3/0.13.2/kind-projector_2.13.3-0.13.2.jar -> Plugin
-[info] -Xplugin:/Users/meriamlachkar/Library/Caches/Coursier/v1/https/repo1.maven.org/maven2/org/scalameta/semanticdb-scalac_2.13.3/4.4.20/semanticdb-scalac_2.13.3-4.4.20.jar -> Plugin
-[info] -P:semanticdb:synthetics:on -> Plugin
-[info] -P:semanticdb:sourceroot:/Users/meriamlachkar/perso/plugin-test -> Plugin
-[info] -P:semanticdb:targetroot:/Users/meriamlachkar/perso/plugin-test/target/scala-2.13/meta -> Plugin
-[info] -P:semanticdb:failures:warning -> Plugin
-
-```
+Reload sbt, check that the project compiles (to Scala 2.13), check that the tests run successfully, and commit your changes.
+You are now ready to migrate the compiler options.
-We see that `-Wunusued` is specific to Scala 2 and doesn't have an equivalent in scala3, so we need to
-remove it, whereas `-Werror` exists under a different name: `-Xfatal-warnings`, and can be renamed.
+## 4. Migrate the compiler options
-The command also outputs information specific to sbt plugins.
-There is no need to modify them, the plugins are supposed to adapt the settings for Scala 3.
+**Usage:** `migrateScalacOptions
+[error] Incompatible Libraries:
+[error] "com.softwaremill.scalamacrodebug" %% "macros" % "0.4.1" % Test (Macro Library)
+[error] addCompilerPlugin("com.olegpy" %% "better-monadic-for" % "0.3.1") (Compiler Plugin)
+
+
+
+
+Some scalac options are still valid, some must be renamed and some must be removed.
+
+> Some options can appear in the output of `migrateScalacOptions` but not in your `build.sbt`.
+> They are added by sbt or by some sbt plugins.
+> Make sure to use up-to-date versions of sbt and sbt plugins.
+> They should be able to adapt the added compiler options to the Scala version automatically.
+
+Once again, it is important to maintain the compatibility with Scala 2.13 because the `migrateSyntax` and `migrateTypes` commands will use the Scala 2.13 compilation to apply some patches automatically.
+
+Here is how we can update the list of scalacOptions:
+```scala
+lazy val main = project
+ .in(file("."))
+ .settings(
+ scalaVersion := "2.13.11",
+ scalacOptions ++= {
+ if (scalaVersion.value.startsWith("3.")) scala3Options
+ else scala2Options
+ }
+ )
-This third command applies a number of scalafix rules that fix some of the deprecated syntaxes.
-Once those changes are applied, the code still compiles in Scala 2.13 and you can
-already commit those changes.
+lazy val sharedScalacOptions =
+ Seq("-encoding", "UTF-8", "-Wunused:imports,privates,locals")
-**Usage:** `migrate-syntax projectId` where projectId is the name of the module chosen to be migrated.
+lazy val scala2Options = sharedScalacOptions ++
+ Seq("-target:jvm-1.8", "-Xsource:3", "-explaintypes")
-The list of scalafix rules applied are:
-- ProcedureSyntax
-- fix.scala213.ConstructorProcedureSyntax
-- fix.scala213.ExplicitNullaryEtaExpansion
-- fix.scala213.ParensAroundLambda
-- fix.scala213.ExplicitNonNullaryApply
-- fix.scala213.Any2StringAdd
+lazy val scala3Options = sharedScalacOptions ++
+ Seq("-Xunchecked-java-output-version:8", "-explain")
+```
-For more information on the fixed incompatibilities, please refer to
-[the Incompatibility Table](incompat-syntactic.html).
+Reload sbt, check that the project compiles (to Scala 2.13), check that the tests run successfully, and commit your changes.
+You are now ready to migrate the syntax.
-> There are more incompatibilities listed in the migration guide.
-> Most of them are not frequent and can easily be fixed by hand.
-> If you want to contribute by developing automatic rewrite with scalafix,
-> we will be happy to add your rule in the migrate-syntax command.
+## 5. Migrate the syntax
-This is the output of `migrate-syntax`.
-```
-> migrate-syntax main
-[info] We are going to fix some syntax incompatibilities
-[info]
-[info] Successfully run fixSyntaxForScala3 in 8839 milliseconds
-[info]
-[info] The syntax incompatibilities have been fixed on the project main
-[info] You can now commit the change!
-[info] You can also execute the next command to try to migrate to 3.1.0
-[info]
-[info] migrate main
-[info]
-[success] Total time: 2 s, completed 9 Apr 2021, 11:12:05
-```
+**Usage:** `migrateSyntax
+sbt:main> migrateScalacOptions main
+[info]
+[info] Starting migration of scalacOptions in main
+[info]
+[info] Valid scalacOptions:
+[info] -encoding UTF-8
+[info] -Wunused:imports,privates,locals
+[warn]
+[warn] Renamed scalacOptions:
+[warn] -target:jvm-1.8 -> -Xunchecked-java-output-version:8
+[warn] -explaintypes -> -explain
+[warn]
+[warn] Removed scalacOptions:
+[warn] -Xsource:3
+[warn] -Yrangepos
+[success] Total time: 0 s, completed Aug 29, 2023 2:00:57 PM
+
+
+
+
+Take a look at the applied changes, check that the project still compiles, check that the tests run successfully and commit the changes.
+The next and final step is to migrate the types.
+
+## 6. Migrate the types
+
+**Usage:** `migrateTypes
+sbt:main> migrateSyntax main
+[info] Starting migration of syntax in main
+[info] Run syntactic rules in 7 Scala sources successfully
+[info] Applied 3 patches in src/main/scala/example/SyntaxRewrites.scala
+[info] Run syntactic rules in 8 Scala sources successfully
+[info] Applied 1 patch in src/test/scala/example/SyntaxRewritesTests.scala
+[info] Migration of syntax in main succeeded.
+[success] Total time: 2 s, completed Aug 31, 2023 11:23:51 AM
+
+
+
+
+`migrateTypes main` found 2 required patches: one in `src/test/scala/example/TypeIncompatTests.scala.scala` and the other in `src/main/scala/example/TypeIncompat.scala`.
+It applied them, then it compiled to Scala 3 with `-source:3.0-migration -rewrite` to finalize the migration.
+
+Congratulations! Your project can now compile to Scala 3.
-The command will display the following output:
-```
-> migrate main
-[info] We are going to migrate main / [Compile, Test] to 3.1.0
-2022.01.06 21:56:39 [INFO] migrate:24 - Found 1 required patch(es) in Incompat4.scala after 823 milliseconds ms
-2022.01.06 21:56:39 [INFO] compileWithRewrite:114 - Finalizing the migration: compiling in Scala 3 with -rewrite option
-[info]
-[info] main / Compile has been successfully migrated to Scala 3.1.0
-[info]
-[info] You can now commit the change!
-[info] Then you can permanently change the scalaVersion of main:
-[info]
-[info] crossScalaVersions += "3.1.0" // or
-[info] scalaVersion := "3.1.0"
-```
+## What to do next ?
-In this example, a file has been modified by adding some implicit parameters,
-implicit conversions or explicit result types.
+If you project contains only one module, you can set `scalaVersion := 3.3.1`.
-## What to do next ?
-If you project contains only one module, you're done. Depending on the nature of your project,
-you will either change permanently the `scalaVersion` of your project, or add Scala 3 to `crossScalaVerions`.
+If you have more than one module, you can start again from [3. Migrate the dependencies](#3-migrate-the-dependencies) with another module.
-If you have more than one module, you can start again with a second module `MODULE2`.
-if `MODULE2` depends on the last module migrated which is now compiling in Scala 3, you can either keep this module in Scala 3 and add `-Ytasty-reader` to `MODULE2 scalacOptions`,
-or `reload` the project to keep the migrated module on Scala 2 during the entire migration
-which implies cross-compiling during the process of the migration.
+Once you are done with all modules, you can remove `sbt-scala3-migrate` from `project/plugins.abt`, and all Scala 2.13 related settings.
-Once you are done, you can remove scala3-migrate from your plugins.
+## Feedback and contributions are welcome
-## Contributions and feedback are welcome
-The tool is still under development, and we would love to hear from you.
-Every feedback will help us build a better tool: typos, clearer log messages, better documentation,
-bug reports, ideas of features, so please open a [GitHub issue](https://github.com/scalacenter/scala3-migrate)
-or contact us on [discord](https://discord.com/invite/scala).
+Every feedback will help us improve `sbt-scala3-migrate`: typos, clearer log messages, better documentation,
+bug reports, ideas of features.
+Don't hesitate to open a [GitHub issue](https://github.com/scalacenter/scala3-migrate).
diff --git a/_overviews/scala3-migration/tooling-migration-mode.md b/_overviews/scala3-migration/tooling-migration-mode.md
index 96bd3597a9..183edeee7e 100644
--- a/_overviews/scala3-migration/tooling-migration-mode.md
+++ b/_overviews/scala3-migration/tooling-migration-mode.md
@@ -2,8 +2,8 @@
title: Scala 3 Migration Mode
type: chapter
description: This section describes the migration mode of the Scala 3 compiler
-num: 8
-previous-page: scala3-migrate
+num: 7
+previous-page: tooling-tour
next-page: tutorial-intro
---
@@ -22,7 +22,6 @@ where possible standard options include:
...
-explain Explain errors in more detail.
--explain-types Explain type errors in more detail.
...
-rewrite When used in conjunction with a `...-migration` source version, rewrites sources to migrate to new version.
...
@@ -45,7 +44,7 @@ Once your code compiles in the migration mode, almost all warnings can be resolv
To do so you just need to compile again, this time with the `-source:3.0-migration` and the `-rewrite` options.
> Beware that the compiler will modify the code! It is intended to be safe.
-> However you may like to commit the initial state so that you can print the diff applied by the compiler and revert it if necessary.
+> However you may want to commit the initial state so that you can print the diff applied by the compiler and revert it if necessary.
> #### Good to know
> - The rewrites are not applied if the code compiles in error.
diff --git a/_overviews/scala3-migration/tooling-tour.md b/_overviews/scala3-migration/tooling-tour.md
index dda576b594..eb8ec0a439 100644
--- a/_overviews/scala3-migration/tooling-tour.md
+++ b/_overviews/scala3-migration/tooling-tour.md
@@ -4,7 +4,7 @@ type: chapter
description: This chapter is a tour of the migration tooling ecosystem
num: 6
previous-page: compatibility-metaprogramming
-next-page: scala3-migrate
+next-page: tooling-migration-mode
---
## The Scala Compilers
@@ -42,9 +42,9 @@ Once your code is compiled in Scala 3 you can convert it to the new and optional
> The `sbt-dotty` plugin was needed in sbt 1.4 to get support for Scala 3.
> It is not useful anymore since sbt 1.5.
-sbt 1.5 supports Scala 3 out-of-the-box.
+sbt supports Scala 3 out-of-the-box.
All common tasks and settings are intended to work the same.
-Many plugins should also work exactly the same.
+Many sbt plugins should also work exactly the same.
To help with the migration, sbt 1.5 introduces new Scala 3 specific cross versions:
@@ -62,27 +62,24 @@ libraryDependency += ("org.bar" %% "bar" % "1.0.0").cross(CrossVersion.for2_13Us
### Maven
-Scala 3 support for Maven will soon land in the [scala-maven-plugin](https://github.com/davidB/scala-maven-plugin).
+The Scala Maven plugin supports Scala 3 since 4.5.1.
## Code editors and IDEs
### Metals
-[Metals](https://scalameta.org/metals/) is a Scala language server that works with VS Code, Vim, Emacs, Sublime Text, and other editors.
-
-Scala 3 is already very well supported by Metals.
-Some minor adjustments for the new syntax changes and new features are coming.
+[Metals](https://scalameta.org/metals/) is the Scala extension for VS Code.
+It also works with Vim, Emacs, Sublime Text, and other editors.
### IntelliJ IDEA
-The Scala plugin for IntelliJ includes preliminary support for Scala 3.
-Full-fledged support is being worked on by the team at JetBrains.
+The [Scala plugin for IntelliJ](https://plugins.jetbrains.com/plugin/1347-scala) supports Scala 3.
## Formatting Tools
### Scalafmt
-[Scalafmt](https://scalameta.org/scalafmt/) v3.0.0-RC3 supports both Scala 2.13 and Scala 3.
+[Scalafmt](https://scalameta.org/scalafmt/) supports Scala 2.13 and Scala 3 since v3.0.0.
To enable Scala 3 formatting you must set the `runner.dialect = scala3` in your `.scalafmt.conf` file.
@@ -97,13 +94,13 @@ fileOverride {
}
```
+Scalafmt can also enforce the new Scala 3 syntax with the [Scala 3 rewrites](https://scalameta.org/scalafmt/docs/configuration.html#scala3-rewrites).
+
## Migration Tools
### Scalafix
[Scalafix](https://scalacenter.github.io/scalafix/) is a refactoring tool for Scala.
-At the time of writing, it only runs on Scala 2.13.
-But it can be useful to prepare the code before jumping to Scala 3.
The [Incompatibility Table](incompatibility-table.html) shows which incompatibility can be fixed by an existing Scalafix rule.
So far the relevant rules are:
@@ -117,21 +114,17 @@ So far the relevant rules are:
You can apply these rules in sbt using the `sbt-scalafix` plugin.
They are also used internally in `sbt-scala3-migrate` described below.
-### The Scala 3 Migrate Plugin
+### The Scala 3 Migration Plugin for sbt
[Scala 3 Migrate](https://github.com/scalacenter/scala3-migrate) is an sbt plugin that can assist you during the migration to Scala 3.
-It proposes an incremental approach that can be described as follows:
-- Migrate the library dependencies:
- For every library dependency it checks, if there are available versions for Scala 3.
-- Migrate the Scala compiler options (`scalacOptions`):
- Some Scala 2 compiler options have been removed or renamed, others remain the same.
- This step helps you adapt the compiler options of your project.
-- Migrate the syntax:
- This step relies on Scalafix and existing rules to fix the deprecated syntax.
-- Migrate the code by expliciting the types:
- Scala 3 has a new type inference algorithm that may infer slightly different types than the Scala 2 inference.
- This last step explicits a minimum set of types so that the project can be compiled with Scala 3 without altering its runtime behavior.
+It proposes an incremental approach, based on four sbt commands:
+- `migrateDependencies` helps you update the list of `libraryDependencies`
+- `migrateScalacOptions` helps you update the list of `scalacOptions`
+- `migrateSyntax` fixes a number of syntax incompatibilities between Scala 2.13 and Scala 3
+- `migrateTypes` tries to code compile your code to Scala 3 by infering types and resolving implicits where needed.
+
+The detailed instructions on how to use Scala 3 Migrate can be found [here](scala3-migrate.html).
## Scaladex
diff --git a/_overviews/scala3-migration/tutorial-intro.md b/_overviews/scala3-migration/tutorial-intro.md
index 90f75161c4..4f207f5b92 100644
--- a/_overviews/scala3-migration/tutorial-intro.md
+++ b/_overviews/scala3-migration/tutorial-intro.md
@@ -2,7 +2,7 @@
title: Migration Tutorial
type: chapter
description: This chapter contains the tutorials for porting a Scala 2.13 project to Scala 3
-num: 9
+num: 8
previous-page: tooling-migration-mode
next-page: tutorial-prerequisites
---
@@ -10,11 +10,12 @@ next-page: tutorial-prerequisites
You are ready to port your project to Scala 3!
The first step is to check that the [Prerequisites](tutorial-prerequisites.html) are met by your project.
-Then you can go to the [Porting a sbt Project](tutorial-sbt.html) tutorial to learn about the migration workflow.
+
+If you use sbt we recommend you to go to [Porting an sbt Project (using sbt-scala3-migrate)](scala3-migrate.html), or you can go to [Porting an sbt Project (by hand)](tutorial-sbt.html).
> **You are not using sbt?**
>
-> We still advise you to read the [Porting a sbt Project](tutorial-sbt.html) tutorial since the workflow should be very similar.
+> We still advise you to read the [Porting a sbt Project (by hand)](tutorial-sbt.html) tutorial since the workflow is the same in other build tools.
> Prior to that, make sure the version of your build tool is up-to-date to support Scala 3.
diff --git a/_overviews/scala3-migration/tutorial-macro-cross-building.md b/_overviews/scala3-migration/tutorial-macro-cross-building.md
index 6a27f616b1..f9eec72757 100644
--- a/_overviews/scala3-migration/tutorial-macro-cross-building.md
+++ b/_overviews/scala3-migration/tutorial-macro-cross-building.md
@@ -24,7 +24,7 @@ In order to exemplify this tutorial, we will consider the minimal macro library
lazy val example = project
.in(file("example"))
.settings(
- scalaVersion := "2.13.6",
+ scalaVersion := "2.13.11",
libraryDependencies ++= Seq(
"org.scala-lang" % "scala-reflect" % scalaVersion.value
)
@@ -73,7 +73,7 @@ The main idea is to build the artifact twice and to publish two releases:
You can add Scala 3 to the list of `crossScalaVersions` of your project:
```scala
-crossScalaVersions := Seq("2.13.6", "3.0.0")
+crossScalaVersions := Seq("2.13.11", "3.3.1")
```
The `scala-reflect` dependency won't be useful in Scala 3.
@@ -91,15 +91,15 @@ libraryDependencies ++= {
}
```
-After reloading sbt, you can switch to the Scala 3 context by running `++3.0.0`.
-At any point you can go back to the Scala 2.13 context by running `++2.13.6`.
+After reloading sbt, you can switch to the Scala 3 context by running `++3.3.1`.
+At any point you can go back to the Scala 2.13 context by running `++2.13.11`.
## 2. Rearrange the code in version-specific source directories
If you try to compile with Scala 3 you should see some errors of the same kind as:
{% highlight text %}
-sbt:example> ++3.0.0
+sbt:example> ++3.3.1
sbt:example> example / compile
[error] -- Error: /example/src/main/scala/location/Location.scala:15:35
[error] 15 | val location = typeOf[Location]
@@ -222,13 +222,13 @@ class MacrosSpec extends munit.FunSuite {
You should now be able to run the tests in both versions.
{% highlight text %}
-sbt:example> ++2.13.6
+sbt:example> ++2.13.11
sbt:example> example / test
location.MacrosSpec:
+ location
[info] Passed: Total 1, Failed 0, Errors 0, Passed 1
[success]
-sbt:example> ++3.0.0
+sbt:example> ++3.3.1
sbt:example> example / test
location.MacrosSpec:
+ location
diff --git a/_overviews/scala3-migration/tutorial-macro-mixing.md b/_overviews/scala3-migration/tutorial-macro-mixing.md
index 10be2418a6..e7684adc7b 100644
--- a/_overviews/scala3-migration/tutorial-macro-mixing.md
+++ b/_overviews/scala3-migration/tutorial-macro-mixing.md
@@ -100,13 +100,13 @@ However, in many cases you will have to move the Scala 2.13 macro implementation
lazy val example = project.in(file("example"))
.settings(
- scalaVersion := "3.0.0"
+ scalaVersion := "3.3.1"
)
.dependsOn(`example-compat`)
lazy val `example-compat` = project.in(file("example-compat"))
.settings(
- scalaVersion := "2.13.6",
+ scalaVersion := "2.13.11",
libraryDependency += "org.scala-lang" % "scala-reflect" % scalaVersion.value
)
```
@@ -150,8 +150,8 @@ Since we want to execute the tests in Scala 2.13 and Scala 3, we create a cross-
// build.sbt
lazy val `example-test` = project.in(file("example-test"))
.settings(
- scalaVersion := "3.0.0",
- crossScalaVersions := Seq("3.0.0", "2.13.6"),
+ scalaVersion := "3.3.1",
+ crossScalaVersions := Seq("3.3.1", "2.13.11"),
scalacOptions ++= {
CrossVersion.partialVersion(scalaVersion.value) match {
case Some((2, 13)) => Seq("-Ytasty-reader")
@@ -185,13 +185,13 @@ class MacrosSpec extends munit.FunSuite {
You should now be able to run the tests in both versions.
{% highlight text %}
-sbt:example> ++2.13.6
+sbt:example> ++2.13.11
sbt:example> example-test / test
location.MacrosSpec:
+ location
[info] Passed: Total 1, Failed 0, Errors 0, Passed 1
[success]
-sbt:example> ++3.0.0
+sbt:example> ++3.3.1
sbt:example> example-test / test
location.MacrosSpec:
+ location
@@ -213,7 +213,7 @@ You are now ready to publish your library.
It can be used in Scala 3 projects, or in Scala 2.13 projects with these settings:
```scala
-scalaVersion := "2.13.6"
+scalaVersion := "2.13.11"
libraryDependencies += ("org" %% "example" % "x.y.z").cross(CrossVersion.for2_13Use3)
scalacOptions += "-Ytasty-reader"
```
diff --git a/_overviews/scala3-migration/tutorial-prerequisites.md b/_overviews/scala3-migration/tutorial-prerequisites.md
index 1fcbb14d4c..cdd96da785 100644
--- a/_overviews/scala3-migration/tutorial-prerequisites.md
+++ b/_overviews/scala3-migration/tutorial-prerequisites.md
@@ -2,9 +2,9 @@
title: Prerequisites
type: section
description: This section details the prerequisites of migration to Scala 3
-num: 10
+num: 9
previous-page: tutorial-intro
-next-page: tutorial-sbt
+next-page: scala3-migrate
---
The migration to Scala 3 is made easier thanks to the interoperability between Scala 2.13 and Scala 3, as described in the [Compatibility Reference](compatibility-intro.html) page.
diff --git a/_overviews/scala3-migration/tutorial-sbt.md b/_overviews/scala3-migration/tutorial-sbt.md
index c09f6e5e8d..78cd056d06 100644
--- a/_overviews/scala3-migration/tutorial-sbt.md
+++ b/_overviews/scala3-migration/tutorial-sbt.md
@@ -1,9 +1,9 @@
---
-title: Porting an sbt Project
+title: Porting an sbt Project (by hand)
type: section
description: This section shows how to port an sbt project
num: 11
-previous-page: tutorial-prerequisites
+previous-page: scala3-migrate
next-page: tutorial-macro-cross-building
---
@@ -43,16 +43,16 @@ This is crucial to avoid bugs that could happen when fixing the incompatibilitie
Configuring cross-building in sbt is as short as:
```scala
-scalaVersion := "3.0.0"
-crossScalaVersions ++= Seq("2.13.6", "3.0.0")
+scalaVersion := "3.3.1"
+crossScalaVersions ++= Seq("2.13.11", "3.3.1")
```
This configuration means:
-- The default version is `3.0.0`.
-- 2.13.6 can be loaded by running the `++2.13.6` command.
-- 3.0.0 can be loaded by running the `++3.0.0` command.
+- The default version is `3.3.1`.
+- 2.13.11 can be loaded by running the `++2.13.11` command.
+- 3.3.1 can be loaded by running the `++3.3.1` command.
-Beware that the `reload` command will always load the default version---here it is 3.0.0.
+Beware that the `reload` command will always load the default version---here it is 3.3.1.
## 4. Prepare the dependencies
@@ -89,8 +89,8 @@ Or for a Scala.js dependencies:
Once you have fixed all the unresolved dependencies, you can check that the tests are still passing in Scala 2.13:
{% highlight text %}
-sbt:example> ++2.13.6
-[info] Setting Scala version to 2.13.6 on 1 project.
+sbt:example> ++2.13.11
+[info] Setting Scala version to 2.13.11 on 1 project.
...
sbt:example> example / test
...
@@ -138,8 +138,8 @@ Also you should disable `-Xfatal-warnings` to take full advantage of the migrati
It is now time to try compiling in Scala 3:
{% highlight text %}
-sbt:example> ++3.0.0
-[info] Setting Scala version to 3.0.0 on 1 project.
+sbt:example> ++3.3.1
+[info] Setting Scala version to 3.3.1 on 1 project.
...
sbt:example> example / compile
...
@@ -171,8 +171,8 @@ This is particularly crucial if your project is a published library.
After fixing an incompatibility, you can validate the solution by running the tests in Scala 2.13.
{% highlight text %}
-sbt:example> ++2.13.6
-[info] Setting Scala version to 2.13.6 on 1 project.
+sbt:example> ++2.13.11
+[info] Setting Scala version to 2.13.11 on 1 project.
...
sbt:example> example / test
...
@@ -186,7 +186,7 @@ Only the migration warnings are remaining.
You can patch them automatically by compiling with the `-source:3.0-migration -rewrite` options.
{% highlight text %}
-sbt:example> ++3.0.0
+sbt:example> ++3.3.1
sbt:example> set example / scalacOptions += "-rewrite"
sbt:example> example / compile
...
@@ -206,11 +206,11 @@ Good tests are the only guarantee to prevent such bugs from going unnoticed.
Make sure that the tests are passing in both Scala 2.13 and Scala 3.
{% highlight text %}
-sbt:example> ++2.13.6
+sbt:example> ++2.13.11
sbt:example> example / test
...
[success]
-sbt:example> ++3.0.0
+sbt:example> ++3.3.1
sbt:example> example / test
...
[success]
diff --git a/resources/js/functions.js b/resources/js/functions.js
index efd41d00d5..322652b95a 100644
--- a/resources/js/functions.js
+++ b/resources/js/functions.js
@@ -65,7 +65,8 @@ $(document).ready(function() {
// Highlight
$(document).ready(function() {
hljs.configure({
- languages: ["scala", "bash"]
+ languages: ["scala", "bash"],
+ noHighlightRe: /^hljs-skip$/i
})
hljs.registerLanguage("scala", highlightDotty);
hljs.highlightAll();
+sbt:main> migrateTypes main
+[info] compiling 8 Scala sources to /home/piquerez/github/scalacenter/scala3-migration-example/target/scala-2.13/classes ...
+[warn] 1 deprecation; re-run with -deprecation for details
+[warn] one warning found
+[info] compiling 8 Scala sources to /home/piquerez/github/scalacenter/scala3-migration-example/target/scala-2.13/test-classes ...
+[warn] 2 deprecations; re-run with -deprecation for details
+[warn] one warning found
+[success] Total time: 7 s, completed Aug 31, 2023 11:26:25 AM
+[info] Defining scalaVersion
+[info] The new value will be used by Compile / bspBuildTarget, Compile / dependencyTreeCrossProjectId and 68 others.
+[info] Run `last` for details.
+[info] Reapplying settings...
+[info] set current project to main (in build file:/home/piquerez/github/scalacenter/scala3-migration-example/)
+[info]
+[info] Migrating types in main / Compile
+[info]
+[info] Found 3 patches in 1 Scala source
+[info] Starting migration of src/main/scala/example/TypeIncompat.scala
+[info] 3 remaining candidates
+[info] 1 remaining candidate
+[info] Found 1 required patch in src/main/scala/example/TypeIncompat.scala
+[info] Compiling to Scala 3 with -source:3.0-migration -rewrite
+[info] compiling 1 Scala source to /home/piquerez/github/scalacenter/scala3-migration-example/target/scala-3.3.1/classes ...
+[info]
+[info] Migrating types in main / Test
+[info]
+[info] Found 4 patches in 1 Scala source
+[info] Starting migration of src/test/scala/example/TypeIncompatTests.scala.scala
+[info] 4 remaining candidates
+[info] 3 remaining candidates
+[info] 2 remaining candidates
+[info] Found 1 required patch in src/test/scala/example/TypeIncompatTests.scala.scala
+[info] Compiling to Scala 3 with -source:3.0-migration -rewrite
+[info]
+[info] You can safely upgrade main to Scala 3:
+[info] scalaVersion := "3.3.1"
+[success] Total time: 18 s, completed Aug 31, 2023 11:26:45 AM
+[info] Defining scalaVersion
+[info] The new value will be used by Compile / bspBuildTarget, Compile / dependencyTreeCrossProjectId and 68 others.
+[info] Run `last` for details.
+[info] Reapplying settings...
+[info] set current project to main (in build file:/home/piquerez/github/scalacenter/scala3-migration-example/)
+sbt:main>
+
+