@@ -18,16 +18,21 @@ It is unsound and might cause runtime failures, as demonstrated by this [test](h
18
18
19
19
The Scala 3 compiler does not permit this anymore.
20
20
21
- ``` scala
21
+ {% tabs scala-2-unsound_vc_1 %}
22
+ {% tab 'Scala 2 Only' %}
23
+ ~~~ scala
22
24
class Foo [- A ](x : List [A ]) {
23
25
def f [B ](y : List [B ] = x): Unit = ???
24
26
}
25
27
26
28
class Outer [+ A ](x : A ) {
27
29
class Inner (y : A )
28
30
}
29
- ```
31
+ ~~~
32
+ {% endtab %}
33
+ {% endtabs %}
30
34
35
+ So if you compile in Scala 3, you will get the following error.
31
36
{% highlight text %}
32
37
-- Error: src/main/scala/variance.scala:2:8
33
38
2 | def f[ B] (y: List[ B] = x): Unit = y
@@ -75,7 +80,9 @@ Scala 3 fixes some unsoundness bugs in pattern matching, preventing some semanti
75
80
76
81
For instance, the match expression in ` combineReq ` can be compiled with Scala 2.13 but not with Scala 3.
77
82
78
- ``` scala
83
+ {% tabs scala-2-unsound_pm_1 %}
84
+ {% tab 'Scala 2 Only' %}
85
+ ~~~ scala
79
86
trait Request
80
87
case class Fetch [A ](ids : Set [A ]) extends Request
81
88
@@ -88,9 +95,11 @@ object Request {
88
95
}
89
96
}
90
97
}
91
- ```
98
+ ~~~
99
+ {% endtab %}
100
+ {% endtabs %}
92
101
93
- The error message is:
102
+ In Scala 3, the error message is:
94
103
95
104
{% highlight text %}
96
105
-- [ E007] Type Mismatch Error: src/main/scala/pattern-match.scala:9:59
@@ -100,6 +109,7 @@ The error message is:
100
109
| Required: Fetch[ A$1]
101
110
{% endhighlight %}
102
111
112
+
103
113
Which is right, there is no proof that ` x ` and ` y ` have the same type parameter ` A ` .
104
114
105
115
Coming from Scala 2, this is clearly an improvement to help us locate mistakes in our code.
@@ -108,9 +118,13 @@ It is not always easy and sometimes it is even not possible, in which case the c
108
118
109
119
In this example, we can relax the constraint on ` x ` and ` y ` by stating that ` A ` is a common ancestor of both type arguments.
110
120
This makes the compiler type-check the code successfully.
111
-
112
- ``` scala
121
+ {% tabs shared-unsound_pm_2 %}
122
+ {% tab 'Scala 2 and 3' %}
123
+ ~~~ scala
113
124
def combineFetch [A ](x : Fetch [_ <: A ], y : Fetch [_ <: A ]): Fetch [A ] = Fetch (x.ids ++ y.ids)
114
- ```
125
+ ~~~
126
+ {% endtab %}
127
+ {% endtabs %}
115
128
116
129
Alternatively, a general but unsafe solution is to cast.
130
+
0 commit comments