Skip to content

Commit 1c9d9bd

Browse files
committed
Change Scala 3 to Scala 2 only for some cases
1 parent 7d15e26 commit 1c9d9bd

File tree

1 file changed

+28
-29
lines changed

1 file changed

+28
-29
lines changed

_overviews/scala3-migration/incompat-other-changes.md

+28-29
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ Some other features are simplified or restricted to make the language easier, sa
2525
An inherited member, from a parent trait or class, can shadow an identifier defined in an outer scope.
2626
That pattern is called inheritance shadowing.
2727

28-
{% tabs scala-3-inheritance_1 %}
29-
{% tab 'Scala 3 Only' %}
28+
{% tabs shared-inheritance_1 %}
29+
{% tab 'Scala 2 and 3' %}
3030
~~~ scala
3131
object B {
3232
val x = 1
@@ -45,10 +45,9 @@ This is known for being error prone.
4545

4646
That's why, in Scala 3, the compiler requires disambiguation if the parent class `A` does actually have a member `x`.
4747

48-
{% tabs scala-3-inheritance_2 %}
49-
{% tab 'Scala 3 Only' %}
48+
{% tabs scala-2-inheritance_2 %}
49+
{% tab 'Scala 2 Only' %}
5050
It prevents the following piece of code from compiling.
51-
5251
~~~ scala
5352
class A {
5453
val x = 2
@@ -61,48 +60,49 @@ object B {
6160
}
6261
}
6362
~~~
63+
{% endtab %}
64+
{% endtabs %}
6465

65-
~~~ text
66+
But if you try to compile with Scala 3 you should see an error of the same kind as:
67+
{% highlight text %}
6668
-- [E049] Reference Error: src/main/scala/inheritance-shadowing.scala:9:14
6769
9 | println(x)
6870
| ^
6971
| Reference to x is ambiguous,
7072
| it is both defined in object B
7173
| and inherited subsequently in class C
72-
~~~
74+
{% endhighlight %}
7375

7476
The [Scala 3 migration compilation](tooling-migration-mode.html) can automatically disambiguate the code by replacing `println(x)` with `println(this.x)`.
75-
{% endtab %}
76-
{% endtabs %}
7777

7878
## Non-private Constructor In Private Class
7979

8080
The Scala 3 compiler requires the constructor of private classes to be private.
8181

82-
{% tabs scala-3-constructor_1 %}
83-
{% tab 'Scala 3 Only' %}
82+
{% tabs scala-2-constructor_1 %}
83+
{% tab 'Scala 2 Only' %}
8484
For instance, in the example:
8585

8686
~~~ scala
8787
package foo
8888

8989
private class Bar private[foo] () {}
9090
~~~
91+
{% endtab %}
92+
{% endtabs %}
9193

92-
The error message is:
93-
~~~ text
94+
If you try to compile in scala 3 you should get the following error message:
95+
{% highlight text %}
9496
-- Error: /home/piquerez/scalacenter/scala-3-migration-guide/incompat/access-modifier/src/main/scala-2.13/access-modifier.scala:4:19
9597
4 | private class Bar private[foo] ()
9698
| ^
9799
| non-private constructor Bar in class Bar refers to private class Bar
98100
| in its type signature (): foo.Foo.Bar
99-
~~~
101+
{% endhighlight %}
100102

101103
The [Scala 3 migration compilation](tooling-migration-mode.html) warns about this but no automatic rewrite is provided.
102104

103105
The solution is to make the constructor private, since the class is private.
104-
{% endtab %}
105-
{% endtabs %}
106106

107107
## Abstract Override
108108

@@ -149,7 +149,6 @@ Foo.tupled((2, false))
149149
{% tab 'Scala 3' for=companion_1 %}
150150

151151
A cross-compiling solution is to explicitly eta-expand the method `Foo.apply`.
152-
153152
~~~ scala
154153
case class Foo(x: Int, b: Boolean)
155154

@@ -187,8 +186,8 @@ case class Location(lat: Double, long: Double)
187186
{% endtab %}
188187
{% endtabs %}
189188

190-
{% tabs unapply_2 class=tabs-scala-version %}
191-
{% tab 'Scala 2' for=unapply_2 %}
189+
{% tabs scala-2-unapply_2 %}
190+
{% tab 'Scala 2 Only' %}
192191

193192
The Scala 2.13 compiler generates the following `unapply` method:
194193

@@ -198,7 +197,10 @@ object Location {
198197
}
199198
~~~
200199
{% endtab %}
201-
{% tab 'Scala 3' for=unapply_2 %}
200+
{% endtabs %}
201+
202+
{% tabs scala-3-unapply_2 %}
203+
{% tab 'Scala 3 Only' %}
202204

203205
Whereas the Scala 3 compiler generates:
204206
~~~ scala
@@ -223,15 +225,15 @@ A possible solution is to use pattern binding:
223225

224226
~~~ scala
225227
def tuple(location: Location): (Int, Int) = {
226-
Location.unapply(location).get
228+
Location.unapply(location).get
227229
}
228230
~~~
229231
{% endtab %}
230232
{% tab 'Scala 3' for=unaply_3 %}
231233
~~~ scala
232234
def tuple(location: Location): (Int, Int) = {
233-
val Location(lat, lon) = location
234-
(lat, lon)
235+
val Location(lat, lon) = location
236+
(lat, lon)
235237
}
236238
~~~
237239
{% endtab %}
@@ -291,9 +293,8 @@ A type of the form `=> T` cannot be used as an argument to a type parameter anym
291293
This decision is explained in [this comment](https://github.com/lampepfl/dotty/blob/0f1a23e008148f76fd0a1c2991b991e1dad600e8/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala#L144-L152) of the Scala 3 source code.
292294

293295
For instance, it is not allowed to pass a function of type `Int => (=> Int) => Int` to the `uncurried` method since it would assign `=> Int` to the type parameter `T2`.
294-
{% tabs scala-3-type_1 %}
295-
{% tab 'Scala 3 Only' %}
296-
~~~ scala
296+
297+
{% highlight text %}
297298
-- [E134] Type Mismatch Error: src/main/scala/by-name-param-type-infer.scala:3:41
298299
3 | val g: (Int, => Int) => Int = Function.uncurried(f)
299300
| ^^^^^^^^^^^^^^^^^^
@@ -304,9 +305,7 @@ For instance, it is not allowed to pass a function of type `Int => (=> Int) => I
304305
| [T1, T2, T3, R](f: T1 => T2 => T3 => R): (T1, T2, T3) => R
305306
| [T1, T2, R](f: T1 => T2 => R): (T1, T2) => R
306307
|match arguments ((Test.f : Int => (=> Int) => Int))
307-
~~~
308-
{% endtab %}
309-
{% endtabs %}
308+
{% endhighlight %}
310309

311310
The solution depends on the situation. In the given example, you can either:
312311
- define your own `uncurried` method with the appropriate signature

0 commit comments

Comments
 (0)