diff options
Diffstat (limited to 'src/dotty/tools/dotc/core')
-rw-r--r-- | src/dotty/tools/dotc/core/TypeComparer.scala | 21 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Types.scala | 36 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/pickling/ClassfileParser.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/pickling/UnPickler.scala | 4 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/transform/Erasure.scala | 4 |
5 files changed, 41 insertions, 26 deletions
diff --git a/src/dotty/tools/dotc/core/TypeComparer.scala b/src/dotty/tools/dotc/core/TypeComparer.scala index f723dca48..588756db4 100644 --- a/src/dotty/tools/dotc/core/TypeComparer.scala +++ b/src/dotty/tools/dotc/core/TypeComparer.scala @@ -220,8 +220,8 @@ class TypeComparer(initctx: Context) extends DotClass { case tp2: RefinedType => isSubType(tp1, tp2.parent) && ( tp2.refinedName == nme.WILDCARD - || (tp1.typeSymbol eq NothingClass) - || (tp1.typeSymbol eq NullClass) + || (tp1 isRef NothingClass) + || (tp1 isRef NullClass) || tp1.member(tp2.refinedName).hasAltWith(alt => isSubType(alt.info, tp2.refinedInfo))) case AndType(tp21, tp22) => @@ -258,8 +258,8 @@ class TypeComparer(initctx: Context) extends DotClass { case TypeBounds(lo2, hi2) => tp1 match { case TypeBounds(lo1, hi1) => - ((lo2.typeSymbol eq NothingClass) || isSubType(lo2, lo1)) && - ((hi2.typeSymbol eq AnyClass) || isSubType(hi1, hi2)) + ((lo2 isRef NothingClass) || isSubType(lo2, lo1)) && + ((hi2 isRef AnyClass) || isSubType(hi1, hi2)) case tp1: ClassInfo => val tt = tp1.typeConstructor // was typeTemplate isSubType(lo2, tt) && isSubType(tt, hi2) @@ -386,8 +386,9 @@ class TypeComparer(initctx: Context) extends DotClass { formals2 match { case formal2 :: rest2 => (isSameType(formal1, formal2) - || isJava1 && formal2.typeSymbol == ObjectClass && formal1.typeSymbol == AnyClass - || isJava2 && formal1.typeSymbol == ObjectClass && formal2.typeSymbol == AnyClass) && matchingParams(rest1, rest2, isJava1, isJava2) + || isJava1 && (formal2 isRef ObjectClass) && (formal1 isRef AnyClass) + || isJava2 && (formal1 isRef ObjectClass) && (formal2 isRef AnyClass)) && + matchingParams(rest1, rest2, isJava1, isJava2) case nil => false } @@ -402,8 +403,8 @@ class TypeComparer(initctx: Context) extends DotClass { def glb(tp1: Type, tp2: Type): Type = if (tp1 eq tp2) tp1 - else if (!tp1.exists || (tp1.typeSymbol eq AnyClass) || (tp2.typeSymbol eq NothingClass)) tp2 - else if (!tp2.exists || (tp2.typeSymbol eq AnyClass) || (tp1.typeSymbol eq NothingClass)) tp1 + else if (!tp1.exists || (tp1 isRef AnyClass) || (tp2 isRef NothingClass)) tp2 + else if (!tp2.exists || (tp2 isRef AnyClass) || (tp1 isRef NothingClass)) tp1 else tp2 match { // normalize to disjunctive normal form if possible. case OrType(tp21, tp22) => tp1 & tp21 | tp1 & tp22 @@ -442,8 +443,8 @@ class TypeComparer(initctx: Context) extends DotClass { def lub(tp1: Type, tp2: Type): Type = if (tp1 eq tp2) tp1 - else if (!tp1.exists || (tp1.typeSymbol eq AnyClass) || (tp2.typeSymbol eq NothingClass)) tp1 - else if (!tp2.exists || (tp2.typeSymbol eq AnyClass) || (tp1.typeSymbol eq NothingClass)) tp2 + else if (!tp1.exists || (tp1 isRef AnyClass) || (tp2 isRef NothingClass)) tp1 + else if (!tp2.exists || (tp2 isRef AnyClass) || (tp1 isRef NothingClass)) tp2 else { val t1 = mergeIfSuper(tp1, tp2) if (t1.exists) t1 diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index ddb42916e..3e419359b 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -53,7 +53,6 @@ object Types { * | | +--- ConstantType * | | +--- MethodParam * | | +--- RefinedThis - * | | +--- NoPrefix * | +- PolyParam * | +- RefinedType * | +- TypeBounds @@ -69,6 +68,7 @@ object Types { * +- ClassInfo * | * +- NoType + * +- NoPrefix * +- ErrorType * +- WildcardType */ @@ -92,16 +92,30 @@ object Types { case _ => false } - /** Is this type an instance of the given class `cls`? */ - final def isClassType(cls: Symbol)(implicit ctx: Context): Boolean = - dealias.typeSymbol == cls + /** Is this type a (possibly aliased and/or partially applied) type reference + * to the given type symbol? + * @sym The symbol to compare to. It must be a class symbol or abstract type. + * It makes no sense for it to be an alias type because isRef would always + * return false in that case. + */ + def isRef(sym: Symbol)(implicit ctx: Context): Boolean = stripTypeVar match { + case this1: TypeRef => + val thissym = this1.symbol + if (thissym.isAliasType) this1.info.bounds.hi.isRef(sym) + else thissym eq sym + case this1: RefinedType => + // make sure all refinements are type arguments + this1.parent.isRef(sym) && this.typeArgs.nonEmpty + case _ => + false + } /** Is this type an instance of a non-bottom subclass of the given class `cls`? */ - final def derivesFrom(cls: Symbol)(implicit ctx: Context): Boolean = + final def derivesFrom(cls: Symbol)(implicit defctx: Context): Boolean = classSymbol.derivesFrom(cls) /** Is this an array type? */ - final def isArray(implicit ctx: Context): Boolean = isClassType(defn.ArrayClass) + final def isArray(implicit ctx: Context): Boolean = isRef(defn.ArrayClass) /** A type T is a legal prefix in a type selection T#A if * T is stable or T contains no uninstantiated type variables. @@ -568,7 +582,7 @@ object Types { /** Map references to Object to references to Any; needed for Java interop */ final def objToAny(implicit ctx: Context) = - if (isClassType(defn.ObjectClass) && !ctx.phase.erasedTypes) defn.AnyType else this + if ((this isRef defn.ObjectClass) && !ctx.phase.erasedTypes) defn.AnyType else this /** If this is repeated parameter type, its underlying type, * else the type itself. @@ -837,8 +851,8 @@ object Types { final def argType(tparam: Symbol)(implicit ctx: Context): Type = this match { case TypeBounds(lo, hi) => val v = tparam.variance - if (v > 0 && lo.isClassType(defn.NothingClass)) hi - else if (v < 0 && hi.isClassType(defn.AnyClass)) lo + if (v > 0 && (lo isRef defn.NothingClass)) hi + else if (v < 0 && (hi isRef defn.AnyClass)) lo else if (v == 0 && (lo eq hi)) lo else NoType case _ => @@ -1867,9 +1881,9 @@ object Types { if ((prefix eq cls.owner.thisType) || !cls.owner.isClass) tp else tp.substThis(cls.owner.asClass, prefix) - private var tyconCache: Type = null + private var tyconCache: TypeRef = null - def typeConstructor(implicit ctx: Context): Type = { + def typeConstructor(implicit ctx: Context): TypeRef = { def clsDenot = if (prefix eq cls.owner.thisType) cls.denot else cls.denot.copySymDenotation(info = this) if (tyconCache == null) tyconCache = diff --git a/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala b/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala index fc3fb49ec..f640c3d67 100644 --- a/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala +++ b/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala @@ -248,7 +248,7 @@ class ClassfileParser( val tp = sig2type(tparams, skiptvs) // sig2type seems to return AnyClass regardless of the situation: // we don't want Any as a LOWER bound. - if (tp.typeSymbol == defn.AnyClass) TypeBounds.empty + if (tp isRef defn.AnyClass) TypeBounds.empty else TypeBounds.lower(tp) case '*' => TypeBounds.empty } diff --git a/src/dotty/tools/dotc/core/pickling/UnPickler.scala b/src/dotty/tools/dotc/core/pickling/UnPickler.scala index 109987dcf..4570d0654 100644 --- a/src/dotty/tools/dotc/core/pickling/UnPickler.scala +++ b/src/dotty/tools/dotc/core/pickling/UnPickler.scala @@ -71,7 +71,7 @@ object UnPickler { assert(lastArg.isArray) val elemtp0 :: Nil = lastArg.baseTypeArgs(defn.ArrayClass) val elemtp = elemtp0 match { - case AndType(t1, t2) if t1.typeSymbol.isAbstractType && t2.isClassType(defn.ObjectClass) => + case AndType(t1, t2) if t1.typeSymbol.isAbstractType && (t2 isRef defn.ObjectClass) => t1 // drop intersection with Object for abstract types in varargs. UnCurry can handle them. case _ => elemtp0 @@ -538,7 +538,7 @@ class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClassRoot: */ def elimExistentials(boundSyms: List[Symbol], tp: Type): Type = { def removeSingleton(tp: Type): Type = - if (tp.isClassType(defn.SingletonClass)) defn.AnyType else tp + if (tp isRef defn.SingletonClass) defn.AnyType else tp def elim(tp: Type): Type = tp match { case tp @ RefinedType(parent, name) => val parent1 = elim(tp.parent) diff --git a/src/dotty/tools/dotc/core/transform/Erasure.scala b/src/dotty/tools/dotc/core/transform/Erasure.scala index 6bb07e699..201dd107f 100644 --- a/src/dotty/tools/dotc/core/transform/Erasure.scala +++ b/src/dotty/tools/dotc/core/transform/Erasure.scala @@ -131,10 +131,10 @@ object Erasure { } def resultErasure(tp: Type)(implicit ctx: Context) = - if (tp.isClassType(defn.UnitClass)) tp else erasure(tp) + if (tp isRef defn.UnitClass) tp else erasure(tp) def removeLaterObjects(trs: List[TypeRef])(implicit ctx: Context): List[TypeRef] = trs match { - case tr :: trs1 => tr :: trs1.filterNot(_.isClassType(defn.ObjectClass)) + case tr :: trs1 => tr :: trs1.filterNot(_ isRef defn.ObjectClass) case nil => nil } } |