Skip to content

Commit e13a99a

Browse files
Merge pull request #10811 from ShapelessCat/fix-docs-format
Fix the layout part of the matchable.md
2 parents 3e471ab + 1e04a23 commit e13a99a

File tree

1 file changed

+14
-5
lines changed

1 file changed

+14
-5
lines changed

docs/docs/reference/other-new-features/matchable.md

+14-5
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
---
12
layout: doc-page
23
title: The Matchable Trait
34
---
@@ -12,21 +13,26 @@ arrays that is defined like this:
1213
```scala
1314
opaque type IArray[+T] = Array[_ <: T]
1415
```
16+
1517
The `IArray` type offers extension methods for `length` and `apply`, but not for `update`; hence it seems values of type `IArray` cannot be updated.
1618

1719
However, there is a potential hole due to pattern matching. Consider:
20+
1821
```scala
1922
val imm: IArray[Int] = ...
2023
imm match
2124
case a: Array[Int] => a(0) = 1
2225
```
26+
2327
The test will succeed at runtime since `IArray`s _are_ represented as
2428
`Array`s at runtime. But if we allowed it, it would break the fundamental abstraction of immutable arrays.
2529

2630
__Aside:__ One could also achieve the same by casting:
31+
2732
```scala
2833
imm.asInstanceOf[Array[Int]](0) = 1
2934
```
35+
3036
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.
3137

3238
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
3743
case a: Array[Int] => a(0) = 0
3844
f(imm)
3945
```
46+
4047
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.
4148

4249
### The Solution
4350

4451
There is a new type `scala.Matchable` that controls pattern matching. When typing a pattern match of a constructor pattern `C(...)` or
4552
a type pattern `_: C` it is required that the selector type conforms
4653
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:
54+
4755
```
4856
> sc ../new/test.scala -source 3.1
4957
-- Warning: ../new/test.scala:4:12 ---------------------------------------------
@@ -52,18 +60,20 @@ to `Matchable`. If that's not the case a warning is issued. For instance when co
5260
| pattern selector should be an instance of Matchable,
5361
| but it has unmatchable type IArray[Int] instead
5462
```
63+
5564
To allow migration from Scala 2 and cross-compiling
5665
between Scala 2 and 3 the warning is turned on only for `-source 3.1-migration` or higher.
5766

5867
`Matchable` is a universal trait with `Any` as its parent class. It is
5968
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:
6069

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.
6574

6675
Here is the hierarchy of toplevel classes and traits with their defined methods:
76+
6777
```scala
6878
abstract class Any:
6979
def getClass
@@ -84,4 +94,3 @@ class Object extends Any, Matchable
8494

8595
`Matchable` is currently a marker trait without any methods. Over time
8696
we might migrate methods `getClass` and `isInstanceOf` to it, since these are closely related to pattern-matching.
87-

0 commit comments

Comments
 (0)