diff options
-rw-r--r-- | src/dotty/tools/dotc/core/TypeComparer.scala | 8 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Types.scala | 12 | ||||
-rw-r--r-- | tests/pos/Coder.scala | 3 |
3 files changed, 18 insertions, 5 deletions
diff --git a/src/dotty/tools/dotc/core/TypeComparer.scala b/src/dotty/tools/dotc/core/TypeComparer.scala index 6a071c871..1f1e6606f 100644 --- a/src/dotty/tools/dotc/core/TypeComparer.scala +++ b/src/dotty/tools/dotc/core/TypeComparer.scala @@ -66,7 +66,9 @@ class TypeComparer(initctx: Context) extends DotClass { } def addConstraint(param: PolyParam, bound: Type, fromBelow: Boolean): Boolean = + param == bound || !frozenConstraint && { + println(s"adding ${param.show} ${if (fromBelow) ">:>" else "<:<"} ${bound.show} to ${constraint.show}") bound match { case bound: PolyParam if constraint(bound).exists => addConstraint1(param, bound, fromBelow) && @@ -199,9 +201,8 @@ class TypeComparer(initctx: Context) extends DotClass { case tp2: PolyParam => tp2 == tp1 || { isSubTypeWhenFrozen(tp1, bounds(tp2).lo) || { - if (!frozenConstraint) println(s"adding ${tp1.show} <:< ${tp2.show} to ${constraint.show}") // !!!DEBUG constraint(tp2) match { - case TypeBounds(lo, _) => addConstraint(tp2, tp1.widen, fromBelow = true) + case TypeBounds(lo, _) => addConstraint(tp2, tp1.widen.dealias_*, fromBelow = true) case _ => secondTry(tp1, tp2) } } @@ -238,10 +239,9 @@ class TypeComparer(initctx: Context) extends DotClass { case tp1: PolyParam => (tp1 == tp2) || { isSubTypeWhenFrozen(bounds(tp1).hi, tp2) || { - if (!frozenConstraint) println(s"adding ${tp1.show} <:< ${tp2.show} to ${constraint.show}") assert(frozenConstraint || !(tp2 isRef defn.NothingClass)) // !!!DEBUG constraint(tp1) match { - case TypeBounds(_, hi) => addConstraint(tp1, tp2, fromBelow = false) + case TypeBounds(_, hi) => addConstraint(tp1, tp2.dealias_*, fromBelow = false) case _ => thirdTry(tp1, tp2) } } diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index afb1501f5..bcc447f8a 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -643,6 +643,18 @@ object Types { case _ => this } + final def dealias_*(implicit ctx: Context): Type = this match { + case tp: TypeRef => + tp.info match { + case TypeBounds(lo, hi) if lo eq hi => hi.dealias_* + case _ => tp + } + case tp: TypeVar => + val tp1 = tp.instanceOpt + if (tp1.exists) tp1.dealias_* else tp + case tp => tp + } + /** Widen from constant type to its underlying non-constant * base type. */ diff --git a/tests/pos/Coder.scala b/tests/pos/Coder.scala index 3fcda1afd..a47dcf3c9 100644 --- a/tests/pos/Coder.scala +++ b/tests/pos/Coder.scala @@ -38,11 +38,12 @@ class Coder(words: List[String]) { def encode(number: String): Set[List[String]] = if (number.isEmpty) Set(Nil) else { - val xs = for { + val xs = (for { splitPoint <- 1 to number.length word <- wordsForNum(number take splitPoint) rest <- encode(number drop splitPoint) } yield word :: rest + ) xs.toSet } |