From cdc91e28879a6882ce48f3a7fd7f0d7f432258b6 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sun, 19 Mar 2017 19:07:41 +0100 Subject: 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. --- compiler/src/dotty/tools/dotc/core/Types.scala | 93 +++++++++++++++----------- 1 file changed, 53 insertions(+), 40 deletions(-) (limited to 'compiler/src/dotty/tools/dotc/core/Types.scala') 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) -- cgit v1.2.3