Skip to content

Commit c908b13

Browse files
authored
Merge pull request #9618 from dotty-staging/optimize-maps
Allocate fewer TypeMaps and TypeAccumulators
2 parents c99913f + eaf6033 commit c908b13

File tree

5 files changed

+148
-116
lines changed

5 files changed

+148
-116
lines changed

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

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ object Decorators {
171171
def & (ys: List[T]): List[T] = xs filter (ys contains _)
172172
}
173173

174-
extension [T, U](xss: List[List[T]]):
174+
extension [T, U](xss: List[List[T]])
175175
def nestedMap(f: T => U): List[List[U]] =
176176
xss.map(_.map(f))
177177
def nestedMapConserve(f: T => U): List[List[U]] =
@@ -180,14 +180,14 @@ object Decorators {
180180
xss.zipWithConserve(yss)((xs, ys) => xs.zipWithConserve(ys)(f))
181181
end extension
182182

183-
extension (text: Text):
183+
extension (text: Text)
184184
def show(using Context): String = text.mkString(ctx.settings.pageWidth.value, ctx.settings.printLines.value)
185185

186186
/** Test whether a list of strings representing phases contains
187187
* a given phase. See [[config.CompilerCommand#explainAdvanced]] for the
188188
* exact meaning of "contains" here.
189189
*/
190-
extension (names: List[String]) {
190+
extension (names: List[String])
191191
def containsPhase(phase: Phase): Boolean =
192192
names.nonEmpty && {
193193
phase match {
@@ -203,18 +203,16 @@ object Decorators {
203203
}
204204
}
205205
}
206-
}
207206

208-
extension [T](x: T) {
207+
extension [T](x: T)
209208
def reporting(
210209
op: WrappedResult[T] ?=> String,
211210
printer: config.Printers.Printer = config.Printers.default): T = {
212211
printer.println(op(using WrappedResult(x)))
213212
x
214213
}
215-
}
216214

217-
extension [T](x: T) {
215+
extension [T](x: T)
218216
def assertingErrorsReported(using Context): T = {
219217
assert(ctx.reporter.errorsReported)
220218
x
@@ -223,9 +221,12 @@ object Decorators {
223221
assert(ctx.reporter.errorsReported, msg)
224222
x
225223
}
226-
}
227224

228-
extension (sc: StringContext) {
225+
extension [T <: AnyRef](xs: ::[T])
226+
def derivedCons(x1: T, xs1: List[T]) =
227+
if (xs.head eq x1) && (xs.tail eq xs1) then xs else x1 :: xs1
228+
229+
extension (sc: StringContext)
229230
/** General purpose string formatting */
230231
def i(args: Any*)(using Context): String =
231232
new StringFormatter(sc).assemble(args)
@@ -241,9 +242,8 @@ object Decorators {
241242
*/
242243
def ex(args: Any*)(using Context): String =
243244
explained(em(args: _*))
244-
}
245245

246-
extension [T <: AnyRef](arr: Array[T]):
246+
extension [T <: AnyRef](arr: Array[T])
247247
def binarySearch(x: T): Int = java.util.Arrays.binarySearch(arr.asInstanceOf[Array[Object]], x)
248248

249249
}

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

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package dotty.tools.dotc.core
22

3-
import Types._, Symbols._, Contexts._
3+
import Types._, Symbols._, Contexts._, Decorators._
44

55
/** Substitution operations on types. See the corresponding `subst` and
66
* `substThis` methods on class Type for an explanation.
@@ -16,6 +16,8 @@ object Substituters:
1616
else tp.derivedSelect(subst(tp.prefix, from, to, theMap))
1717
case _: ThisType =>
1818
tp
19+
case tp: AppliedType =>
20+
tp.map(subst(_, from, to, theMap))
1921
case _ =>
2022
(if (theMap != null) theMap else new SubstBindingMap(from, to))
2123
.mapOver(tp)
@@ -94,7 +96,7 @@ object Substituters:
9496
ts = ts.tail
9597
}
9698
tp
97-
case _: ThisType | _: BoundType =>
99+
case _: BoundType =>
98100
tp
99101
case _ =>
100102
(if (theMap != null) theMap else new SubstSymMap(from, to))
@@ -152,45 +154,47 @@ object Substituters:
152154
else tp.derivedSelect(substParams(tp.prefix, from, to, theMap))
153155
case _: ThisType =>
154156
tp
157+
case tp: AppliedType =>
158+
tp.map(substParams(_, from, to, theMap))
155159
case _ =>
156160
(if (theMap != null) theMap else new SubstParamsMap(from, to))
157161
.mapOver(tp)
158162
}
159163

160164
final class SubstBindingMap(from: BindingType, to: BindingType)(using Context) extends DeepTypeMap {
161-
def apply(tp: Type): Type = subst(tp, from, to, this)
165+
def apply(tp: Type): Type = subst(tp, from, to, this)(using mapCtx)
162166
}
163167

164168
final class Subst1Map(from: Symbol, to: Type)(using Context) extends DeepTypeMap {
165-
def apply(tp: Type): Type = subst1(tp, from, to, this)
169+
def apply(tp: Type): Type = subst1(tp, from, to, this)(using mapCtx)
166170
}
167171

168172
final class Subst2Map(from1: Symbol, to1: Type, from2: Symbol, to2: Type)(using Context) extends DeepTypeMap {
169-
def apply(tp: Type): Type = subst2(tp, from1, to1, from2, to2, this)
173+
def apply(tp: Type): Type = subst2(tp, from1, to1, from2, to2, this)(using mapCtx)
170174
}
171175

172176
final class SubstMap(from: List[Symbol], to: List[Type])(using Context) extends DeepTypeMap {
173-
def apply(tp: Type): Type = subst(tp, from, to, this)
177+
def apply(tp: Type): Type = subst(tp, from, to, this)(using mapCtx)
174178
}
175179

176180
final class SubstSymMap(from: List[Symbol], to: List[Symbol])(using Context) extends DeepTypeMap {
177-
def apply(tp: Type): Type = substSym(tp, from, to, this)
181+
def apply(tp: Type): Type = substSym(tp, from, to, this)(using mapCtx)
178182
}
179183

180184
final class SubstThisMap(from: ClassSymbol, to: Type)(using Context) extends DeepTypeMap {
181-
def apply(tp: Type): Type = substThis(tp, from, to, this)
185+
def apply(tp: Type): Type = substThis(tp, from, to, this)(using mapCtx)
182186
}
183187

184188
final class SubstRecThisMap(from: Type, to: Type)(using Context) extends DeepTypeMap {
185-
def apply(tp: Type): Type = substRecThis(tp, from, to, this)
189+
def apply(tp: Type): Type = substRecThis(tp, from, to, this)(using mapCtx)
186190
}
187191

188192
final class SubstParamMap(from: ParamRef, to: Type)(using Context) extends DeepTypeMap {
189-
def apply(tp: Type): Type = substParam(tp, from, to, this)
193+
def apply(tp: Type): Type = substParam(tp, from, to, this)(using mapCtx)
190194
}
191195

192196
final class SubstParamsMap(from: BindingType, to: List[Type])(using Context) extends DeepTypeMap {
193-
def apply(tp: Type): Type = substParams(tp, from, to, this)
197+
def apply(tp: Type): Type = substParams(tp, from, to, this)(using mapCtx)
194198
}
195199

196200
/** An approximating substitution that can handle wildcards in the `to` list */

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,8 @@ object TypeOps:
100100
val sym = tp.symbol
101101
if (sym.isStatic && !sym.maybeOwner.seesOpaques || (tp.prefix `eq` NoPrefix)) tp
102102
else derivedSelect(tp, atVariance(variance max 0)(this(tp.prefix)))
103+
case tp: LambdaType =>
104+
mapOverLambda(tp) // special cased common case
103105
case tp: ThisType =>
104106
toPrefix(pre, cls, tp.cls)
105107
case _: BoundType =>
@@ -136,6 +138,9 @@ object TypeOps:
136138
tp2
137139
case tp1 => tp1
138140
}
141+
case tp: AppliedType =>
142+
val normed = tp.tryNormalize
143+
if normed.exists then normed else tp.map(simplify(_, theMap))
139144
case tp: TypeParamRef =>
140145
val tvar = ctx.typerState.constraint.typeVarOfParam(tp)
141146
if (tvar.exists) tvar else tp
@@ -147,7 +152,7 @@ object TypeOps:
147152
simplify(l, theMap) & simplify(r, theMap)
148153
case OrType(l, r) if !ctx.mode.is(Mode.Type) =>
149154
simplify(l, theMap) | simplify(r, theMap)
150-
case _: AppliedType | _: MatchType =>
155+
case _: MatchType =>
151156
val normed = tp.tryNormalize
152157
if (normed.exists) normed else mapOver
153158
case tp: MethodicType =>

0 commit comments

Comments
 (0)