Skip to content

Commit fbfddef

Browse files
committed
Avoid transforming the body in optimization case
1 parent dac0bdf commit fbfddef

File tree

1 file changed

+36
-33
lines changed

1 file changed

+36
-33
lines changed

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

Lines changed: 36 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -103,49 +103,52 @@ class PCPCheckAndHeal(@constructorOnly ictx: Context) extends TreeMapWithStages(
103103
if (ctx.property(InAnnotation).isDefined)
104104
report.error("Cannot have a quote in an annotation", quote.srcPos)
105105

106-
val contextWithQuote =
107-
if level == 0 then contextWithQuoteTypeTags(taggedTypes)(using quoteContext)
108-
else quoteContext
109-
val body1 = transform(body)(using contextWithQuote)
110-
val body2 =
106+
def transformBody() =
107+
val contextWithQuote =
108+
if level == 0 then contextWithQuoteTypeTags(taggedTypes)(using quoteContext)
109+
else quoteContext
110+
val transformedBody = transform(body)(using contextWithQuote)
111111
taggedTypes.getTypeTags match
112-
case Nil => body1
113-
case tags => tpd.Block(tags, body1).withSpan(body.span)
112+
case Nil => transformedBody
113+
case tags => tpd.Block(tags, transformedBody).withSpan(body.span)
114114

115115
if body.isTerm then
116+
val transformedBody = transformBody()
116117
// `quoted.runtime.Expr.quote[T](<body>)` --> `quoted.runtime.Expr.quote[T2](<body2>)`
117118
val TypeApply(fun, targs) = quote.fun: @unchecked
118119
val targs2 = targs.map(targ => TypeTree(healTypeOfTerm(quote.fun.srcPos)(targ.tpe)))
119-
cpy.Apply(quote)(cpy.TypeApply(quote.fun)(fun, targs2), body2 :: Nil)
120+
cpy.Apply(quote)(cpy.TypeApply(quote.fun)(fun, targs2), transformedBody :: Nil)
120121
else
121-
object DirectTypeOfRef:
122-
def unapply(body: Tree): Option[Tree] =
123-
body.tpe match
124-
case tp @ TypeRef(x: TermRef, _) if tp.symbol == defn.QuotedType_splice =>
125-
// Optimization: `quoted.Type.of[x.Underlying](quotes)` --> `x`
126-
Some(ref(x).withSpan(quote.span))
127-
case _ =>
128-
body2 match
129-
case Block(List(tdef: TypeDef), tpt: TypeTree) =>
130-
tpt.tpe match
131-
case tpe: TypeRef if tpe.typeSymbol == tdef.symbol =>
132-
tdef.rhs.tpe.hiBound match
133-
case tp @ TypeRef(x: TermRef, _) if tp.symbol == defn.QuotedType_splice =>
134-
// Optimization: `quoted.Type.of[@SplicedType type T = x.Underlying; T](quotes)` --> `x`
135-
Some(ref(x).withSpan(quote.span))
136-
case _ => None
137-
case _ => None
138-
case _ => None
139-
140-
body match
141-
case DirectTypeOfRef(ref) => ref
122+
body.tpe match
123+
case tp @ TypeRef(x: TermRef, _) if tp.symbol == defn.QuotedType_splice =>
124+
// Optimization: `quoted.Type.of[x.Underlying](quotes)` --> `x`
125+
ref(x).withSpan(quote.span)
142126
case _ =>
143-
val quotes = quote.args.mapConserve(transform)
144-
// `quoted.Type.of[<body>](quotes)` --> `quoted.Type.of[<body2>](quotes)`
145-
val TypeApply(fun, _) = quote.fun: @unchecked
146-
cpy.Apply(quote)(cpy.TypeApply(quote.fun)(fun, body2 :: Nil), quotes)
127+
transformBody() match
128+
case HealedDirectQuotedTypeRef(termRef) =>
129+
// Optimization: `quoted.Type.of[@SplicedType type T = x.Underlying; T](quotes)` --> `x`
130+
ref(termRef).withSpan(quote.span)
131+
case transformedBody =>
132+
val quotes = quote.args.mapConserve(transform)
133+
// `quoted.Type.of[<body>](quotes)` --> `quoted.Type.of[<body2>](quotes)`
134+
val TypeApply(fun, _) = quote.fun: @unchecked
135+
cpy.Apply(quote)(cpy.TypeApply(quote.fun)(fun, transformedBody :: Nil), quotes)
136+
147137
}
148138

139+
private object HealedDirectQuotedTypeRef:
140+
/** Matches `quoted.Type.of[@SplicedType type T = x.Underlying; T](quotes)` and extracts the TermRef to `x` */
141+
def unapply(body: Tree)(using Context): Option[TermRef] =
142+
body match
143+
case Block(List(tdef: TypeDef), tpt: TypeTree) =>
144+
tpt.tpe match
145+
case tpe: TypeRef if tpe.typeSymbol == tdef.symbol =>
146+
tdef.rhs.tpe.hiBound match
147+
case tp @ TypeRef(x: TermRef, _) if tp.symbol == defn.QuotedType_splice => Some(x)
148+
case _ => None
149+
case _ => None
150+
case _ => None
151+
149152
/** Transform splice
150153
* - If inside a quote, transform the contents of the splice.
151154
* - If inside inlined code, expand the macro code.

0 commit comments

Comments
 (0)