Skip to content

Commit d479de6

Browse files
committed
Avoid transforming the body in optimization case
1 parent 1053899 commit d479de6

File tree

2 files changed

+48
-33
lines changed

2 files changed

+48
-33
lines changed

compiler/src/dotty/tools/dotc/staging/CrossStageSafety.scala

Lines changed: 23 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -107,47 +107,37 @@ class CrossStageSafety extends TreeMapWithStages {
107107
val stripAnnotsDeep: TypeMap = new TypeMap:
108108
def apply(tp: Type): Type = mapOver(tp.stripAnnots)
109109

110-
val contextWithQuote =
111-
if level == 0 then contextWithQuoteTypeTags(taggedTypes)(using quoteContext)
112-
else quoteContext
113-
val body1 = transform(body)(using contextWithQuote)
114-
val body2 =
110+
def transformBody() =
111+
val contextWithQuote =
112+
if level == 0 then contextWithQuoteTypeTags(taggedTypes)(using quoteContext)
113+
else quoteContext
114+
val transformedBody = transform(body)(using contextWithQuote)
115115
taggedTypes.getTypeTags match
116-
case Nil => body1
117-
case tags => tpd.Block(tags, body1).withSpan(body.span)
116+
case Nil => transformedBody
117+
case tags => tpd.Block(tags, transformedBody).withSpan(body.span)
118118

119119
if body.isTerm then
120+
val transformedBody = transformBody()
120121
// `quoted.runtime.Expr.quote[T](<body>)` --> `quoted.runtime.Expr.quote[T2](<body2>)`
121122
val TypeApply(fun, targs) = quote.fun: @unchecked
122123
val targs2 = targs.map(targ => TypeTree(healType(quote.fun.srcPos)(stripAnnotsDeep(targ.tpe))))
123-
cpy.Apply(quote)(cpy.TypeApply(quote.fun)(fun, targs2), body2 :: Nil)
124+
cpy.Apply(quote)(cpy.TypeApply(quote.fun)(fun, targs2), transformedBody :: Nil)
124125
else
125-
object DirectTypeOfRef:
126-
def unapply(body: Tree): Option[Tree] =
127-
body.tpe match
128-
case tp @ TypeRef(x: TermRef, _) if tp.symbol == defn.QuotedType_splice =>
129-
// Optimization: `quoted.Type.of[x.Underlying](quotes)` --> `x`
130-
Some(ref(x).withSpan(quote.span))
131-
case _ =>
132-
body2 match
133-
case Block(List(tdef: TypeDef), tpt: TypeTree) =>
134-
tpt.tpe match
135-
case tpe: TypeRef if tpe.typeSymbol == tdef.symbol =>
136-
tdef.rhs.tpe.hiBound match
137-
case tp @ TypeRef(x: TermRef, _) if tp.symbol == defn.QuotedType_splice =>
138-
// Optimization: `quoted.Type.of[@SplicedType type T = x.Underlying; T](quotes)` --> `x`
139-
Some(ref(x).withSpan(quote.span))
140-
case _ => None
141-
case _ => None
142-
case _ => None
143-
144-
body match
145-
case DirectTypeOfRef(ref) => ref
126+
body.tpe match
127+
case DirectTypeOf(termRef) =>
128+
// Optimization: `quoted.Type.of[x.Underlying](quotes)` --> `x`
129+
ref(termRef).withSpan(quote.span)
146130
case _ =>
147-
val quotes = quote.args.mapConserve(transform)
148-
// `quoted.Type.of[<body>](quotes)` --> `quoted.Type.of[<body2>](quotes)`
149-
val TypeApply(fun, _) = quote.fun: @unchecked
150-
cpy.Apply(quote)(cpy.TypeApply(quote.fun)(fun, body2 :: Nil), quotes)
131+
transformBody() match
132+
case DirectTypeOf.Healed(termRef) =>
133+
// Optimization: `quoted.Type.of[@SplicedType type T = x.Underlying; T](quotes)` --> `x`
134+
ref(termRef).withSpan(quote.span)
135+
case transformedBody =>
136+
val quotes = quote.args.mapConserve(transform)
137+
// `quoted.Type.of[<body>](quotes)` --> `quoted.Type.of[<body2>](quotes)`
138+
val TypeApply(fun, _) = quote.fun: @unchecked
139+
cpy.Apply(quote)(cpy.TypeApply(quote.fun)(fun, transformedBody :: Nil), quotes)
140+
151141
}
152142

153143
/** Transform splice
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package dotty.tools.dotc.staging
2+
3+
import dotty.tools.dotc.ast.{tpd, untpd}
4+
import dotty.tools.dotc.core.Contexts._
5+
import dotty.tools.dotc.core.Symbols._
6+
import dotty.tools.dotc.core.Types._
7+
8+
object DirectTypeOf:
9+
import tpd.*
10+
11+
/** Matches `x.Underlying` and extracts the TermRef to `x` */
12+
def unapply(tpe: Type)(using Context): Option[TermRef] = tpe match
13+
case tp @ TypeRef(x: TermRef, _) if tp.symbol == defn.QuotedType_splice => Some(x)
14+
case _ => None
15+
16+
object Healed:
17+
/** Matches `{ @SplicedType type T = x.Underlying; T }` and extracts the TermRef to `x` */
18+
def unapply(body: Tree)(using Context): Option[TermRef] =
19+
body match
20+
case Block(List(tdef: TypeDef), tpt: TypeTree) =>
21+
tpt.tpe match
22+
case tpe: TypeRef if tpe.typeSymbol == tdef.symbol =>
23+
DirectTypeOf.unapply(tdef.rhs.tpe.hiBound)
24+
case _ => None
25+
case _ => None

0 commit comments

Comments
 (0)