Skip to content

Commit 0ee80f9

Browse files
committed
Place staged type captures in Quote AST
1 parent d103f8c commit 0ee80f9

25 files changed

+249
-251
lines changed

compiler/src/dotty/tools/dotc/CompilationUnit.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ object CompilationUnit {
157157
if tree.symbol.is(Flags.Inline) then
158158
containsInline = true
159159
tree match
160-
case tpd.Quote(_) =>
160+
case _: tpd.Quote =>
161161
containsQuote = true
162162
case tree: tpd.Apply if tree.symbol == defn.QuotedTypeModule_of =>
163163
containsQuote = true

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1976,7 +1976,7 @@ object desugar {
19761976
trees foreach collect
19771977
case Block(Nil, expr) =>
19781978
collect(expr)
1979-
case Quote(body) =>
1979+
case Quote(body, _) =>
19801980
new UntypedTreeTraverser {
19811981
def traverse(tree: untpd.Tree)(using Context): Unit = tree match {
19821982
case Splice(expr) => collect(expr)

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

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -690,9 +690,14 @@ object Trees {
690690
* when type checking. TASTy files will not contain type quotes. Type quotes are used again
691691
* in the `staging` phase to represent the reification of `Type.of[T]]`.
692692
*
693+
* Type tags `tags` are always empty before the `staging` phase. Tags for stage inconsistent
694+
* types are added in the `staging` phase to level 0 quotes. Tags for types that refer to
695+
* definitions in an outer quote are added in the `splicing` phase
696+
*
693697
* @param body The tree that was quoted
698+
* @param tags Term references to instances of `Type[T]` for `T`s that are used in the quote
694699
*/
695-
case class Quote[+T <: Untyped] private[ast] (body: Tree[T])(implicit @constructorOnly src: SourceFile)
700+
case class Quote[+T <: Untyped] private[ast] (body: Tree[T], tags: List[Tree[T]])(implicit @constructorOnly src: SourceFile)
696701
extends TermTree[T] {
697702
type ThisTree[+T <: Untyped] = Quote[T]
698703

@@ -1313,9 +1318,9 @@ object Trees {
13131318
case tree: Inlined if (call eq tree.call) && (bindings eq tree.bindings) && (expansion eq tree.expansion) => tree
13141319
case _ => finalize(tree, untpd.Inlined(call, bindings, expansion)(sourceFile(tree)))
13151320
}
1316-
def Quote(tree: Tree)(body: Tree)(using Context): Quote = tree match {
1317-
case tree: Quote if (body eq tree.body) => tree
1318-
case _ => finalize(tree, untpd.Quote(body)(sourceFile(tree)))
1321+
def Quote(tree: Tree)(body: Tree, tags: List[Tree])(using Context): Quote = tree match {
1322+
case tree: Quote if (body eq tree.body) && (tags eq tree.tags) => tree
1323+
case _ => finalize(tree, untpd.Quote(body, tags)(sourceFile(tree)))
13191324
}
13201325
def Splice(tree: Tree)(expr: Tree)(using Context): Splice = tree match {
13211326
case tree: Splice if (expr eq tree.expr) => tree
@@ -1558,8 +1563,8 @@ object Trees {
15581563
case Thicket(trees) =>
15591564
val trees1 = transform(trees)
15601565
if (trees1 eq trees) tree else Thicket(trees1)
1561-
case tree @ Quote(body) =>
1562-
cpy.Quote(tree)(transform(body)(using quoteContext))
1566+
case Quote(body, tags) =>
1567+
cpy.Quote(tree)(transform(body)(using quoteContext), transform(tags))
15631568
case tree @ Splice(expr) =>
15641569
cpy.Splice(tree)(transform(expr)(using spliceContext))
15651570
case tree @ Hole(isTerm, idx, args, content, tpt) =>
@@ -1703,8 +1708,8 @@ object Trees {
17031708
this(this(x, arg), annot)
17041709
case Thicket(ts) =>
17051710
this(x, ts)
1706-
case Quote(body) =>
1707-
this(x, body)(using quoteContext)
1711+
case Quote(body, tags) =>
1712+
this(this(x, body)(using quoteContext), tags)
17081713
case Splice(expr) =>
17091714
this(x, expr)(using spliceContext)
17101715
case Hole(_, _, args, content, tpt) =>

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,8 +170,8 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
170170
def Inlined(call: Tree, bindings: List[MemberDef], expansion: Tree)(using Context): Inlined =
171171
ta.assignType(untpd.Inlined(call, bindings, expansion), bindings, expansion)
172172

173-
def Quote(body: Tree)(using Context): Quote =
174-
untpd.Quote(body).withBodyType(body.tpe)
173+
def Quote(body: Tree, tags: List[Tree])(using Context): Quote =
174+
untpd.Quote(body, tags).withBodyType(body.tpe)
175175

176176
def Splice(expr: Tree, tpe: Type)(using Context): Splice =
177177
untpd.Splice(expr).withType(tpe)

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,7 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
397397
def SeqLiteral(elems: List[Tree], elemtpt: Tree)(implicit src: SourceFile): SeqLiteral = new SeqLiteral(elems, elemtpt)
398398
def JavaSeqLiteral(elems: List[Tree], elemtpt: Tree)(implicit src: SourceFile): JavaSeqLiteral = new JavaSeqLiteral(elems, elemtpt)
399399
def Inlined(call: tpd.Tree, bindings: List[MemberDef], expansion: Tree)(implicit src: SourceFile): Inlined = new Inlined(call, bindings, expansion)
400-
def Quote(body: Tree)(implicit src: SourceFile): Quote = new Quote(body)
400+
def Quote(body: Tree, tags: List[Tree])(implicit src: SourceFile): Quote = new Quote(body, tags)
401401
def Splice(expr: Tree)(implicit src: SourceFile): Splice = new Splice(expr)
402402
def TypeTree()(implicit src: SourceFile): TypeTree = new TypeTree()
403403
def InferredTypeTree()(implicit src: SourceFile): TypeTree = new InferredTypeTree()

compiler/src/dotty/tools/dotc/core/Phases.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ object Phases {
211211
private var mySbtExtractDependenciesPhase: Phase = _
212212
private var myPicklerPhase: Phase = _
213213
private var myInliningPhase: Phase = _
214+
private var myStagingPhase: Phase = _
214215
private var mySplicingPhase: Phase = _
215216
private var myFirstTransformPhase: Phase = _
216217
private var myCollectNullableFieldsPhase: Phase = _
@@ -235,6 +236,7 @@ object Phases {
235236
final def sbtExtractDependenciesPhase: Phase = mySbtExtractDependenciesPhase
236237
final def picklerPhase: Phase = myPicklerPhase
237238
final def inliningPhase: Phase = myInliningPhase
239+
final def stagingPhase: Phase = myStagingPhase
238240
final def splicingPhase: Phase = mySplicingPhase
239241
final def firstTransformPhase: Phase = myFirstTransformPhase
240242
final def collectNullableFieldsPhase: Phase = myCollectNullableFieldsPhase
@@ -262,6 +264,7 @@ object Phases {
262264
mySbtExtractDependenciesPhase = phaseOfClass(classOf[sbt.ExtractDependencies])
263265
myPicklerPhase = phaseOfClass(classOf[Pickler])
264266
myInliningPhase = phaseOfClass(classOf[Inlining])
267+
myStagingPhase = phaseOfClass(classOf[Staging])
265268
mySplicingPhase = phaseOfClass(classOf[Splicing])
266269
myFirstTransformPhase = phaseOfClass(classOf[FirstTransform])
267270
myCollectNullableFieldsPhase = phaseOfClass(classOf[CollectNullableFields])
@@ -449,6 +452,7 @@ object Phases {
449452
def sbtExtractDependenciesPhase(using Context): Phase = ctx.base.sbtExtractDependenciesPhase
450453
def picklerPhase(using Context): Phase = ctx.base.picklerPhase
451454
def inliningPhase(using Context): Phase = ctx.base.inliningPhase
455+
def stagingPhase(using Context): Phase = ctx.base.stagingPhase
452456
def splicingPhase(using Context): Phase = ctx.base.splicingPhase
453457
def firstTransformPhase(using Context): Phase = ctx.base.firstTransformPhase
454458
def refchecksPhase(using Context): Phase = ctx.base.refchecksPhase

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -665,7 +665,7 @@ class TreePickler(pickler: TastyPickler) {
665665
pickleTree(hi)
666666
pickleTree(alias)
667667
}
668-
case tree @ Quote(body) =>
668+
case tree @ Quote(body, Nil) =>
669669
// TODO: Add QUOTE tag to TASTy
670670
assert(body.isTerm,
671671
"""Quote with type should not be pickled.

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1269,7 +1269,7 @@ class TreeUnpickler(reader: TastyReader,
12691269

12701270
def quotedExpr(fn: Tree, args: List[Tree]): Tree =
12711271
val TypeApply(_, targs) = fn: @unchecked
1272-
untpd.Quote(args.head).withBodyType(targs.head.tpe)
1272+
untpd.Quote(args.head, Nil).withBodyType(targs.head.tpe)
12731273

12741274
def splicedExpr(fn: Tree, args: List[Tree]): Tree =
12751275
val TypeApply(_, targs) = fn: @unchecked

compiler/src/dotty/tools/dotc/inlines/Inliner.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -827,7 +827,7 @@ class Inliner(val call: tpd.Tree)(using Context):
827827

828828
override def typedQuote(tree: untpd.Quote, pt: Type)(using Context): Tree =
829829
super.typedQuote(tree, pt) match
830-
case Quote(Splice(inner)) => inner
830+
case Quote(Splice(inner), _) => inner
831831
case tree1 =>
832832
ctx.compilationUnit.needsStaging = true
833833
tree1

compiler/src/dotty/tools/dotc/parsing/Parsers.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1243,7 +1243,7 @@ object Parsers {
12431243
}
12441244
}
12451245
in.nextToken()
1246-
Quote(t)
1246+
Quote(t, Nil)
12471247
}
12481248
else
12491249
if !in.featureEnabled(Feature.symbolLiterals) then
@@ -2480,7 +2480,7 @@ object Parsers {
24802480
val body =
24812481
if (in.token == LBRACKET) inBrackets(typ())
24822482
else stagedBlock()
2483-
Quote(body)
2483+
Quote(body, Nil)
24842484
}
24852485
}
24862486
case NEW =>

0 commit comments

Comments
 (0)