diff --git a/_overviews/scala3-migration/incompat-dropped-features.md b/_overviews/scala3-migration/incompat-dropped-features.md
index 26e4d84ced..ae7e3e3f1e 100644
--- a/_overviews/scala3-migration/incompat-dropped-features.md
+++ b/_overviews/scala3-migration/incompat-dropped-features.md
@@ -27,14 +27,17 @@ But the `scala.Symbol` class still exists so that each string literal can be saf
This piece of code cannot be compiled with Scala 3:
-```scala
+{% tabs scala-2-literals_1 %}
+{% tab 'Scala 2 Only' %}
+~~~ scala
val values: Map[Symbol, Int] = Map('abc -> 1)
-val abc = values('abc) // Migration Warning: symbol literal 'abc is no longer supported
-```
+val abc = values('abc) // In Scala 3, Migration Warning: symbol literal 'abc is no longer supported
+~~~
+{% endtab %}
+{% endtabs %}
The [Scala 3 migration compilation](tooling-migration-mode.html) rewrites the code into:
-
{% highlight diff %}
val values: Map[Symbol, Int] = Map(Symbol("abc") -> 1)
@@ -54,19 +57,26 @@ It is recommended to use the equivalent `while ({
; }) ()` that can
The following piece of code cannot be compiled with Scala 3.
-```scala
-do { // Migration Warning: `do while ` is no longer supported
+{% tabs scala-2-do_while_1 %}
+{% tab 'Scala 2 Only' %}
+~~~ scala
+do { // In Scala 3, Migration Warning: `do while ` is no longer supported
i += 1
} while (f(i) == 0)
-```
+~~~
+{% endtab %}
+{% endtabs %}
The [Scala 3 migration compilation](tooling-migration-mode.html) rewrites it into.
-
-```scala
+{% tabs scala-3-do_while_2 %}
+{% tab 'Scala 3 Only' %}
+~~~ scala
while ({ {
i += 1
} ; f(i) == 0}) ()
-```
+~~~
+{% endtab %}
+{% endtabs %}
## Auto-application
@@ -75,16 +85,19 @@ It is deprecated in Scala 2.13 and dropped in Scala 3.
The following code is invalid in Scala 3:
-```scala
+{% tabs scala-2-auto_application_1 %}
+{% tab 'Scala 2 Only' %}
+~~~ scala
object Hello {
def message(): String = "Hello"
}
-println(Hello.message) // Migration Warning: method message must be called with () argument
-```
+println(Hello.message) // In Scala 3, Migration Warning: method message must be called with () argument
+~~~
+{% endtab %}
+{% endtabs %}
The [Scala 3 migration compilation](tooling-migration-mode.html) rewrites it into:
-
{% highlight diff %}
object Hello {
def message(): String = "Hello"
@@ -103,13 +116,16 @@ Furthermore Scala 3 does not allow eta-expansion of values to nullary functions
Thus, this piece of code is invalid in Scala 3:
-```scala
+{% tabs scala-2-eta_expansion_1 %}
+{% tab 'Scala 2 Only' %}
+~~~ scala
val x = 1
-val f: () => Int = x _ // Migration Warning: The syntax ` _` is no longer supported;
-```
+val f: () => Int = x _ // In Scala 3, Migration Warning: The syntax ` _` is no longer supported;
+~~~
+{% endtab %}
+{% endtabs %}
The [Scala 3 migration compilation](tooling-migration-mode.html) rewrites it into:
-
{% highlight diff %}
val x = 1
-val f: () => Int = x _
@@ -120,14 +136,17 @@ val x = 1
The implicit `Predef.any2stringadd` conversion is deprecated in Scala 2.13 and dropped in Scala 3.
-This piece of code does not compile anymore.
+This piece of code does not compile anymore in Scala 3.
-```scala
-val str = new AnyRef + "foo" // Error: value + is not a member of Object
-```
+{% tabs scala-2-any2stringadd_1 %}
+{% tab 'Scala 2 Only' %}
+~~~ scala
+val str = new AnyRef + "foo" // In Scala 3, Error: value + is not a member of Object
+~~~
+{% endtab %}
+{% endtabs %}
The conversion to `String` must be applied explicitly, for instance with `String.valueOf`.
-
{% highlight diff %}
-val str = new AnyRef + "foo"
+val str = String.valueOf(new AnyRef) + "foo"
@@ -140,9 +159,11 @@ This rewrite can be applied by the `fix.scala213.Any2StringAdd` Scalafix rule in
Early initializers are deprecated in Scala 2.13 and dropped in Scala 3.
They were rarely used, and mostly to compensate for the lack of [Trait parameters]({{ site.scala3ref }}/other-new-features/trait-parameters.html) which are now supported in Scala 3.
-That is why the following piece of code does not compile anymore.
+That is why the following piece of code does not compile anymore in Scala 3.
-```scala
+{% tabs scala-2-initializer_1 %}
+{% tab 'Scala 2 Only' %}
+~~~ scala
trait Bar {
val name: String
val size: Int = name.size
@@ -151,7 +172,9 @@ trait Bar {
object Foo extends {
val name = "Foo"
} with Bar
-```
+~~~
+{% endtab %}
+{% endtabs %}
The Scala 3 compiler produces two error messages:
@@ -161,7 +184,6 @@ The Scala 3 compiler produces two error messages:
| ^
| `extends` must be followed by at least one parent
{% endhighlight %}
-
{% highlight text %}
-- [E009] Syntax Error: src/main/scala/early-initializer.scala:8:2
8 |} with Bar
@@ -171,51 +193,66 @@ The Scala 3 compiler produces two error messages:
It suggests to use trait parameters which would give us:
-```scala
+{% tabs scala-3-initializer_2 %}
+{% tab 'Scala 3 Only' %}
+~~~ scala
trait Bar(name: String) {
val size: Int = name.size
}
object Foo extends Bar("Foo")
-```
+~~~
+{% endtab %}
+{% endtabs %}
Since trait parameters are not available in Scala 2.13, it does not cross-compile.
If you need a cross-compiling solution you can use an intermediate class that carries the early initialized `val`s and `var`s as constructor parameters.
-```scala
+{% tabs shared-initializer_4 %}
+{% tab 'Scala 2 and 3' %}
+~~~ scala
abstract class BarEarlyInit(val name: String) extends Bar
object Foo extends BarEarlyInit("Foo")
-```
+~~~
In the case of a class, it is also possible to use a secondary constructor with a fixed value, as shown by:
-
-```scala
+~~~ scala
class Fizz private (val name: String) extends Bar {
def this() = this("Fizz")
}
-```
+~~~
+{% endtab %}
+{% endtabs %}
## Existential Type
Existential type is a [dropped feature]({{ site.scala3ref }}/dropped-features/existential-types.html), which makes the following code invalid.
-
-```scala
-def foo: List[Class[T]] forSome { type T } // Error: Existential types are no longer supported
-```
+
+{% tabs scala-2-existential_1 %}
+{% tab 'Scala 2 Only' %}
+~~~ scala
+def foo: List[Class[T]] forSome { type T } // In Scala 3, Error: Existential types are no longer supported
+~~~
+{% endtab %}
+{% endtabs %}
> Existential type is an experimental feature in Scala 2.13 that must be enabled explicitly either by importing `import scala.language.existentials` or by setting the `-language:existentials` compiler flag.
-The proposed solution is to introduce an enclosing type that carries the dependent type:
+In Scala 3, the proposed solution is to introduce an enclosing type that carries the dependent type:
-```scala
+{% tabs shared-existential_1 %}
+{% tab 'Scala 2 and 3' %}
+~~~ scala
trait Bar {
type T
val value: List[Class[T]]
}
def foo: Bar
-```
+~~~
+{% endtab %}
+{% endtabs %}
Note that using a wildcard argument, `_` or `?`, is often simpler but is not always possible.
For instance you could replace `List[T] forSome { type T }` by `List[?]`.