diff options
author | Martin Odersky <odersky@gmail.com> | 2017-03-19 19:07:41 +0100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2017-04-06 13:15:29 +0200 |
commit | cdc91e28879a6882ce48f3a7fd7f0d7f432258b6 (patch) | |
tree | f1366387f84c39a10dae19477b64c0b393e8d104 | |
parent | 15e60e8637887892b0c03e5f6948f1222819a746 (diff) | |
download | dotty-cdc91e28879a6882ce48f3a7fd7f0d7f432258b6.tar.gz dotty-cdc91e28879a6882ce48f3a7fd7f0d7f432258b6.tar.bz2 dotty-cdc91e28879a6882ce48f3a7fd7f0d7f432258b6.zip |
Refactorings for efficiency
- split LambdaType.equals into two equals so that tests
are more specific (also avoids type testing against
a trait)
- re-order cases in some pattern matches with the aim to
(1) move common cases earlier, (2) move more expensive
trait type tests later.
-rw-r--r-- | compiler/src/dotty/tools/dotc/core/SymDenotations.scala | 6 | ||||
-rw-r--r-- | compiler/src/dotty/tools/dotc/core/Types.scala | 93 |
2 files changed, 56 insertions, 43 deletions
diff --git a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala index 56acbd9d6..602848a50 100644 --- a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala @@ -1146,13 +1146,13 @@ object SymDenotations { case tp: NamedType => hasSkolems(tp.prefix) case tp: RefinedType => hasSkolems(tp.parent) || hasSkolems(tp.refinedInfo) case tp: RecType => hasSkolems(tp.parent) - case tp: LambdaType => tp.paramInfos.exists(hasSkolems) || hasSkolems(tp.resType) + case tp: TypeBounds => hasSkolems(tp.lo) || hasSkolems(tp.hi) + case tp: TypeVar => hasSkolems(tp.inst) case tp: ExprType => hasSkolems(tp.resType) case tp: HKApply => hasSkolems(tp.tycon) || tp.args.exists(hasSkolems) + case tp: LambdaType => tp.paramInfos.exists(hasSkolems) || hasSkolems(tp.resType) case tp: AndOrType => hasSkolems(tp.tp1) || hasSkolems(tp.tp2) - case tp: TypeBounds => hasSkolems(tp.lo) || hasSkolems(tp.hi) case tp: AnnotatedType => hasSkolems(tp.tpe) - case tp: TypeVar => hasSkolems(tp.inst) case _ => false } diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index fc6d5f44c..0a3191b84 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -2393,8 +2393,18 @@ object Types { x => paramInfos.mapConserve(_.subst(this, x).asInstanceOf[PInfo]), x => resType.subst(this, x)) + protected def prefixString: String + final override def toString = s"$prefixString($paramNames, $paramInfos, $resType)" + } + + abstract class HKLambda extends CachedProxyType with LambdaType { + final override def underlying(implicit ctx: Context) = resType + + final override def computeHash = doHash(paramNames, resType, paramInfos) + + // Defined here instead of in LambdaType for efficiency final override def equals(that: Any) = that match { - case that: LambdaType => + case that: HKLambda => this.paramNames == that.paramNames && this.paramInfos == that.paramInfos && this.resType == that.resType && @@ -2402,18 +2412,21 @@ object Types { case _ => false } - - protected def prefixString: String - final override def toString = s"$prefixString($paramNames, $paramInfos, $resType)" - } - - abstract class HKLambda extends CachedProxyType with LambdaType { - final override def computeHash = doHash(paramNames, resType, paramInfos) - final override def underlying(implicit ctx: Context) = resType } abstract class MethodOrPoly extends CachedGroundType with LambdaType with TermType { final override def computeHash = doHash(paramNames, resType, paramInfos) + + // Defined here instead of in LambdaType for efficiency + final override def equals(that: Any) = that match { + case that: MethodOrPoly => + this.paramNames == that.paramNames && + this.paramInfos == that.paramInfos && + this.resType == that.resType && + (this.companion eq that.companion) + case _ => + false + } } trait TermLambda extends LambdaType { thisLambdaType => @@ -3543,6 +3556,26 @@ object Types { variance = -variance derivedTypeBounds(tp, lo1, this(tp.hi)) + case tp: RecType => + derivedRecType(tp, this(tp.parent)) + + case tp: TypeVar => + val inst = tp.instanceOpt + if (inst.exists) apply(inst) else tp + + case tp: HKApply => + def mapArg(arg: Type, tparam: ParamInfo): Type = { + val saved = variance + variance *= tparam.paramVariance + try this(arg) + finally variance = saved + } + derivedAppliedType(tp, this(tp.tycon), + tp.args.zipWithConserve(tp.typeParams)(mapArg)) + + case tp: ExprType => + derivedExprType(tp, this(tp.resultType)) + case tp: LambdaType => def mapOverLambda = { variance = -variance @@ -3552,12 +3585,6 @@ object Types { } mapOverLambda - case tp: ExprType => - derivedExprType(tp, this(tp.resultType)) - - case tp: RecType => - derivedRecType(tp, this(tp.parent)) - case tp @ SuperType(thistp, supertp) => derivedSuperType(tp, this(thistp), this(supertp)) @@ -3567,21 +3594,7 @@ object Types { case tp: ClassInfo => mapClassInfo(tp) - case tp: TypeVar => - val inst = tp.instanceOpt - if (inst.exists) apply(inst) else tp - - case tp: HKApply => - def mapArg(arg: Type, tparam: ParamInfo): Type = { - val saved = variance - variance *= tparam.paramVariance - try this(arg) - finally variance = saved - } - derivedAppliedType(tp, this(tp.tycon), - tp.args.zipWithConserve(tp.typeParams)(mapArg)) - - case tp: AndOrType => + case tp: AndOrType => derivedAndOrType(tp, this(tp.tp1), this(tp.tp2)) case tp: SkolemType => @@ -3762,17 +3775,14 @@ object Types { this(y, hi) } - case tp: LambdaType => - variance = -variance - val y = foldOver(x, tp.paramInfos) - variance = -variance - this(y, tp.resultType) + case tp: RecType => + this(x, tp.parent) case ExprType(restpe) => this(x, restpe) - case tp: RecType => - this(x, tp.parent) + case tp: TypeVar => + this(x, tp.underlying) case SuperType(thistp, supertp) => this(this(x, thistp), supertp) @@ -3797,6 +3807,12 @@ object Types { } foldArgs(this(x, tycon), tp.typeParams, args) + case tp: LambdaType => + variance = -variance + val y = foldOver(x, tp.paramInfos) + variance = -variance + this(y, tp.resultType) + case tp: AndOrType => this(this(x, tp.tp1), tp.tp2) @@ -3806,9 +3822,6 @@ object Types { case AnnotatedType(underlying, annot) => this(applyToAnnot(x, annot), underlying) - case tp: TypeVar => - this(x, tp.underlying) - case tp: WildcardType => this(x, tp.optBounds) |