Skip to content

Commit fc4a648

Browse files
committed
Avoid cuadratic behaviour with embedding in levels > 1
1 parent b5d0fdf commit fc4a648

File tree

1 file changed

+10
-13
lines changed

1 file changed

+10
-13
lines changed

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

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ class ReifyQuotes extends MacroTransformWithImplicits {
6565
if (ctx.compilationUnit.containsQuotesOrSplices) super.run
6666

6767
protected def newTransformer(implicit ctx: Context): Transformer =
68-
new Reifier(inQuote = false, null, 0, new LevelInfo)
68+
new Reifier(inQuote = false, null, 0, new LevelInfo, new mutable.ListBuffer[Tree])
6969

7070
private class LevelInfo {
7171
/** A map from locally defined symbols to the staging levels of their definitions */
@@ -92,21 +92,22 @@ class ReifyQuotes extends MacroTransformWithImplicits {
9292
* @param outer the next outer reifier, null is this is the topmost transformer
9393
* @param level the current level, where quotes add one and splices subtract one level
9494
* @param levels a stacked map from symbols to the levels in which they were defined
95+
* @param embedded a list of embedded quotes (if `inSplice = true`) or splices (if `inQuote = true`
9596
*/
96-
private class Reifier(inQuote: Boolean, val outer: Reifier, val level: Int, levels: LevelInfo) extends ImplicitsTransformer {
97+
private class Reifier(inQuote: Boolean, val outer: Reifier, val level: Int, levels: LevelInfo,
98+
val embedded: mutable.ListBuffer[Tree]) extends ImplicitsTransformer {
9799
import levels._
98100
assert(level >= 0)
99101

100102
/** A nested reifier for a quote (if `isQuote = true`) or a splice (if not) */
101-
def nested(isQuote: Boolean): Reifier =
102-
new Reifier(isQuote, this, if (isQuote) level + 1 else level - 1, levels)
103+
def nested(isQuote: Boolean): Reifier = {
104+
val nestedEmbedded = if (level > 1 || (level == 1 && isQuote)) embedded else new mutable.ListBuffer[Tree]
105+
new Reifier(isQuote, this, if (isQuote) level + 1 else level - 1, levels, nestedEmbedded)
106+
}
103107

104108
/** We are in a `~(...)` context that is not shadowed by a nested `'(...)` */
105109
def inSplice = outer != null && !inQuote
106110

107-
/** A list of embedded quotes (if `inSplice = true`) or splices (if `inQuote = true`) */
108-
val embedded = new mutable.ListBuffer[Tree]
109-
110111
/** A map from type ref T to expressions of type `quoted.Type[T]`".
111112
* These will be turned into splices using `addTags`
112113
*/
@@ -281,9 +282,7 @@ class ReifyQuotes extends MacroTransformWithImplicits {
281282
private def quotation(body: Tree, quote: Tree)(implicit ctx: Context): Tree = {
282283
val isType = quote.symbol eq defn.typeQuoteMethod
283284
if (level > 0) {
284-
val reifier = nested(isQuote = true)
285-
val body1 = reifier.transform(body)
286-
embedded ++= reifier.embedded
285+
val body1 = nested(isQuote = true).transform(body)
287286
// Keep quotes in quotes as trees to reduce pickled size and have a Expr.show without pickled quotes embedded
288287
if (isType) ref(defn.typeQuoteMethod).appliedToType(body1.tpe.widen)
289288
else ref(defn.quoteMethod).appliedToType(body1.tpe.widen).appliedTo(body1)
@@ -305,9 +304,7 @@ class ReifyQuotes extends MacroTransformWithImplicits {
305304
*/
306305
private def splice(splice: Select)(implicit ctx: Context): Tree = {
307306
if (level > 1) {
308-
val reifier = nested(isQuote = false)
309-
val body1 = reifier.transform(splice.qualifier)
310-
embedded ++= reifier.embedded
307+
val body1 = nested(isQuote = false).transform(splice.qualifier)
311308
body1.select(splice.name)
312309
}
313310
else if (!inQuote && level == 0) {

0 commit comments

Comments
 (0)