Skip to content

Commit f031f2e

Browse files
authored
Merge pull request #13628 from dotty-staging/fix-8702
2 parents 3b5ff7a + 222dc19 commit f031f2e

File tree

2 files changed

+65
-6
lines changed

2 files changed

+65
-6
lines changed

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

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -216,14 +216,10 @@ type errors. If there is a stack overflow during subtyping, the exception will
216216
be caught and turned into a compile-time error that indicates a trace of the
217217
subtype tests that caused the overflow without showing a full stack trace.
218218

219-
## Variance Laws for Match Types
220219

221-
**Note:** This section does not reflect the current implementation.
220+
## Match Types Variance
222221

223-
Within a match type `Match(S, Cs) <: B`, all occurrences of type variables count
224-
as covariant. By the nature of the cases `Ci` this means that occurrences in
225-
pattern position are contravariant (since patterns are represented as function
226-
type arguments).
222+
All type positions in a match type (scrutinee, patterns, bodies) are considered invariant.
227223

228224
## Related Work
229225

tests/neg/8702.scala

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
// All three All type positions in a match type (scrutinee, patterns, bodies)
2+
// are considered invariant, as showed by the following examples:
3+
4+
trait TA[+Plus] { type M[X] = Plus match { case Int => String } } // error
5+
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
// covariant type Plus occurs in invariant position in type [X] =
7+
// Plus match {
8+
// case Int => String
9+
// } of type M
10+
11+
trait TB[+Plus] { type M[X] = X match { case Plus => String } } // error
12+
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
13+
// covariant type Plus occurs in invariant position in type [X] =
14+
// X match {
15+
// case Plus => String
16+
// } of type M
17+
18+
trait TC[+Plus] { type M[X] = X match { case Int => Plus } } // error
19+
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
20+
// covariant type Plus occurs in invariant position in type [X] =
21+
// X match {
22+
// case Int => Plus
23+
// } of type M
24+
25+
trait TD[-Minus] { type M[X] = Minus match { case Int => String } } // error
26+
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
27+
// contravariant type Minus occurs in invariant position in type [X] =
28+
// Minus match {
29+
// case Int => String
30+
// } of type M
31+
32+
trait TE[-Minus] { type M[X] = X match { case Minus => String } } // error
33+
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
34+
// contravariant type Minus occurs in invariant position in type [X] =
35+
// X match {
36+
// case Minus => String
37+
// } of type M
38+
39+
trait TF[-Minus] { type M[X] = X match { case Int => Minus } } // error
40+
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
41+
// contravariant type Minus occurs in invariant position in type [X] =
42+
// X match {
43+
// case Int => Minus
44+
// } of type M
45+
46+
// Furthermore, both unannotated type parameters and unannotated type bindings
47+
// in patterns are invariant, as showed by the following examples:
48+
49+
trait Cov[+X]
50+
trait Contra[-X]
51+
52+
// As usual:
53+
type Test0[X] = Cov[X] // OK
54+
type Test1[X] = Contra[X] // OK
55+
type Test2[+X] = Contra[X] // error: covariant type parameter X occurs in
56+
// in contravariant position in Contra[X]
57+
type Test3[-X] = Cov[X] // error: contravariant type parameter X occurs in
58+
// covariant position in Cov[X]
59+
60+
type M0[X] = X match { case Int => Cov[X] }
61+
type M1[X] = X match { case Int => Contra[X] }
62+
type M2[X] = X match { case Cov[x] => Contra[x] }
63+
type M3[X] = X match { case Contra[x] => Cov[x] }

0 commit comments

Comments
 (0)