diff options
author | Martin Odersky <odersky@gmail.com> | 2013-03-05 13:26:50 +0100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2013-03-05 13:26:50 +0100 |
commit | 3efd95c6b2f9a0347edcdc14535ff6ed6dae054c (patch) | |
tree | 5937a95d96216fc2a57b0d6a967065f8cec18be1 | |
parent | c6daa22c03b6957cbea1eaae2d935e9a418d705e (diff) | |
download | dotty-3efd95c6b2f9a0347edcdc14535ff6ed6dae054c.tar.gz dotty-3efd95c6b2f9a0347edcdc14535ff6ed6dae054c.tar.bz2 dotty-3efd95c6b2f9a0347edcdc14535ff6ed6dae054c.zip |
Review of TypeComparers
-rw-r--r-- | src/dotty/tools/dotc/core/Contexts.scala | 11 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/TypeComparers.scala | 105 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Types.scala | 10 |
3 files changed, 63 insertions, 63 deletions
diff --git a/src/dotty/tools/dotc/core/Contexts.scala b/src/dotty/tools/dotc/core/Contexts.scala index 8c10c12f4..f769ad318 100644 --- a/src/dotty/tools/dotc/core/Contexts.scala +++ b/src/dotty/tools/dotc/core/Contexts.scala @@ -81,7 +81,7 @@ object Contexts { def typeComparer: TypeComparer = { if ((_typeComparer eq outer.typeComparer) && (constraints ne outer.constraints)) - _typeComparer = new TypeComparer(this) + _typeComparer = new TypeComparer() _typeComparer } @@ -335,8 +335,13 @@ object Contexts { /** Initial capacity of uniques HashMap */ private[core] final val initialUniquesCapacity = 50000 - /** How many recursive calls to isVolatile are performed before + /** How many recursive calls to NamedType#underlying are performed before * logging starts. */ - private[core] final val LogUnderlyingThreshold = 50 + private[core] final val LogPendingUnderlyingThreshold = 50 + + /** How many recursive calls to isSubType are performed before + * logging starts. + */ + private[core] final val LogPendingSubTypesThreshold = 50 } diff --git a/src/dotty/tools/dotc/core/TypeComparers.scala b/src/dotty/tools/dotc/core/TypeComparers.scala index 2bdad0d50..f07ec5b9e 100644 --- a/src/dotty/tools/dotc/core/TypeComparers.scala +++ b/src/dotty/tools/dotc/core/TypeComparers.scala @@ -7,14 +7,7 @@ object TypeComparers { type Constraints = Map[PolyParam, TypeBounds] - object TypeComparer { - private final val LogPendingSubTypesThreshold = 50 - } - - class TypeComparer(_ctx: Context) extends DotClass { - import TypeComparer._ - - implicit val ctx = _ctx + class TypeComparer()(implicit val ctx: Context) extends DotClass { var constraints = ctx.constraints @@ -63,59 +56,60 @@ object TypeComparers { } def firstTry(tp1: Type, tp2: Type): Boolean = tp2 match { - case tp2: TypeRef => + case tp2: NamedType => tp1 match { - case tp1: TypeRef => + case tp1: NamedType => val sym1 = tp1.symbol val sym2 = tp2.symbol val pre1 = tp1.prefix val pre2 = tp2.prefix - (sym1 == sym2 && ( - ctx.erasedTypes || - (sym1.owner.isPackage) || - isSubType(pre1, pre2)) - || - tp1.name == tp2.name && - isSubType(pre1, pre2) && - (sym2.info.isRealTypeBounds || isSubType(pre2, pre1)) // ??? - || - (sym2.isClass) && { - val base = tp1.baseType(sym2) - (base ne tp1) && isSubType(base, tp2) - } - || - thirdTryRef(tp1, tp2)) + if (sym1 == sym2) ( + ctx.erasedTypes + || sym1.owner.isPackage + || isSubType(pre1, pre2) + ) else ( + tp1.name == tp2.name && isSubType(pre1, pre2) + || sym2.isClass && { + val base = tp1.baseType(sym2) + (base ne tp1) && isSubType(base, tp2) + } + || thirdTryNamed(tp1, tp2) + ) case _ => secondTry(tp1, tp2) } case WildcardType | ErrorType => true - case tp2: PolyParam if (constraints contains tp2) => - addConstraint(tp2, TypeBounds(tp1, defn.AnyType)) + case tp2: PolyParam if constraints contains tp2 => + addConstraint(tp2, TypeBounds.lower(tp1)) case _ => secondTry(tp1, tp2) } def secondTry(tp1: Type, tp2: Type): Boolean = tp1 match { - case tp1: PolyParam if (constraints contains tp1) => - addConstraint(tp1, TypeBounds.upper(tp2)) case WildcardType | ErrorType => true + case tp1: PolyParam if constraints contains tp1 => + addConstraint(tp1, TypeBounds.upper(tp2)) case _ => thirdTry(tp1, tp2) } - def thirdTryRef(tp1: Type, tp2: TypeRef): Boolean = { - val cls2 = tp2.symbol - (cls2 == defn.SingletonClass && tp1.isStable) || - (!cls2.isClass && isSubType(tp1, tp2.info.bounds.lo)) || - fourthTry(tp1, tp2) + def thirdTryNamed(tp1: Type, tp2: NamedType): Boolean = tp2.info match { + case TypeBounds(lo, _) => + isSubType(tp1, lo) + case _ => + val cls2 = tp2.symbol + ( cls2 == defn.SingletonClass && tp1.isStable + || cls2 == defn.NotNullClass && tp1.isNotNull + || fourthTry(tp1, tp2) + ) } def thirdTry(tp1: Type, tp2: Type): Boolean = tp2 match { - case tp2: TypeRef => - thirdTryRef(tp1, tp2) + case tp2: NamedType => + thirdTryNamed(tp1, tp2) case tp2: RefinedType => isSubType(tp1, tp2.parent) && isSubType(tp1.member(tp2.refinedName).info, tp2.refinedInfo) @@ -128,7 +122,7 @@ object TypeComparers { case tp1 @ MethodType(_, formals2) => tp1.signature == tp2.signature && matchingParams(formals1, formals2, tp1.isJava, tp2.isJava) && - tp1.isImplicit == tp2.isImplicit && + tp1.isImplicit == tp2.isImplicit && // needed? isSubType(tp1.resultType, tp2.resultType.subst(tp2, tp1)) case _ => false @@ -173,23 +167,22 @@ object TypeComparers { def fourthTry(tp1: Type, tp2: Type): Boolean = tp1 match { case tp1: TypeRef => - ((tp1 eq defn.NothingType) - || - (tp1 eq defn.NullType) && tp2.typeSymbol.isNonValueClass - || - (!tp1.symbol.isClass && isSubType(tp1.info.bounds.hi, tp2))) + ( (tp1 eq defn.NothingType) + || (tp1 eq defn.NullType) && tp2.typeSymbol.isNonValueClass + || !tp1.symbol.isClass && isSubType(tp1.info.bounds.hi, tp2) + ) + case tp1: SingletonType => + isSubType(tp1.underlying, tp2) case tp1: RefinedType => isSubType(tp1.parent, tp2) case AndType(tp11, tp12) => isSubType(tp11, tp2) || isSubType(tp12, tp2) case OrType(tp11, tp12) => isSubType(tp11, tp2) && isSubType(tp12, tp2) - case tp1: SingletonType => - isSubType(tp1.underlying, tp2) case _ => false } - +/* not needed def isSubArgs(tps1: List[Type], tps2: List[Type], tparams: List[TypeSymbol]): Boolean = tparams match { case tparam :: tparams1 => val variance = tparam.variance @@ -202,7 +195,7 @@ object TypeComparers { assert(tps1.isEmpty && tps2.isEmpty) true } - +*/ /** A function implementing `tp1` matches `tp2`. */ final def matchesType(tp1: Type, tp2: Type, alwaysMatchSimple: Boolean): Boolean = tp1 match { case tp1: MethodType => @@ -225,7 +218,7 @@ object TypeComparers { case tp2: ExprType => matchesType(tp1.resultType, tp2.resultType, alwaysMatchSimple) case _ => - matchesType(tp1.resultType, tp2, alwaysMatchSimple) + false // was: matchesType(tp1.resultType, tp2, alwaysMatchSimple) } case tp1: PolyType => tp2 match { @@ -239,6 +232,8 @@ object TypeComparers { tp2 match { case _: MethodType | _: PolyType => false + case tp2: ExprType => + false // was: matchesType(tp1, tp2.resultType, alwaysMatchSimple) case _ => alwaysMatchSimple || isSameType(tp1, tp2) } @@ -246,18 +241,18 @@ object TypeComparers { /** Are `syms1` and `syms2` parameter lists with pairwise equivalent types? */ private def matchingParams(formals1: List[Type], formals2: List[Type], isJava1: Boolean, isJava2: Boolean): Boolean = formals1 match { - case Nil => - formals2.isEmpty case formal1 :: rest1 => formals2 match { - case Nil => - false case formal2 :: rest2 => - (isSameType(formal1, formal2) || - isJava1 && formal2 == defn.ObjectType && formal1 == defn.AnyType || - isJava2 && formal1 == defn.ObjectType && formal2 == defn.AnyType) && - matchingParams(rest1, rest2, isJava1, isJava2) + ( isSameType(formal1, formal2) + || isJava1 && formal2 == defn.ObjectType && formal1 == defn.AnyType + || isJava2 && formal1 == defn.ObjectType && formal2 == defn.AnyType + ) && matchingParams(rest1, rest2, isJava1, isJava2) + case nil => + false } + case nil => + formals2.isEmpty } def isSameType(tp1: Type, tp2: Type): Boolean = diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index e6faad37c..e48eece8d 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -372,10 +372,10 @@ object Types { case tp: ClassInfo => val candidates = tp.cls.membersNamed(name) candidates.filterAsSeenFrom(pre, excluded).toDenot - case tp: AndType => - tp.tp1.findMember(name, pre, excluded) & tp.tp2.findMember(name, pre, excluded) - case tp: OrType => - (tp.tp1.findMember(name, pre, excluded) | tp.tp2.findMember(name, pre, excluded))(pre) + case AndType(l, r) => + l.findMember(name, pre, excluded) & r.findMember(name, pre, excluded) + case OrType(l, r) => + (l.findMember(name, pre, excluded) | r.findMember(name, pre, excluded))(pre) } /** Is this type a subtype of that type? */ @@ -764,7 +764,7 @@ object Types { override def underlying(implicit ctx: Context): Type = try { ctx.underlyingRecursions += 1 - if (ctx.underlyingRecursions < LogUnderlyingThreshold) + if (ctx.underlyingRecursions < LogPendingUnderlyingThreshold) info else if (ctx.pendingUnderlying(this)) throw new CyclicReference(symbol) |