You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/docs/reference/other-new-features/matchable.md
+14-5
Original file line number
Diff line number
Diff line change
@@ -1,3 +1,4 @@
1
+
---
1
2
layout: doc-page
2
3
title: The Matchable Trait
3
4
---
@@ -12,21 +13,26 @@ arrays that is defined like this:
12
13
```scala
13
14
opaquetypeIArray[+T] =Array[_ <:T]
14
15
```
16
+
15
17
The `IArray` type offers extension methods for `length` and `apply`, but not for `update`; hence it seems values of type `IArray` cannot be updated.
16
18
17
19
However, there is a potential hole due to pattern matching. Consider:
20
+
18
21
```scala
19
22
valimm:IArray[Int] = ...
20
23
imm match
21
24
casea: Array[Int] => a(0) =1
22
25
```
26
+
23
27
The test will succeed at runtime since `IArray`s _are_ represented as
24
28
`Array`s at runtime. But if we allowed it, it would break the fundamental abstraction of immutable arrays.
25
29
26
30
__Aside:__ One could also achieve the same by casting:
31
+
27
32
```scala
28
33
imm.asInstanceOf[Array[Int]](0) =1
29
34
```
35
+
30
36
But that is not as much of a problem since in Scala `asInstanceOf` is understood to be low-level and unsafe. By contrast, a pattern match that compiles without warning or error should not break abstractions.
31
37
32
38
Note also that the problem is not tied to opaque types as match selectors. The following slight variant with a value of parametric
@@ -37,13 +43,15 @@ def f[T](x: T) = x match
37
43
casea: Array[Int] => a(0) =0
38
44
f(imm)
39
45
```
46
+
40
47
Finally, note that the problem is not linked to just opaque types. No unbounded type parameter or abstract type should be decomposable with a pattern match.
41
48
42
49
### The Solution
43
50
44
51
There is a new type `scala.Matchable` that controls pattern matching. When typing a pattern match of a constructor pattern `C(...)` or
45
52
a type pattern `_: C` it is required that the selector type conforms
46
53
to `Matchable`. If that's not the case a warning is issued. For instance when compiling the example at the start of this section we get:
@@ -52,18 +60,20 @@ to `Matchable`. If that's not the case a warning is issued. For instance when co
52
60
| pattern selector should be an instance of Matchable,
53
61
| but it has unmatchable type IArray[Int] instead
54
62
```
63
+
55
64
To allow migration from Scala 2 and cross-compiling
56
65
between Scala 2 and 3 the warning is turned on only for `-source 3.1-migration` or higher.
57
66
58
67
`Matchable` is a universal trait with `Any` as its parent class. It is
59
68
extended by both `AnyVal` and `AnyRef`. Since `Matchable` is a supertype of every concrete value or reference class it means that instances of such classes can be matched as before. However, match selectors of the following types will produce a warning:
60
69
61
-
- Type `Any`: if pattern matching is required one should use `Matchable` instead.
62
-
- Unbounded type parameters and abstract types: If pattern matching is required they should have an upper bound `Matchable`.
63
-
- Type parameters and abstract types that are only bounded by some
64
-
universal trait: Again, `Matchable` should be added as a bound.
70
+
- Type `Any`: if pattern matching is required one should use `Matchable` instead.
71
+
- Unbounded type parameters and abstract types: If pattern matching is required they should have an upper bound `Matchable`.
72
+
- Type parameters and abstract types that are only bounded by some
73
+
universal trait: Again, `Matchable` should be added as a bound.
65
74
66
75
Here is the hierarchy of toplevel classes and traits with their defined methods:
76
+
67
77
```scala
68
78
abstractclassAny:
69
79
defgetClass
@@ -84,4 +94,3 @@ class Object extends Any, Matchable
84
94
85
95
`Matchable` is currently a marker trait without any methods. Over time
86
96
we might migrate methods `getClass` and `isInstanceOf` to it, since these are closely related to pattern-matching.
0 commit comments