Skip to content

Commit d86b09d

Browse files
committed
Don't expand match aliases in variance checking
They might be recursive, so we can't blindly expand them for variance checking. Instead use normalize to follow possible reductions.
1 parent 64d613b commit d86b09d

File tree

3 files changed

+60
-21
lines changed

3 files changed

+60
-21
lines changed

compiler/src/dotty/tools/dotc/typer/VarianceChecker.scala

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ object VarianceChecker {
3434
val paramVarianceStr = if (v == 0) "contra" else "co"
3535
val occursStr = variance match {
3636
case -1 => "contra"
37-
case 0 => "non"
37+
case 0 => "in"
3838
case 1 => "co"
3939
}
4040
val pos = tree.tparams
@@ -123,18 +123,19 @@ class VarianceChecker()(implicit ctx: Context) {
123123
def apply(status: Option[VarianceError], tp: Type): Option[VarianceError] = trace(s"variance checking $tp of $base at $variance", variances) {
124124
try
125125
if (status.isDefined) status
126-
else tp match {
126+
else tp.normalized match {
127127
case tp: TypeRef =>
128128
val sym = tp.symbol
129129
if (sym.variance != 0 && base.isContainedIn(sym.owner)) checkVarianceOfSymbol(sym)
130-
else if (sym.isAliasType) this(status, sym.info.bounds.hi)
131-
else foldOver(status, tp)
130+
else sym.info match {
131+
case MatchAlias(_) => foldOver(status, tp)
132+
case TypeAlias(alias) => this(status, alias)
133+
case _ => foldOver(status, tp)
134+
}
132135
case tp: MethodOrPoly =>
133136
this(status, tp.resultType) // params will be checked in their TypeDef or ValDef nodes.
134137
case AnnotatedType(_, annot) if annot.symbol == defn.UncheckedVarianceAnnot =>
135138
status
136-
case tp: MatchType =>
137-
apply(status, tp.bound)
138139
case tp: ClassInfo =>
139140
foldOver(status, tp.classParents)
140141
case _ =>

tests/neg/i6047.scala

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,36 @@
1-
type Id[+X] = X match { // error: covariant type X appears in nonvariant position
1+
type Id[+X] = X match { // error: covariant type X appears in invariant position
22
case Int => Int
33
case String => String
44
}
5-
type T1[+X, Y] = Y match { // error: covariant type X appears in nonvariant position
5+
type T1[+X, Y] = Y match { // error: covariant type X appears in invariant position
66
case List[X] => Int
77
case _ => String
88
}
9-
type T2[+X, Y] = Y match { // error: covariant type X appears in nonvariant position
9+
type T2[+X, Y] = Y match { // error: covariant type X appears in invariant position
1010
case List[_ >: X] => Int
1111
case _ => String
1212
}
13-
type T3[+X, Y] = Y match { // error: covariant type X appears in nonvariant position
13+
type T3[+X, Y] = Y match { // error: covariant type X appears in invariant position
1414
case List[_ <: X] => Int
1515
case _ => String
1616
}
17-
type Id2[-X] = X match { // error: contravariant type X appears in nonvariant position
17+
type Id2[-X] = X match { // error: contravariant type X appears in invariant position
1818
case Int => Int
1919
case String => String
2020
}
21-
type T4[+X, Y] = Y match { // error: contravariant type X appears in nonvariant position
21+
type T4[-X, Y] = Y match { // error: contravariant type X appears in invariant position
2222
case List[X] => Int
2323
case _ => String
2424
}
25-
type T5[+X, Y] = Y match { // error: contravariant type X appears in nonvariant position
25+
type T5[-X, Y] = Y match { // error: contravariant type X appears in invariant position
2626
case List[_ >: X] => Int
2727
case _ => String
2828
}
29-
type T6[+X, Y] = Y match { // error: contravariant type X appears in nonvariant position
29+
type T6[-X, Y] = Y match { // error: contravariant type X appears in invariant position
3030
case List[_ <: X] => Int
3131
case _ => String
3232
}
3333
type T7[-X, Y] = Y match { // error: contravariant type X appears in covariant position
3434
case List[_] => X
3535
case _ => String
3636
}
37-
38-
class C[+X] {
39-
type Id = X match {
40-
case Int => Int
41-
case String => String
42-
}
43-
}

tests/neg/i6047a.scala

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
class C[+X] {
2+
type Id = X match { // error: covariant type X appears in invariant position
3+
case Int => Int
4+
case String => String
5+
}
6+
7+
type T1[Y] = Y match { // error: covariant type X appears in invariant position
8+
case List[X] => Int
9+
case _ => String
10+
}
11+
type T2[Y] = Y match { // error: covariant type X appears in invariant position
12+
case List[_ >: X] => Int
13+
case _ => String
14+
}
15+
type T3[Y] = Y match { // error: covariant type X appears in invariant position
16+
case List[_ <: X] => Int
17+
case _ => String
18+
}
19+
20+
def foo[Y <: X](): Unit = ??? // error: covariant type X appears in contravariant position
21+
type Foo[Y <: X] <: Y // error: covariant type X appears in contravariant position
22+
}
23+
class D[-X] {
24+
25+
type Id2 = X match { // error: contravariant type X appears in invariant position
26+
case Int => Int
27+
case String => String
28+
}
29+
type T4[Y] = Y match { // error: contravariant type X appears in invariant position
30+
case List[X] => Int
31+
case _ => String
32+
}
33+
type T5[Y] = Y match { // error: contravariant type X appears in invariant position
34+
case List[_ >: X] => Int
35+
case _ => String
36+
}
37+
type T6[Y] = Y match { // error: contravariant type X appears in invariant position
38+
case List[_ <: X] => Int
39+
case _ => String
40+
}
41+
type T7[Y] = Y match { // error: contravariant type X appears in covariant position
42+
case List[_] => X
43+
case _ => String
44+
}
45+
}

0 commit comments

Comments
 (0)