diff options
author | Martin Odersky <odersky@gmail.com> | 2014-02-13 14:50:04 +0100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2014-02-13 14:50:04 +0100 |
commit | c4bed34b009ffc54b1eac10ee75fba27040f1533 (patch) | |
tree | 956b51a53a1b0c5358cca63bf3f4ee47abb59c38 /src/dotty/tools/dotc/typer | |
parent | 80acc2d331cf8359c00d9a15c8cc10d537be503a (diff) | |
download | dotty-c4bed34b009ffc54b1eac10ee75fba27040f1533.tar.gz dotty-c4bed34b009ffc54b1eac10ee75fba27040f1533.tar.bz2 dotty-c4bed34b009ffc54b1eac10ee75fba27040f1533.zip |
Two performance optimizations
1) Split out wildApprox into separate function
2) Be more careful not to follow static prefix chains where not needed
Diffstat (limited to 'src/dotty/tools/dotc/typer')
-rw-r--r-- | src/dotty/tools/dotc/typer/Implicits.scala | 7 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Inferencing.scala | 80 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Namer.scala | 2 |
3 files changed, 49 insertions, 40 deletions
diff --git a/src/dotty/tools/dotc/typer/Implicits.scala b/src/dotty/tools/dotc/typer/Implicits.scala index 5e5077cc4..74e79269f 100644 --- a/src/dotty/tools/dotc/typer/Implicits.scala +++ b/src/dotty/tools/dotc/typer/Implicits.scala @@ -56,9 +56,9 @@ object Implicits { case mt: MethodType => mt.isImplicit || mt.paramTypes.length != 1 || - !(argType <:< ((new WildApprox) apply mt.paramTypes.head))(ctx.fresh.withExploreTyperState) + !(argType <:< wildApprox(mt.paramTypes.head)(ctx.fresh.withExploreTyperState)) case rtp => - discardForView((new WildApprox) apply rtp, argType) + discardForView(wildApprox(rtp), argType) } case tpw: TermRef => false // can't discard overloaded refs @@ -270,6 +270,7 @@ trait ImplicitRunInfo { self: RunInfo => */ object liftToClasses extends TypeMap { private implicit val ctx: Context = liftingCtx + override def stopAtStatic = true def apply(tp: Type) = tp match { case tp: TypeRef if tp.symbol.isAbstractOrAliasType => val pre = tp.prefix @@ -439,7 +440,7 @@ trait Implicits { self: Typer => } /** The expected type where parameters and uninstantiated typevars are replaced by wildcard types */ - val wildProto = implicitProto(pt, new WildApprox) + val wildProto = implicitProto(pt, wildApprox(_)) /** Search failures; overridden in ExplainedImplicitSearch */ protected def nonMatchingImplicit(ref: TermRef): SearchFailure = NoImplicitMatches diff --git a/src/dotty/tools/dotc/typer/Inferencing.scala b/src/dotty/tools/dotc/typer/Inferencing.scala index 868276598..409d4a356 100644 --- a/src/dotty/tools/dotc/typer/Inferencing.scala +++ b/src/dotty/tools/dotc/typer/Inferencing.scala @@ -520,44 +520,52 @@ object Inferencing { /** Approximate occurrences of parameter types and uninstantiated typevars * by wildcard types. */ - class WildApprox(implicit ctx: Context) extends TypeMap { - override def apply(tp: Type) = tp match { - case PolyParam(pt, pnum) => - WildcardType(apply(pt.paramBounds(pnum)).bounds) - case MethodParam(mt, pnum) => - WildcardType(TypeBounds.upper(apply(mt.paramTypes(pnum)))) - case tp: TypeVar => - val inst = tp.instanceOpt - if (inst.exists) apply(inst) - else ctx.typerState.constraint.at(tp.origin) match { - case bounds: TypeBounds => apply(WildcardType(bounds)) - case NoType => WildcardType - } - case tp: AndType => - val tp1a = apply(tp.tp1) - val tp2a = apply(tp.tp2) - def wildBounds(tp: Type) = - if (tp.isInstanceOf[WildcardType]) tp.bounds else TypeBounds.upper(tp) - if (tp1a.isInstanceOf[WildcardType] || tp2a.isInstanceOf[WildcardType]) - WildcardType(wildBounds(tp1a) & wildBounds(tp2a)) - else - tp.derivedAndType(tp1a, tp2a) - case tp: OrType => - val tp1a = apply(tp.tp1) - val tp2a = apply(tp.tp2) - if (tp1a.isInstanceOf[WildcardType] || tp2a.isInstanceOf[WildcardType]) - WildcardType(tp1a.bounds | tp2a.bounds) - else - tp.derivedOrType(tp1a, tp2a) - case tp: SelectionProto => - tp.derivedSelectionProto(tp.name, this(tp.refinedInfo), NoViewsAllowed) - case tp: ViewProto => - tp.derivedViewProto(this(tp.argType), this(tp.resultType)) - case _ => - mapOver(tp) - } + final def wildApprox(tp: Type, theMap: WildApproxMap = null)(implicit ctx: Context): Type = tp match { + case tp: NamedType => // default case, inlined for speed + if (tp.symbol.isStatic) tp + else tp.derivedSelect(wildApprox(tp.prefix, theMap)) + case PolyParam(pt, pnum) => + WildcardType(wildApprox(pt.paramBounds(pnum)).bounds) + case MethodParam(mt, pnum) => + WildcardType(TypeBounds.upper(wildApprox(mt.paramTypes(pnum)))) + case tp: TypeVar => + val inst = tp.instanceOpt + if (inst.exists) wildApprox(inst) + else ctx.typerState.constraint.at(tp.origin) match { + case bounds: TypeBounds => wildApprox(WildcardType(bounds)) + case NoType => WildcardType + } + case tp: AndType => + val tp1a = wildApprox(tp.tp1) + val tp2a = wildApprox(tp.tp2) + def wildBounds(tp: Type) = + if (tp.isInstanceOf[WildcardType]) tp.bounds else TypeBounds.upper(tp) + if (tp1a.isInstanceOf[WildcardType] || tp2a.isInstanceOf[WildcardType]) + WildcardType(wildBounds(tp1a) & wildBounds(tp2a)) + else + tp.derivedAndType(tp1a, tp2a) + case tp: OrType => + val tp1a = wildApprox(tp.tp1) + val tp2a = wildApprox(tp.tp2) + if (tp1a.isInstanceOf[WildcardType] || tp2a.isInstanceOf[WildcardType]) + WildcardType(tp1a.bounds | tp2a.bounds) + else + tp.derivedOrType(tp1a, tp2a) + case tp: SelectionProto => + tp.derivedSelectionProto(tp.name, wildApprox(tp.refinedInfo), NoViewsAllowed) + case tp: ViewProto => + tp.derivedViewProto(wildApprox(tp.argType), wildApprox(tp.resultType)) + case _: ThisType | _: BoundType | NoPrefix => // default case, inlined for speed + tp + case tp: RefinedType => // default case, inlined for speed + tp.derivedRefinedType(wildApprox(tp.parent, theMap), tp.refinedName, wildApprox(tp.refinedInfo, theMap)) + case _ => + (if (theMap != null) theMap else new WildApproxMap).mapOver(tp) } + private[Inferencing] class WildApproxMap(implicit ctx: Context) extends TypeMap { + def apply(tp: Type) = wildApprox(tp, this) + } /** Add all parameters in given polytype `pt` to the constraint's domain. * If the constraint contains already some of these parameters in its domain, diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala index fac08ea3d..96fa7f44f 100644 --- a/src/dotty/tools/dotc/typer/Namer.scala +++ b/src/dotty/tools/dotc/typer/Namer.scala @@ -551,7 +551,7 @@ class Namer { typer: Typer => defContext(sym).denotNamed(original) def paramProto(paramss: List[List[Type]], idx: Int): Type = paramss match { case params :: paramss1 => - if (idx < params.length) (new WildApprox) apply params(idx) + if (idx < params.length) wildApprox(params(idx)) else paramProto(paramss1, idx - params.length) case nil => WildcardType |