Skip to content

Commit 872d052

Browse files
Restore text on termination
1 parent 4cb631d commit 872d052

File tree

1 file changed

+31
-0
lines changed

1 file changed

+31
-0
lines changed

docs/docs/reference/new-types/match-types.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,37 @@ The third rule states that a match type conforms to its upper bound:
147147
(S match { P1 => T1 ... Pn => Tn } <: B) <: B
148148
```
149149

150+
## Termination
151+
152+
Match type definitions can be recursive, which means that it's possible to run
153+
into an infinite loop while reducing match types.
154+
155+
Since reduction is linked to subtyping, we already have a cycle detection mechanism in place.
156+
So the following will already give a reasonable error message:
157+
158+
```scala
159+
type L[X] = X match {
160+
case Int => L[X]
161+
}
162+
def g[X]: L[X] = ???
163+
```
164+
165+
```scala
166+
| val x: Int = g[Int]
167+
| ^
168+
|Recursion limit exceeded.
169+
|Maybe there is an illegal cyclic reference?
170+
|If that's not the case, you could also try to increase the stacksize using the -Xss JVM option.
171+
|A recurring operation is (inner to outer):
172+
|
173+
| subtype LazyRef(Test.L[Int]) <:< Int
174+
```
175+
176+
Internally, `dotc` detects these cycles by turning selected stackoverflows
177+
into type errors. If there is a stackoverflow during subtyping, the exception
178+
will be caught and turned into a compile-time error that indicates a trace of
179+
the subtype tests that caused the overflow without showing a full stacktrace.
180+
150181
## Variance Laws for Match Types
151182

152183
Within a match type `Match(S, Cs) <: B`, all occurrences of type variables count as covariant. By the nature of the cases `Ci` this means that occurrences in pattern position are contravarant (since patterns are represented as function type arguments).

0 commit comments

Comments
 (0)