Skip to content

Commit 6f35436

Browse files
authored
Merge pull request #9590 from dotty-staging/optimze-local-givens
Avoid lazy local contexts
2 parents b1d3e8f + 30f22ff commit 6f35436

File tree

3 files changed

+169
-135
lines changed

3 files changed

+169
-135
lines changed

compiler/src/dotty/tools/dotc/ast/TreeMapWithImplicits.scala

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -91,13 +91,14 @@ class TreeMapWithImplicits extends tpd.TreeMap {
9191
case tree: Block =>
9292
super.transform(tree)(using nestedScopeCtx(tree.stats))
9393
case tree: DefDef =>
94-
given Context = localCtx
95-
cpy.DefDef(tree)(
96-
tree.name,
97-
transformSub(tree.tparams),
98-
tree.vparamss mapConserve (transformSub(_)),
99-
transform(tree.tpt),
100-
transform(tree.rhs)(using nestedScopeCtx(tree.vparamss.flatten)))
94+
inContext(localCtx) {
95+
cpy.DefDef(tree)(
96+
tree.name,
97+
transformSub(tree.tparams),
98+
tree.vparamss mapConserve (transformSub(_)),
99+
transform(tree.tpt),
100+
transform(tree.rhs)(using nestedScopeCtx(tree.vparamss.flatten)))
101+
}
101102
case EmptyValDef =>
102103
tree
103104
case _: PackageDef | _: MemberDef =>

compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -597,9 +597,10 @@ class TreeUnpickler(reader: TastyReader,
597597
else if (sym.isInlineMethod)
598598
sym.addAnnotation(LazyBodyAnnotation { (using ctx0: Context) =>
599599
val ctx1 = localContext(sym)(using ctx0).addMode(Mode.ReadPositions)
600-
given Context = sourceChangeContext(Addr(0))(using ctx1)
600+
inContext(sourceChangeContext(Addr(0))(using ctx1)) {
601601
// avoids space leaks by not capturing the current context
602-
forkAt(rhsStart).readTerm()
602+
forkAt(rhsStart).readTerm()
603+
}
603604
})
604605
goto(start)
605606
sym

compiler/src/dotty/tools/dotc/transform/MegaPhase.scala

Lines changed: 158 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -221,171 +221,203 @@ class MegaPhase(val miniPhases: Array[MiniPhase]) extends Phase {
221221

222222
def transformNamed(tree: Tree, start: Int, outerCtx: Context): Tree = tree match {
223223
case tree: Ident =>
224-
given Context = prepIdent(tree, start)(using outerCtx)
225-
goIdent(tree, start)
224+
inContext(prepIdent(tree, start)(using outerCtx)) {
225+
goIdent(tree, start)
226+
}
226227
case tree: Select =>
227-
given Context = prepSelect(tree, start)(using outerCtx)
228-
val qual = transformTree(tree.qualifier, start)
229-
goSelect(cpy.Select(tree)(qual, tree.name), start)
228+
inContext(prepSelect(tree, start)(using outerCtx)) {
229+
val qual = transformTree(tree.qualifier, start)
230+
goSelect(cpy.Select(tree)(qual, tree.name), start)
231+
}
230232
case tree: ValDef =>
231-
given Context = prepValDef(tree, start)(using outerCtx)
232-
def mapValDef(using Context) = {
233-
val tpt = transformTree(tree.tpt, start)
234-
val rhs = transformTree(tree.rhs, start)
235-
cpy.ValDef(tree)(tree.name, tpt, rhs)
233+
inContext(prepValDef(tree, start)(using outerCtx)) {
234+
def mapValDef(using Context) = {
235+
val tpt = transformTree(tree.tpt, start)
236+
val rhs = transformTree(tree.rhs, start)
237+
cpy.ValDef(tree)(tree.name, tpt, rhs)
238+
}
239+
if (tree.isEmpty) tree
240+
else goValDef(mapValDef(using if (tree.symbol.exists) localContext else ctx), start)
236241
}
237-
if (tree.isEmpty) tree
238-
else goValDef(mapValDef(using if (tree.symbol.exists) localContext else ctx), start)
239242
case tree: DefDef =>
240-
given Context = prepDefDef(tree, start)(using outerCtx)
241-
def mapDefDef(using Context) = {
242-
val tparams = transformSpecificTrees(tree.tparams, start)
243-
val vparamss = tree.vparamss.mapConserve(transformSpecificTrees(_, start))
244-
val tpt = transformTree(tree.tpt, start)
245-
val rhs = transformTree(tree.rhs, start)
246-
cpy.DefDef(tree)(tree.name, tparams, vparamss, tpt, rhs)
243+
inContext(prepDefDef(tree, start)(using outerCtx)) {
244+
def mapDefDef(using Context) = {
245+
val tparams = transformSpecificTrees(tree.tparams, start)
246+
val vparamss = tree.vparamss.mapConserve(transformSpecificTrees(_, start))
247+
val tpt = transformTree(tree.tpt, start)
248+
val rhs = transformTree(tree.rhs, start)
249+
cpy.DefDef(tree)(tree.name, tparams, vparamss, tpt, rhs)
250+
}
251+
goDefDef(mapDefDef(using localContext), start)
247252
}
248-
goDefDef(mapDefDef(using localContext), start)
249253
case tree: TypeDef =>
250-
given Context = prepTypeDef(tree, start)(using outerCtx)
251-
val rhs = transformTree(tree.rhs, start)(using localContext)
252-
goTypeDef(cpy.TypeDef(tree)(tree.name, rhs), start)
254+
inContext(prepTypeDef(tree, start)(using outerCtx)) {
255+
val rhs = transformTree(tree.rhs, start)(using localContext)
256+
goTypeDef(cpy.TypeDef(tree)(tree.name, rhs), start)
257+
}
253258
case tree: Labeled =>
254-
given Context = prepLabeled(tree, start)(using outerCtx)
255-
val bind = transformTree(tree.bind, start).asInstanceOf[Bind]
256-
val expr = transformTree(tree.expr, start)
257-
goLabeled(cpy.Labeled(tree)(bind, expr), start)
259+
inContext(prepLabeled(tree, start)(using outerCtx)) {
260+
val bind = transformTree(tree.bind, start).asInstanceOf[Bind]
261+
val expr = transformTree(tree.expr, start)
262+
goLabeled(cpy.Labeled(tree)(bind, expr), start)
263+
}
258264
case tree: Bind =>
259-
given Context = prepBind(tree, start)(using outerCtx)
260-
val body = transformTree(tree.body, start)
261-
goBind(cpy.Bind(tree)(tree.name, body), start)
265+
inContext(prepBind(tree, start)(using outerCtx)) {
266+
val body = transformTree(tree.body, start)
267+
goBind(cpy.Bind(tree)(tree.name, body), start)
268+
}
262269
case _ =>
263-
given Context = prepOther(tree, start)(using outerCtx)
264-
goOther(tree, start)
270+
inContext(prepOther(tree, start)(using outerCtx)) {
271+
goOther(tree, start)
272+
}
265273
}
266274

267275
def transformUnnamed(tree: Tree, start: Int, outerCtx: Context): Tree = tree match {
268276
case tree: Apply =>
269-
given Context = prepApply(tree, start)(using outerCtx)
270-
val fun = transformTree(tree.fun, start)
271-
val args = transformTrees(tree.args, start)
272-
goApply(cpy.Apply(tree)(fun, args), start)
277+
inContext(prepApply(tree, start)(using outerCtx)) {
278+
val fun = transformTree(tree.fun, start)
279+
val args = transformTrees(tree.args, start)
280+
goApply(cpy.Apply(tree)(fun, args), start)
281+
}
273282
case tree: TypeTree =>
274-
given Context = prepTypeTree(tree, start)(using outerCtx)
275-
goTypeTree(tree, start)
283+
inContext(prepTypeTree(tree, start)(using outerCtx)) {
284+
goTypeTree(tree, start)
285+
}
276286
case tree: Thicket =>
277287
cpy.Thicket(tree)(transformTrees(tree.trees, start))
278288
case tree: This =>
279-
given Context = prepThis(tree, start)(using outerCtx)
280-
goThis(tree, start)
289+
inContext(prepThis(tree, start)(using outerCtx)) {
290+
goThis(tree, start)
291+
}
281292
case tree: Literal =>
282-
given Context = prepLiteral(tree, start)(using outerCtx)
283-
goLiteral(tree, start)
293+
inContext(prepLiteral(tree, start)(using outerCtx)) {
294+
goLiteral(tree, start)
295+
}
284296
case tree: Block =>
285-
given Context = prepBlock(tree, start)(using outerCtx)
286-
val stats = transformStats(tree.stats, ctx.owner, start)
287-
val expr = transformTree(tree.expr, start)
288-
goBlock(cpy.Block(tree)(stats, expr), start)
297+
inContext(prepBlock(tree, start)(using outerCtx)) {
298+
val stats = transformStats(tree.stats, ctx.owner, start)
299+
val expr = transformTree(tree.expr, start)
300+
goBlock(cpy.Block(tree)(stats, expr), start)
301+
}
289302
case tree: TypeApply =>
290-
given Context = prepTypeApply(tree, start)(using outerCtx)
291-
val fun = transformTree(tree.fun, start)
292-
val args = transformTrees(tree.args, start)
293-
goTypeApply(cpy.TypeApply(tree)(fun, args), start)
303+
inContext(prepTypeApply(tree, start)(using outerCtx)) {
304+
val fun = transformTree(tree.fun, start)
305+
val args = transformTrees(tree.args, start)
306+
goTypeApply(cpy.TypeApply(tree)(fun, args), start)
307+
}
294308
case tree: If =>
295-
given Context = prepIf(tree, start)(using outerCtx)
296-
val cond = transformTree(tree.cond, start)
297-
val thenp = transformTree(tree.thenp, start)
298-
val elsep = transformTree(tree.elsep, start)
299-
goIf(cpy.If(tree)(cond, thenp, elsep), start)
309+
inContext(prepIf(tree, start)(using outerCtx)) {
310+
val cond = transformTree(tree.cond, start)
311+
val thenp = transformTree(tree.thenp, start)
312+
val elsep = transformTree(tree.elsep, start)
313+
goIf(cpy.If(tree)(cond, thenp, elsep), start)
314+
}
300315
case tree: New =>
301-
given Context = prepNew(tree, start)(using outerCtx)
302-
val tpt = transformTree(tree.tpt, start)
303-
goNew(cpy.New(tree)(tpt), start)
316+
inContext(prepNew(tree, start)(using outerCtx)) {
317+
val tpt = transformTree(tree.tpt, start)
318+
goNew(cpy.New(tree)(tpt), start)
319+
}
304320
case tree: Typed =>
305-
given Context = prepTyped(tree, start)(using outerCtx)
306-
val expr = transformTree(tree.expr, start)
307-
val tpt = transformTree(tree.tpt, start)
308-
goTyped(cpy.Typed(tree)(expr, tpt), start)
321+
inContext(prepTyped(tree, start)(using outerCtx)) {
322+
val expr = transformTree(tree.expr, start)
323+
val tpt = transformTree(tree.tpt, start)
324+
goTyped(cpy.Typed(tree)(expr, tpt), start)
325+
}
309326
case tree: CaseDef =>
310-
given Context = prepCaseDef(tree, start)(using outerCtx)
311-
val pat = withMode(Mode.Pattern)(transformTree(tree.pat, start))
312-
val guard = transformTree(tree.guard, start)
313-
val body = transformTree(tree.body, start)
314-
goCaseDef(cpy.CaseDef(tree)(pat, guard, body), start)
327+
inContext(prepCaseDef(tree, start)(using outerCtx)) {
328+
val pat = withMode(Mode.Pattern)(transformTree(tree.pat, start))
329+
val guard = transformTree(tree.guard, start)
330+
val body = transformTree(tree.body, start)
331+
goCaseDef(cpy.CaseDef(tree)(pat, guard, body), start)
332+
}
315333
case tree: Closure =>
316-
given Context = prepClosure(tree, start)(using outerCtx)
317-
val env = transformTrees(tree.env, start)
318-
val meth = transformTree(tree.meth, start)
319-
val tpt = transformTree(tree.tpt, start)
320-
goClosure(cpy.Closure(tree)(env, meth, tpt), start)
334+
inContext(prepClosure(tree, start)(using outerCtx)) {
335+
val env = transformTrees(tree.env, start)
336+
val meth = transformTree(tree.meth, start)
337+
val tpt = transformTree(tree.tpt, start)
338+
goClosure(cpy.Closure(tree)(env, meth, tpt), start)
339+
}
321340
case tree: Assign =>
322-
given Context = prepAssign(tree, start)(using outerCtx)
323-
val lhs = transformTree(tree.lhs, start)
324-
val rhs = transformTree(tree.rhs, start)
325-
goAssign(cpy.Assign(tree)(lhs, rhs), start)
341+
inContext(prepAssign(tree, start)(using outerCtx)) {
342+
val lhs = transformTree(tree.lhs, start)
343+
val rhs = transformTree(tree.rhs, start)
344+
goAssign(cpy.Assign(tree)(lhs, rhs), start)
345+
}
326346
case tree: SeqLiteral =>
327-
given Context = prepSeqLiteral(tree, start)(using outerCtx)
328-
val elems = transformTrees(tree.elems, start)
329-
val elemtpt = transformTree(tree.elemtpt, start)
330-
goSeqLiteral(cpy.SeqLiteral(tree)(elems, elemtpt), start)
347+
inContext(prepSeqLiteral(tree, start)(using outerCtx)) {
348+
val elems = transformTrees(tree.elems, start)
349+
val elemtpt = transformTree(tree.elemtpt, start)
350+
goSeqLiteral(cpy.SeqLiteral(tree)(elems, elemtpt), start)
351+
}
331352
case tree: Super =>
332-
given Context = prepSuper(tree, start)(using outerCtx)
333-
goSuper(tree, start)
353+
inContext(prepSuper(tree, start)(using outerCtx)) {
354+
goSuper(tree, start)
355+
}
334356
case tree: Template =>
335-
given Context = prepTemplate(tree, start)(using outerCtx)
336-
val constr = transformSpecificTree(tree.constr, start)
337-
val parents = transformTrees(tree.parents, start)(using ctx.superCallContext)
338-
val self = transformSpecificTree(tree.self, start)
339-
val body = transformStats(tree.body, tree.symbol, start)
340-
goTemplate(cpy.Template(tree)(constr, parents, Nil, self, body), start)
357+
inContext(prepTemplate(tree, start)(using outerCtx)) {
358+
val constr = transformSpecificTree(tree.constr, start)
359+
val parents = transformTrees(tree.parents, start)(using ctx.superCallContext)
360+
val self = transformSpecificTree(tree.self, start)
361+
val body = transformStats(tree.body, tree.symbol, start)
362+
goTemplate(cpy.Template(tree)(constr, parents, Nil, self, body), start)
363+
}
341364
case tree: Match =>
342-
given Context = prepMatch(tree, start)(using outerCtx)
343-
val selector = transformTree(tree.selector, start)
344-
val cases = transformSpecificTrees(tree.cases, start)
345-
goMatch(cpy.Match(tree)(selector, cases), start)
365+
inContext(prepMatch(tree, start)(using outerCtx)) {
366+
val selector = transformTree(tree.selector, start)
367+
val cases = transformSpecificTrees(tree.cases, start)
368+
goMatch(cpy.Match(tree)(selector, cases), start)
369+
}
346370
case tree: UnApply =>
347-
given Context = prepUnApply(tree, start)(using outerCtx)
348-
val fun = transformTree(tree.fun, start)
349-
val implicits = transformTrees(tree.implicits, start)
350-
val patterns = transformTrees(tree.patterns, start)
351-
goUnApply(cpy.UnApply(tree)(fun, implicits, patterns), start)
371+
inContext(prepUnApply(tree, start)(using outerCtx)) {
372+
val fun = transformTree(tree.fun, start)
373+
val implicits = transformTrees(tree.implicits, start)
374+
val patterns = transformTrees(tree.patterns, start)
375+
goUnApply(cpy.UnApply(tree)(fun, implicits, patterns), start)
376+
}
352377
case tree: PackageDef =>
353-
given Context = prepPackageDef(tree, start)(using outerCtx)
354-
def mapPackage(using Context) = {
355-
val pid = transformSpecificTree(tree.pid, start)
356-
val stats = transformStats(tree.stats, tree.symbol, start)
357-
cpy.PackageDef(tree)(pid, stats)
378+
inContext(prepPackageDef(tree, start)(using outerCtx)) {
379+
def mapPackage(using Context) = {
380+
val pid = transformSpecificTree(tree.pid, start)
381+
val stats = transformStats(tree.stats, tree.symbol, start)
382+
cpy.PackageDef(tree)(pid, stats)
383+
}
384+
goPackageDef(mapPackage(using localContext), start)
358385
}
359-
goPackageDef(mapPackage(using localContext), start)
360386
case tree: Try =>
361-
given Context = prepTry(tree, start)(using outerCtx)
362-
val expr = transformTree(tree.expr, start)
363-
val cases = transformSpecificTrees(tree.cases, start)
364-
val finalizer = transformTree(tree.finalizer, start)
365-
goTry(cpy.Try(tree)(expr, cases, finalizer), start)
387+
inContext(prepTry(tree, start)(using outerCtx)) {
388+
val expr = transformTree(tree.expr, start)
389+
val cases = transformSpecificTrees(tree.cases, start)
390+
val finalizer = transformTree(tree.finalizer, start)
391+
goTry(cpy.Try(tree)(expr, cases, finalizer), start)
392+
}
366393
case tree: Inlined =>
367-
given Context = prepInlined(tree, start)(using outerCtx)
368-
val bindings = transformSpecificTrees(tree.bindings, start)
369-
val expansion = transformTree(tree.expansion, start)(using inlineContext(tree.call))
370-
goInlined(cpy.Inlined(tree)(tree.call, bindings, expansion), start)
394+
inContext(prepInlined(tree, start)(using outerCtx)) {
395+
val bindings = transformSpecificTrees(tree.bindings, start)
396+
val expansion = transformTree(tree.expansion, start)(using inlineContext(tree.call))
397+
goInlined(cpy.Inlined(tree)(tree.call, bindings, expansion), start)
398+
}
371399
case tree: Return =>
372-
given Context = prepReturn(tree, start)(using outerCtx)
373-
val expr = transformTree(tree.expr, start)
374-
goReturn(cpy.Return(tree)(expr, tree.from), start)
375-
// don't transform `tree.from`, as this is not a normal ident, but
376-
// a pointer to the enclosing method.
400+
inContext(prepReturn(tree, start)(using outerCtx)) {
401+
val expr = transformTree(tree.expr, start)
402+
goReturn(cpy.Return(tree)(expr, tree.from), start)
403+
// don't transform `tree.from`, as this is not a normal ident, but
404+
// a pointer to the enclosing method.
405+
}
377406
case tree: WhileDo =>
378-
given Context = prepWhileDo(tree, start)(using outerCtx)
379-
val cond = transformTree(tree.cond, start)
380-
val body = transformTree(tree.body, start)
381-
goWhileDo(cpy.WhileDo(tree)(cond, body), start)
407+
inContext(prepWhileDo(tree, start)(using outerCtx)) {
408+
val cond = transformTree(tree.cond, start)
409+
val body = transformTree(tree.body, start)
410+
goWhileDo(cpy.WhileDo(tree)(cond, body), start)
411+
}
382412
case tree: Alternative =>
383-
given Context = prepAlternative(tree, start)(using outerCtx)
384-
val trees = transformTrees(tree.trees, start)
385-
goAlternative(cpy.Alternative(tree)(trees), start)
413+
inContext(prepAlternative(tree, start)(using outerCtx)) {
414+
val trees = transformTrees(tree.trees, start)
415+
goAlternative(cpy.Alternative(tree)(trees), start)
416+
}
386417
case tree =>
387-
given Context = prepOther(tree, start)(using outerCtx)
388-
goOther(tree, start)
418+
inContext(prepOther(tree, start)(using outerCtx)) {
419+
goOther(tree, start)
420+
}
389421
}
390422

391423
if (tree.source != ctx.source && tree.source.exists)

0 commit comments

Comments
 (0)