Skip to content

Commit 1a709f1

Browse files
committed
Fix widenAbstractTypes
This is significantly more subtle than it looks at first sight. We are probably still unsound for scrutinees that are aliases of matchtypes themselves.
1 parent 911d4f1 commit 1a709f1

File tree

3 files changed

+22
-10
lines changed

3 files changed

+22
-10
lines changed

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

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2313,19 +2313,30 @@ class TrackingTypeComparer(initctx: Context) extends TypeComparer(initctx) {
23132313
cas
23142314
}
23152315
def widenAbstractTypes(tp: Type): Type = new TypeMap {
2316+
var seen = Set[TypeParamRef]()
23162317
def apply(tp: Type) = tp match {
23172318
case tp: TypeRef =>
2318-
if (tp.symbol.isAbstractOrParamType | tp.symbol.isOpaqueAlias)
2319-
WildcardType
2320-
else tp.info match {
2321-
case TypeAlias(alias) =>
2322-
val alias1 = widenAbstractTypes(alias)
2323-
if (alias1 ne alias) alias1 else tp
2324-
case _ => mapOver(tp)
2319+
tp.info match {
2320+
case info: MatchAlias =>
2321+
mapOver(tp)
2322+
// TODO: We should follow the alias in this case, but doing so
2323+
// risks infinite recursion
2324+
case TypeBounds(lo, hi) =>
2325+
if (hi frozen_<:< lo) {
2326+
val alias = apply(lo)
2327+
if (alias ne lo) alias else mapOver(tp)
2328+
}
2329+
else WildcardType
2330+
case _ =>
2331+
mapOver(tp)
23252332
}
2326-
2333+
case tp: TypeLambda =>
2334+
val saved = seen
2335+
seen ++= tp.paramRefs
2336+
try mapOver(tp)
2337+
finally seen = saved
23272338
case tp: TypeVar if !tp.isInstantiated => WildcardType
2328-
case _: TypeParamRef => WildcardType
2339+
case tp: TypeParamRef if !seen.contains(tp) => WildcardType
23292340
case _ => mapOver(tp)
23302341
}
23312342
}.apply(tp)

compiler/test/dotc/run-test-pickling.blacklist

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ typeclass-derivation1.scala
88
typeclass-derivation2.scala
99
typeclass-derivation2a.scala
1010
typeclass-derivation2c.scala
11+
typeclass-derivation2d.scala
1112
typeclass-derivation3.scala
1213
derive-generic.scala
1314
mixin-forwarder-overload

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 {
5+
type LL[X] = X match { // error: recursion limit exceeded
66
case Int => LL[LL[X]]
77
}
88
def a: L[Boolean] = ???

0 commit comments

Comments
 (0)