diff options
author | Martin Odersky <odersky@gmail.com> | 2012-12-18 15:12:47 +0100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2012-12-18 15:12:47 +0100 |
commit | 5991fd353278dd8b4e30d080fdfb846b060ea327 (patch) | |
tree | c626c72af10cbb3a44a89e8a0d0e0879632e6eb8 /src | |
parent | 789d15e6d5d98880dd64c8b55b9c2456f020b46b (diff) | |
download | dotty-5991fd353278dd8b4e30d080fdfb846b060ea327.tar.gz dotty-5991fd353278dd8b4e30d080fdfb846b060ea327.tar.bz2 dotty-5991fd353278dd8b4e30d080fdfb846b060ea327.zip |
Started working on Subtyper object
Diffstat (limited to 'src')
-rw-r--r-- | src/dotty/tools/dotc/core/SubTyper.scala | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/src/dotty/tools/dotc/core/SubTyper.scala b/src/dotty/tools/dotc/core/SubTyper.scala new file mode 100644 index 000000000..ad9bb7fb4 --- /dev/null +++ b/src/dotty/tools/dotc/core/SubTyper.scala @@ -0,0 +1,92 @@ +package dotty.tools.dotc.core + +import Types._, Contexts._, Symbols._ + +object SubTypers { + + type Constraints = Map[PolyParam, TypeBounds] + + class SubTyper extends DotClass { + + var constraints: Constraints = _ + implicit var ctx: Context = _ + + def init(constraints: Constraints)(implicit ctx: Context): SubTyper = { + this.constraints = constraints + this.ctx = ctx + this + } + + def addConstraint(param: PolyParam, bounds: TypeBounds): Boolean = { + val newbounds = constraints(param) & bounds + constraints = constraints.updated(param, newbounds) + newbounds.lo <:< newbounds.hi + } + + def isSubType(tp1: Type, tp2: Type): Boolean = { + if (tp1 == NoType || tp2 == NoType) return false + if (tp1 eq tp2) return true + val cs = constraints + try { + val result = firstTry(tp1, tp2) + if (!result) constraints = cs + result + } catch { + case ex: Throwable => + constraints = cs + throw ex + } + } + + def firstTry(tp1: Type, tp2: Type): Boolean = tp2 match { + case tp2: TypeRef => + tp1 match { + case tp1: TypeRef => + val sym1 = tp1.symbol + val sym2 = tp2.symbol + val pre1 = tp1.prefix + val pre2 = tp2.prefix + (sym1 == sym2 && ( + ctx.erasedTypes || + sym1.owner.hasFlag(Flags.Package) || + isSubType(pre1, pre2)) + || + tp1.name == tp2.name && + isSubType(pre1, pre2) && + (sym2.isAbstractType || isSubType(pre2, pre1)) + || + (sym2.isClass) && { + val base = tp1.baseType(sym2) + (base ne tp1) && isSubType(base, tp2) + } + || + thirdTryRef(tp1, tp2)) + case _ => + secondTry(tp1, tp2) + } + case tp2: PolyParam if (constraints contains tp2) => + addConstraint(tp2, TypeBounds(tp1, AnyType)) + case _ => + secondTry(tp1, tp2) + } + + + def secondTry(tp1: Type, tp2: Type): Boolean = tp1 match { + case tp1: PolyParam if (constraints contains tp1) => + addConstraint(tp1, TypeBounds(NothingType, tp2)) + case _ => + thirdTry(tp1, tp2) + } + + def thirdTryRef(tp1: Type, tp2: TypeRef): Boolean = ( + (tp2 == SingletonType && tp1.isStable) + || + (!tp2.symbol.isClass && isSubType(tp1, tp2.info.bounds.lo)) + || + fourthTry(tp1, tp2) + ) + + def thirdTry(tp1: Type, tp2: Type): Boolean = ??? + def fourthTry(tp1: Type, tp2: Type): Boolean = ??? + } +}
\ No newline at end of file |