aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/core/Types.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2014-03-08 12:24:34 +0100
committerDmitry Petrashko <dmitry.petrashko@gmail.com>2014-03-20 13:02:40 +0100
commit88c4a6cddefb6bf3e7d1ac3c61358cc06abd8bd4 (patch)
treeb3438b800980b8684646d62591a569dc55094cdf /src/dotty/tools/dotc/core/Types.scala
parent7a04b119c9744262bd46c1795b811f56df9516a6 (diff)
downloaddotty-88c4a6cddefb6bf3e7d1ac3c61358cc06abd8bd4.tar.gz
dotty-88c4a6cddefb6bf3e7d1ac3c61358cc06abd8bd4.tar.bz2
dotty-88c4a6cddefb6bf3e7d1ac3c61358cc06abd8bd4.zip
Allow And/OrTypes in baseType operations
Introduce new cases for AndTypes and OrTypes in methods `derivesFrom`, `baseClasses`, and `baseTypeWithArgs`. These cases are ultimately needed so that `baseTypeWithArgs` makes sense for union and intersection types. Also, fixed embarrassing typo in method `TypeBounds#|`.
Diffstat (limited to 'src/dotty/tools/dotc/core/Types.scala')
-rw-r--r--src/dotty/tools/dotc/core/Types.scala22
1 files changed, 19 insertions, 3 deletions
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index a0293d50a..b06a95dc7 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -102,8 +102,19 @@ object Types {
}
/** Is this type an instance of a non-bottom subclass of the given class `cls`? */
- final def derivesFrom(cls: Symbol)(implicit ctx: Context): Boolean =
- classSymbol.derivesFrom(cls)
+ final def derivesFrom(cls: Symbol)(implicit ctx: Context): Boolean = this match {
+ case tp: TypeRef =>
+ val sym = tp.symbol
+ if (sym.isClass) sym.derivesFrom(cls) else tp.underlying.derivesFrom(cls)
+ case tp: TypeProxy =>
+ tp.underlying.derivesFrom(cls)
+ case tp: AndType =>
+ tp.tp1.derivesFrom(cls) || tp.tp2.derivesFrom(cls)
+ case tp: OrType =>
+ tp.tp1.derivesFrom(cls) && tp.tp2.derivesFrom(cls)
+ case _ =>
+ false
+ }
/** A type T is a legal prefix in a type selection T#A if
* T is stable or T contains no abstract types
@@ -254,6 +265,7 @@ object Types {
/** The base classes of this type as determined by ClassDenotation
* in linearization order, with the class itself as first element.
+ * For AndTypes/OrTypes, the union/intersection of the operands' baseclasses.
* Inherited by all type proxies. `Nil` for all other types.
*/
final def baseClasses(implicit ctx: Context): List[ClassSymbol] = track("baseClasses") {
@@ -262,6 +274,10 @@ object Types {
tp.underlying.baseClasses
case tp: ClassInfo =>
tp.cls.baseClasses
+ case AndType(tp1, tp2) =>
+ tp1.baseClasses union tp2.baseClasses
+ case OrType(tp1, tp2) =>
+ tp1.baseClasses intersect tp2.baseClasses
case _ => Nil
}
}
@@ -1863,7 +1879,7 @@ object Types {
def | (that: TypeBounds)(implicit ctx: Context): TypeBounds = {
val v = this commonVariance that
- if (v == 0 && (this.lo eq this.hi) && (that.lo eq that.hi))
+ if (v != 0 && (this.lo eq this.hi) && (that.lo eq that.hi))
if (v > 0) derivedTypeAlias(this.hi | that.hi, v)
else derivedTypeAlias(this.lo & that.lo, v)
else derivedTypeBounds(this.lo & that.lo, this.hi | that.hi, v)