diff options
author | Martin Odersky <odersky@gmail.com> | 2014-01-23 09:47:36 +0100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2014-01-26 18:52:33 +0100 |
commit | 47b36b45455ecd73853dc63e9e047833cf4612c5 (patch) | |
tree | 8c89643d46d60d9875d992548ad03464a885ab78 /src/dotty/tools/dotc | |
parent | a6d26a142672c47b457b6ef7d042e4880ad3345a (diff) | |
download | dotty-47b36b45455ecd73853dc63e9e047833cf4612c5.tar.gz dotty-47b36b45455ecd73853dc63e9e047833cf4612c5.tar.bz2 dotty-47b36b45455ecd73853dc63e9e047833cf4612c5.zip |
Split TermRefs with underlying OrTypes.
Implements
(A | B)(x) ==> A(x) | B(x)
in phase 2 of subtype checking. This is useful because it ensures that certain subtype judegments that should be correct are correct. It might also help prune the search space earlier.
Diffstat (limited to 'src/dotty/tools/dotc')
-rw-r--r-- | src/dotty/tools/dotc/core/TypeComparer.scala | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/src/dotty/tools/dotc/core/TypeComparer.scala b/src/dotty/tools/dotc/core/TypeComparer.scala index 8762cf637..0cf94c829 100644 --- a/src/dotty/tools/dotc/core/TypeComparer.scala +++ b/src/dotty/tools/dotc/core/TypeComparer.scala @@ -2,7 +2,7 @@ package dotty.tools package dotc package core -import Types._, Contexts._, Symbols._, Flags._, Names._, NameOps._ +import Types._, Contexts._, Symbols._, Flags._, Names._, NameOps._, Denotations._ import typer.Mode import Decorators._ import StdNames.{nme, tpnme} @@ -103,12 +103,13 @@ class TypeComparer(initctx: Context) extends DotClass { * @pre `param` is in the constraint's domain * @return Whether the augmented constraint is still satisfiable. */ - def addConstraint(param: PolyParam, bound: Type, fromBelow: Boolean): Boolean = { + def addConstraint(param: PolyParam, bound0: Type, fromBelow: Boolean): Boolean = { + val bound = bound0.dealias.stripTypeVar param == bound || // ### !frozenConstraint && { // ### constr.println(s"adding ${param.show} ${if (fromBelow) ">:>" else "<:<"} ${bound.show} (${bound.getClass}) to ${constraint.show}") - val res = bound.dealias.stripTypeVar match { + val res = bound match { case bound: PolyParam if constraint contains bound => val TypeBounds(lo, hi) = constraint.bounds(bound) if (lo eq hi) @@ -532,7 +533,7 @@ class TypeComparer(initctx: Context) extends DotClass { case tp2: PolyParam => tp2 == tp1 || isSubTypeWhenFrozen(tp1, bounds(tp2).lo) || { - if (constraint contains tp2) addConstraint(tp2, tp1.widen.dealias.stripTypeVar, fromBelow = true) + if (constraint contains tp2) addConstraint(tp2, tp1.widen, fromBelow = true) else (ctx.mode is Mode.TypevarsMissContext) || secondTry(tp1, tp2) } case tp2: BoundType => @@ -567,13 +568,13 @@ class TypeComparer(initctx: Context) extends DotClass { } thirdTry(tp1, tp2) case tp1: PolyParam => - (tp1 == tp2) || + tp1 == tp2 || isSubTypeWhenFrozen(bounds(tp1).hi, tp2) || { if (!frozenConstraint && (tp2 isRef defn.NothingClass) && ctx.typerState.isGlobalCommittable) ctx.log(s"!!! instantiating to Nothing: $tp1") - if (constraint contains tp1) addConstraint(tp1, tp2.dealias.stripTypeVar, fromBelow = false) + if (constraint contains tp1) addConstraint(tp1, tp2, fromBelow = false) else (ctx.mode is Mode.TypevarsMissContext) || thirdTry(tp1, tp2) } case tp1: BoundType => @@ -591,6 +592,19 @@ class TypeComparer(initctx: Context) extends DotClass { isSubType(tp11, tp2) && isSubType(tp12, tp2) case ErrorType => true + case tp1: TermRef => + tp1.denot match { + case sd: SingleDenotation => + sd.info match { + case OrType(tp11, tp12) => + def derivedRef(tp: Type) = + TermRef(tp1.prefix, tp1.name, sd.derivedSingleDenotation(sd.symbol, tp)) + return secondTry(OrType(derivedRef(tp11), derivedRef(tp12)), tp2) + case _ => + } + case _ => + } + thirdTry(tp1, tp2) case _ => thirdTry(tp1, tp2) } |