aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2012-12-18 15:12:47 +0100
committerMartin Odersky <odersky@gmail.com>2012-12-18 15:12:47 +0100
commit5991fd353278dd8b4e30d080fdfb846b060ea327 (patch)
treec626c72af10cbb3a44a89e8a0d0e0879632e6eb8 /src
parent789d15e6d5d98880dd64c8b55b9c2456f020b46b (diff)
downloaddotty-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.scala92
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