diff options
author | Martin Odersky <odersky@gmail.com> | 2015-05-24 11:43:37 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2015-06-06 11:04:53 +0200 |
commit | c8a479255745d7de391f386bbf8946233ff46f7d (patch) | |
tree | 42c1d657f121875894c8e611c713bd77a22ea009 /src | |
parent | 8e9233b9fce1c7e15d0d1111e88edd5139b3ced7 (diff) | |
download | dotty-c8a479255745d7de391f386bbf8946233ff46f7d.tar.gz dotty-c8a479255745d7de391f386bbf8946233ff46f7d.tar.bz2 dotty-c8a479255745d7de391f386bbf8946233ff46f7d.zip |
Make skolemsstate three valued
Diffstat (limited to 'src')
-rw-r--r-- | src/dotty/tools/dotc/core/Skolemization.scala | 23 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/TypeComparer.scala | 7 |
2 files changed, 21 insertions, 9 deletions
diff --git a/src/dotty/tools/dotc/core/Skolemization.scala b/src/dotty/tools/dotc/core/Skolemization.scala index fb47cb62a..af7530458 100644 --- a/src/dotty/tools/dotc/core/Skolemization.scala +++ b/src/dotty/tools/dotc/core/Skolemization.scala @@ -18,26 +18,33 @@ trait Skolemization { implicit val ctx: Context - protected var skolemsOutstanding = false + private[core] var skolemsState = Skolemization.SkolemsDisallowed - def ensureStableSingleton(tp: Type): SingletonType = tp.stripTypeVar match { + final def ensureStableSingleton(tp: Type): SingletonType = tp.stripTypeVar match { case tp: SingletonType if tp.isStable => tp case tp: ValueType => - skolemsOutstanding = true + assert(skolemsState != Skolemization.SkolemsDisallowed) + skolemsState = Skolemization.SkolemsEncountered SkolemType(tp) case tp: TypeProxy => ensureStableSingleton(tp.underlying) } - /** Approximate a type `tp` with a type that does not contain skolem types. + /** If skolems were encountered, approximate a type `tp` with a type that + * does not contain skolem types. * @param toSuper if true, return the smallest supertype of `tp` with this property * else return the largest subtype. */ - final def deSkolemize(tp: Type, toSuper: Boolean): Type = - if (skolemsOutstanding) deSkolemize(tp, if (toSuper) 1 else -1, Set()) + final def deSkolemizeIfSkolemsSeen(tp: Type, toSuper: Boolean): Type = + if (skolemsState == Skolemization.SkolemsEncountered) + deSkolemize(tp, if (toSuper) 1 else -1, Set()) else tp + /** Approximate a type `tp` with a type that does not contain skolem types. + */ + final def deSkolemize(tp: Type): Type = deSkolemize(tp, 1, Set()) + private def deSkolemize(tp: Type, variance: Int, seen: Set[SkolemType]): Type = ctx.traceIndented(s"deskolemize $tp, variance = $variance, seen = $seen = ") { def approx(lo: Type = defn.NothingType, hi: Type = defn.AnyType, newSeen: Set[SkolemType] = seen) = @@ -124,3 +131,7 @@ trait Skolemization { } } } + +object Skolemization extends Enumeration { + val SkolemsDisallowed, SkolemsAllowed, SkolemsEncountered = Value +} diff --git a/src/dotty/tools/dotc/core/TypeComparer.scala b/src/dotty/tools/dotc/core/TypeComparer.scala index 9559666a4..692f05d5a 100644 --- a/src/dotty/tools/dotc/core/TypeComparer.scala +++ b/src/dotty/tools/dotc/core/TypeComparer.scala @@ -531,7 +531,8 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling wi * rebase both itself and the member info of `tp` on a freshly created skolem type. */ protected def hasMatchingMember(name: Name, tp1: Type, tp2: RefinedType): Boolean = { - val saved = skolemsOutstanding + val saved = skolemsState + if (skolemsState == Skolemization.SkolemsDisallowed) skolemsState = Skolemization.SkolemsAllowed try { val rebindNeeded = tp2.refinementRefersToThis val base = if (rebindNeeded) ensureStableSingleton(tp1) else tp1 @@ -555,7 +556,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling wi } } } - finally skolemsOutstanding = saved + finally skolemsState = saved } /** Skip refinements in `tp2` which match corresponding refinements in `tp1`. @@ -640,7 +641,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling wi private def narrowGADTBounds(tr: NamedType, bound: Type, isUpper: Boolean): Boolean = ctx.mode.is(Mode.GADTflexible) && { val tparam = tr.symbol - val bound1 = deSkolemize(bound, toSuper = !isUpper) + val bound1 = deSkolemizeIfSkolemsSeen(bound, toSuper = !isUpper) typr.println(s"narrow gadt bound of $tparam: ${tparam.info} from ${if (isUpper) "above" else "below"} to $bound1 ${bound1.isRef(tparam)}") !bound1.isRef(tparam) && { val oldBounds = ctx.gadt.bounds(tparam) |