Skip to content

Commit 393d91f

Browse files
committed
Optimize simplify for applied types
1 parent 7204538 commit 393d91f

File tree

2 files changed

+55
-34
lines changed

2 files changed

+55
-34
lines changed

compiler/src/dotty/tools/dotc/core/TypeOps.scala

Lines changed: 54 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -109,41 +109,62 @@ trait TypeOps { this: Context => // TODO: Make standalone object.
109109
}
110110

111111
/** Implementation of Types#simplified */
112-
final def simplify(tp: Type, theMap: SimplifyMap): Type = tp match {
113-
case tp: NamedType =>
114-
if (tp.symbol.isStatic) tp
115-
else tp.derivedSelect(simplify(tp.prefix, theMap)) match {
116-
case tp1: NamedType if tp1.denotationIsCurrent =>
117-
val tp2 = tp1.reduceProjection
118-
//if (tp2 ne tp1) println(i"simplified $tp1 -> $tp2")
119-
tp2
120-
case tp1 => tp1
121-
}
122-
case tp: TypeParamRef =>
123-
if (tp.paramName.is(DepParamName)) {
124-
val bounds = ctx.typeComparer.bounds(tp)
125-
if (bounds.lo.isRef(defn.NothingClass)) bounds.hi else bounds.lo
126-
}
127-
else {
128-
val tvar = typerState.constraint.typeVarOfParam(tp)
129-
if (tvar.exists) tvar else tp
130-
}
131-
case _: ThisType | _: BoundType | NoPrefix =>
132-
tp
133-
case tp: RefinedType => // @!!!
134-
tp.derivedRefinedType(simplify(tp.parent, theMap), tp.refinedName, simplify(tp.refinedInfo, theMap))
135-
case tp: TypeAlias =>
136-
tp.derivedTypeAlias(simplify(tp.alias, theMap))
137-
case AndType(l, r) if !ctx.mode.is(Mode.Type) =>
138-
simplify(l, theMap) & simplify(r, theMap)
139-
case OrType(l, r) if !ctx.mode.is(Mode.Type) =>
140-
simplify(l, theMap) | simplify(r, theMap)
141-
case _ =>
142-
(if (theMap != null) theMap else new SimplifyMap).mapOver(tp)
112+
final def simplify(tp: Type): Type = tp match {
113+
case tp: NamedType => simplifyNamed(tp)
114+
case _: ThisType => tp
115+
case _ => new SimplifyMap().mapOver2(tp)
143116
}
144117

145-
class SimplifyMap extends TypeMap {
146-
def apply(tp: Type) = simplify(tp, this)
118+
def simplifyNamed(tp: NamedType) =
119+
if (tp.symbol.isStatic) tp
120+
else tp.derivedSelect(simplify(tp.prefix)) match {
121+
case tp1: NamedType if tp1.denotationIsCurrent => tp1.reduceProjection
122+
case tp1 => tp1
123+
}
124+
125+
private class SimplifyMap extends TypeMap {
126+
def apply(tp: Type): Type = tp match {
127+
case tp: NamedType => simplifyNamed(tp)
128+
case _: ThisType => tp
129+
case _ => mapOver2(tp)
130+
}
131+
132+
// Specialize mapOver2 to get monomorphic dispatch for handling AppliedTypes
133+
override def mapOver2(tp: Type) = tp match {
134+
case tp: AppliedType =>
135+
def mapArgs(args: List[Type]): List[Type] = args match {
136+
case arg :: otherArgs =>
137+
val arg1 = this(arg)
138+
val otherArgs1 = mapArgs(otherArgs)
139+
if ((arg1 eq arg) && (otherArgs1 eq otherArgs)) args
140+
else arg1 :: otherArgs1
141+
case nil =>
142+
nil
143+
}
144+
derivedAppliedType(tp, this(tp.tycon), mapArgs(tp.args))
145+
case _ =>
146+
mapOver3(tp)
147+
}
148+
149+
override def mapOver3(tp: Type) = tp match {
150+
case tp: TypeParamRef =>
151+
if (tp.paramName.is(DepParamName)) {
152+
val bounds = ctx.typeComparer.bounds(tp)
153+
if (bounds.lo.isRef(defn.NothingClass)) bounds.hi else bounds.lo
154+
}
155+
else {
156+
val tvar = typerState.constraint.typeVarOfParam(tp)
157+
if (tvar.exists) tvar else tp
158+
}
159+
case _: BoundType | NoPrefix | NoType =>
160+
tp
161+
case AndType(l, r) if !ctx.mode.is(Mode.Type) => // TODO: Drop all simplifications if mode isType?
162+
this(l) & this(r)
163+
case OrType(l, r) if !ctx.mode.is(Mode.Type) =>
164+
this(l) | this(r)
165+
case _ =>
166+
super.mapOver3(tp)
167+
}
147168
}
148169

149170
/** Approximate union type by intersection of its dominators.

compiler/src/dotty/tools/dotc/core/Types.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1374,7 +1374,7 @@ object Types {
13741374
* after the type variables are instantiated. Finally, it
13751375
* maps poly params in the current constraint set back to their type vars.
13761376
*/
1377-
def simplified(implicit ctx: Context) = ctx.simplify(this, null)
1377+
def simplified(implicit ctx: Context) = ctx.simplify(this)
13781378

13791379
/** customized hash code of this type.
13801380
* NotCached for uncached types. Cached types

0 commit comments

Comments
 (0)