Skip to content

Commit

Permalink
Fix a recursive TypeBound with some half answers
Browse files Browse the repository at this point in the history
  • Loading branch information
dwijnand committed Jan 17, 2022
1 parent 7939ddb commit 9e7f1e0
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 1 deletion.
10 changes: 9 additions & 1 deletion compiler/src/dotty/tools/dotc/core/TypeOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,8 @@ object TypeOps:
sym.is(Package) || sym.isStatic && isStaticPrefix(pre.prefix)
case _ => true

private var halfAnswers: util.SimpleIdentityMap[Type, Type] = util.SimpleIdentityMap.empty

override def apply(tp: Type): Type = tp match
case tp: TermRef
if toAvoid(tp) =>
Expand All @@ -434,8 +436,14 @@ object TypeOps:
tp.info match {
case info: AliasingBounds =>
apply(info.alias)
case TypeBounds(lo, hi) if halfAnswers.contains(tp) =>
halfAnswers(tp)
case TypeBounds(lo, hi) =>
range(atVariance(-variance)(apply(lo)), apply(hi))
val hi2 = apply(hi)
halfAnswers = halfAnswers.updated(tp, range(defn.NothingType, hi2))
val res = range(atVariance(-variance)(apply(lo)), hi2)
halfAnswers = halfAnswers.remove(tp)
res
case info: ClassInfo =>
range(defn.NothingType, apply(classBound(info)))
case _ =>
Expand Down
7 changes: 7 additions & 0 deletions tests/pos/i14287.min.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
enum Foo[+H[_]]:
case Bar[F[_]](f: Foo[F]) extends Foo[F]
case Baz()

def test: Foo[H] = this match
case Bar(Bar(f)) => Bar(f)
case _ => this
15 changes: 15 additions & 0 deletions tests/pos/i14287.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
enum Free[+F[_], A]:
case Return(a: A)
case Suspend(s: F[A])
case FlatMap[F[_], A, B](
s: Free[F, A],
f: A => Free[F, B]) extends Free[F, B]

def flatMap[F2[x] >: F[x], B](f: A => Free[F2,B]): Free[F2,B] =
FlatMap(this, f)

@annotation.tailrec
final def step: Free[F, A] = this match
case FlatMap(FlatMap(fx, f), g) => fx.flatMap(x => f(x).flatMap(y => g(y))).step
case FlatMap(Return(x), f) => f(x).step
case _ => this

0 comments on commit 9e7f1e0

Please sign in to comment.