Skip to content

Commit a1edf01

Browse files
Simplify MT reduction algorithm
By removing the widenAbstractTypes step, which is subsumed by the provably empty test.
1 parent 7d3ba8f commit a1edf01

File tree

4 files changed

+63
-81
lines changed

4 files changed

+63
-81
lines changed

compiler/src/dotty/tools/dotc/core/TypeComparer.scala

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2409,34 +2409,6 @@ class TrackingTypeComparer(initctx: Context) extends TypeComparer(initctx) {
24092409
case _ =>
24102410
cas
24112411
}
2412-
def widenAbstractTypes(tp: Type): Type = new TypeMap {
2413-
var seen = Set[TypeParamRef]()
2414-
def apply(tp: Type) = tp match {
2415-
case tp: TypeRef =>
2416-
tp.info match {
2417-
case info: MatchAlias =>
2418-
mapOver(tp)
2419-
// TODO: We should follow the alias in this case, but doing so
2420-
// risks infinite recursion
2421-
case TypeBounds(lo, hi) =>
2422-
if (hi frozen_<:< lo) {
2423-
val alias = apply(lo)
2424-
if (alias ne lo) alias else mapOver(tp)
2425-
}
2426-
else WildcardType
2427-
case _ =>
2428-
mapOver(tp)
2429-
}
2430-
case tp: TypeLambda =>
2431-
val saved = seen
2432-
seen ++= tp.paramRefs
2433-
try mapOver(tp)
2434-
finally seen = saved
2435-
case tp: TypeVar if !tp.isInstantiated => WildcardType
2436-
case tp: TypeParamRef if !seen.contains(tp) => WildcardType
2437-
case _ => mapOver(tp)
2438-
}
2439-
}.apply(tp)
24402412

24412413
val defn.MatchCase(pat, body) = cas1
24422414

@@ -2451,8 +2423,6 @@ class TrackingTypeComparer(initctx: Context) extends TypeComparer(initctx) {
24512423
body
24522424
}
24532425
}
2454-
else if (isSubType(widenAbstractTypes(scrut), widenAbstractTypes(pat)))
2455-
Some(NoType)
24562426
else if (provablyDisjoint(scrut, pat))
24572427
// We found a proof that `scrut` and `pat` are incompatible.
24582428
// The search continues.

tests/neg-custom-args/matchtype-loop.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ object Test {
22
type L[X] = X match {
33
case Int => L[X]
44
}
5-
type LL[X] = X match { // error: recursion limit exceeded
5+
type LL[X] = X match {
66
case Int => LL[LL[X]]
77
}
88
def a: L[Boolean] = ???

tests/neg/6314-6.scala

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
final class X
2+
final class Y
3+
4+
object Test3 {
5+
type Bar[A] = A match {
6+
case X => String
7+
case Y => Int
8+
}
9+
10+
trait XX {
11+
type Foo
12+
13+
val a: Bar[X & Foo] = "hello"
14+
val b: Bar[Y & Foo] = 1
15+
16+
def apply(fa: Bar[X & Foo]): Bar[Y & Foo]
17+
18+
def boom: Int = apply(a)
19+
}
20+
21+
trait YY extends XX {
22+
type Foo = X & Y
23+
24+
def apply(fa: Bar[X & Foo]): Bar[Y & Foo] = fa
25+
}
26+
(new YY {}).boom // error
27+
// object creation impossible, since def apply(fa: String):
28+
// Int is not defined (Note that String does not match
29+
// Test3.Bar[X & Object with Test3.YY {...}#Foo])
30+
31+
// So the apply in YY doesn't implements the one in XX, and
32+
// everything is nice and sound.
33+
}
34+
35+
object Test4 {
36+
type Bar[A] = A match {
37+
case X => String
38+
case Y => Int
39+
}
40+
41+
trait XX {
42+
type Foo
43+
type FooAlias = Foo
44+
45+
val a: Bar[X & FooAlias] = "hello"
46+
val b: Bar[Y & FooAlias] = 1
47+
48+
def apply(fa: Bar[X & FooAlias]): Bar[Y & FooAlias]
49+
50+
def boom: Int = apply(a)
51+
}
52+
53+
trait YY extends XX {
54+
type Foo = X & Y
55+
56+
def apply(fa: Bar[X & FooAlias]): Bar[Y & FooAlias] = fa
57+
}
58+
(new YY {}).boom // error
59+
// object creation impossible, since def apply(fa: String):
60+
// Int is not defined (Note that String does not match
61+
// Test4.Bar[X & Object with Test4.YY {...}#FooAlias])
62+
}

tests/neg/6314.scala

Lines changed: 0 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -46,53 +46,3 @@ object Test2 {
4646
def right(fa: Bar[L]): Int = fa // error
4747
}
4848
}
49-
50-
51-
object Test3 {
52-
type Bar[A] = A match {
53-
case X => String
54-
case Y => Int
55-
}
56-
57-
trait XX {
58-
type Foo
59-
60-
val a: Bar[X & Foo] = "hello"
61-
val b: Bar[Y & Foo] = 1 // error
62-
63-
def apply(fa: Bar[X & Foo]): Bar[Y & Foo]
64-
65-
def boom: Int = apply(a) // error
66-
}
67-
68-
trait YY extends XX {
69-
type Foo = X & Y
70-
71-
def apply(fa: Bar[X & Foo]): Bar[Y & Foo] = fa
72-
}
73-
}
74-
75-
object Test4 {
76-
type Bar[A] = A match {
77-
case X => String
78-
case Y => Int
79-
}
80-
81-
trait XX {
82-
type Foo
83-
type FooAlias = Foo
84-
85-
val a: Bar[X & FooAlias] = "hello"
86-
val b: Bar[Y & FooAlias] = 1 // error
87-
88-
def apply(fa: Bar[X & FooAlias]): Bar[Y & FooAlias]
89-
90-
def boom: Int = apply(a) // error
91-
}
92-
93-
trait YY extends XX {
94-
type Foo = X & Y
95-
96-
def apply(fa: Bar[X & FooAlias]): Bar[Y & FooAlias] = fa
97-
}
98-
}

0 commit comments

Comments
 (0)