Skip to content

Commit 357b860

Browse files
committed
Refactor quote cancellation logic
1 parent 1b6e413 commit 357b860

File tree

2 files changed

+32
-41
lines changed

2 files changed

+32
-41
lines changed

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

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -714,17 +714,6 @@ object Trees {
714714
defn.FunctionType(1, isContextual = true)
715715
.appliedTo(defn.QuotesClass.typeRef, exprType)
716716
withType(quoteType)
717-
718-
/** Cancel this Quote if it contains a Splice */
719-
def cancelled(using Context): Option[Tree[T]] =
720-
def rec(tree: Tree[T]): Option[Tree[T]] = tree match
721-
case Block(Nil, expr) => rec(expr)
722-
case Splice(inner) =>
723-
// Optimization: `'{ $x }` --> `x`
724-
// and adapt the refinement of `Quotes { type reflect: ... } ?=> Expr[T]`
725-
Some(inner)
726-
case _ => None
727-
rec(body)
728717
}
729718

730719
/** A tree representing a splice `${ expr }`
@@ -741,16 +730,6 @@ object Trees {
741730
case class Splice[+T <: Untyped] private[ast] (expr: Tree[T])(implicit @constructorOnly src: SourceFile)
742731
extends TermTree[T] {
743732
type ThisTree[+T <: Untyped] = Splice[T]
744-
745-
/** Cancel this Splice if it contains a Quote */
746-
def cancelled(using Context): Option[Tree[T]] =
747-
def rec(tree: Tree[T]): Option[Tree[T]] = tree match
748-
case Block(Nil, expr1) => rec(expr1)
749-
case Quote(body) =>
750-
// Optimization: `${ 'x }` --> `x`
751-
Some(body)
752-
case _ => None
753-
rec(expr)
754733
}
755734

756735
/** A type tree that represents an existing or inferred type */

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

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -51,29 +51,25 @@ class CrossStageSafety extends TreeMapWithStages {
5151
if (tree.source != ctx.source && tree.source.exists)
5252
transform(tree)(using ctx.withSource(tree.source))
5353
else tree match
54+
case CancelledQuote(tree) =>
55+
transform(tree) // Optimization: `'{ $x }` --> `x`
5456
case tree: Quote =>
55-
tree.cancelled match
56-
case Some(tree1) =>
57-
transform(tree1)
58-
case None =>
59-
if (ctx.property(InAnnotation).isDefined)
60-
report.error("Cannot have a quote in an annotation", tree.srcPos)
61-
val body1 = transformQuoteBody(tree.body, tree.span)
62-
val stripAnnotationsDeep: TypeMap = new TypeMap:
63-
def apply(tp: Type): Type = mapOver(tp.stripAnnots)
64-
val bodyType1 = healType(tree.srcPos)(stripAnnotationsDeep(tree.bodyType))
65-
cpy.Quote(tree)(body1).withBodyType(bodyType1)
57+
if (ctx.property(InAnnotation).isDefined)
58+
report.error("Cannot have a quote in an annotation", tree.srcPos)
59+
val body1 = transformQuoteBody(tree.body, tree.span)
60+
val stripAnnotationsDeep: TypeMap = new TypeMap:
61+
def apply(tp: Type): Type = mapOver(tp.stripAnnots)
62+
val bodyType1 = healType(tree.srcPos)(stripAnnotationsDeep(tree.bodyType))
63+
cpy.Quote(tree)(body1).withBodyType(bodyType1)
6664

65+
case CancelledSplice(tree) =>
66+
transform(tree) // Optimization: `${ 'x }` --> `x`
6767
case tree: Splice =>
68-
tree.cancelled match
69-
case Some(tree1) =>
70-
transform(tree1)
71-
case None =>
72-
val body1 = transform(tree.expr)(using spliceContext)
73-
val tpe1 =
74-
if level == 0 then tree.tpe
75-
else healType(tree.srcPos)(tree.tpe.widenTermRefExpr)
76-
untpd.cpy.Splice(tree)(body1).withType(tpe1)
68+
val body1 = transform(tree.expr)(using spliceContext)
69+
val tpe1 =
70+
if level == 0 then tree.tpe
71+
else healType(tree.srcPos)(tree.tpe.widenTermRefExpr)
72+
untpd.cpy.Splice(tree)(body1).withType(tpe1)
7773

7874
case tree @ QuotedTypeOf(body) =>
7975
if (ctx.property(InAnnotation).isDefined)
@@ -224,4 +220,20 @@ class CrossStageSafety extends TreeMapWithStages {
224220
| - but the access is at level $level.$hint""", pos)
225221
tp
226222
}
223+
224+
private object CancelledQuote:
225+
def unapply(tree: Quote): Option[Tree] =
226+
def rec(tree: Tree): Option[Tree] = tree match
227+
case Block(Nil, expr) => rec(expr)
228+
case Splice(inner) => Some(inner)
229+
case _ => None
230+
rec(tree.body)
231+
232+
private object CancelledSplice:
233+
def unapply(tree: Splice): Option[Tree] =
234+
def rec(tree: Tree): Option[Tree] = tree match
235+
case Block(Nil, expr) => rec(expr)
236+
case Quote(inner) => Some(inner)
237+
case _ => None
238+
rec(tree.expr)
227239
}

0 commit comments

Comments
 (0)