Skip to content

Commit df717b5

Browse files
committed
Refactor checks
1 parent 7eb40dc commit df717b5

File tree

2 files changed

+28
-31
lines changed

2 files changed

+28
-31
lines changed

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

Lines changed: 12 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,10 @@ class PCPCheckAndHeal(@constructorOnly ictx: Context) extends TreeMapWithStages(
3838

3939
private val InAnnotation = Property.Key[Unit]()
4040

41-
private[this] var inQuoteOrSplice = false
42-
4341
override def transform(tree: Tree)(implicit ctx: Context): Tree =
4442
if (tree.source != ctx.source && tree.source.exists)
4543
transform(tree)(ctx.withSource(tree.source))
46-
else if !inQuoteOrSplice then
44+
else if !isInQuoteOrSplice then
4745
checkAnnotations(tree)
4846
super.transform(tree)
4947
else tree match {
@@ -54,11 +52,9 @@ class PCPCheckAndHeal(@constructorOnly ictx: Context) extends TreeMapWithStages(
5452
else TypeTree(healedType).withSpan(tree.span)
5553

5654
case _: This =>
57-
if level != -1 && level != levelOf(tree.symbol) then
58-
levelError(tree.symbol, tree.tpe, tree.sourcePos, "")
59-
tree
55+
tree.withType(healTermType(tree.sourcePos)(tree.tpe))
6056
case _: Ident =>
61-
checkTermLevel(tree).withType(healTermType(tree.sourcePos)(tree.tpe))
57+
tree.withType(healTermType(tree.sourcePos)(tree.tpe))
6258

6359
// Remove inline defs in quoted code. Already fully inlined.
6460
case tree: DefDef if tree.symbol.is(Inline) && level > 0 => EmptyTree
@@ -79,16 +75,14 @@ class PCPCheckAndHeal(@constructorOnly ictx: Context) extends TreeMapWithStages(
7975
/** Transform quoted trees while maintaining phase correctness */
8076
override protected def transformQuotation(body: Tree, quote: Tree)(implicit ctx: Context): Tree = {
8177
val taggedTypes = new PCPCheckAndHeal.QuoteTypeTags(quote.span)(using ctx)
78+
8279
if (ctx.property(InAnnotation).isDefined)
8380
ctx.error("Cannot have a quote in an annotation", quote.sourcePos)
8481

8582
val contextWithQuote =
8683
if level == 0 then contextWithQuoteTypeTags(taggedTypes)(quoteContext)
8784
else quoteContext
88-
val inQuoteOrSpliceOld = inQuoteOrSplice
89-
inQuoteOrSplice = true
9085
val body1 = transform(body)(contextWithQuote)
91-
inQuoteOrSplice = inQuoteOrSpliceOld
9286
val body2 =
9387
taggedTypes.getTypeTags match
9488
case Nil => body1
@@ -103,10 +97,7 @@ class PCPCheckAndHeal(@constructorOnly ictx: Context) extends TreeMapWithStages(
10397
* - If inside of a macro definition, check the validity of the macro.
10498
*/
10599
protected def transformSplice(body: Tree, splice: Tree)(implicit ctx: Context): Tree = {
106-
val inQuoteOrSpliceOld = inQuoteOrSplice
107-
inQuoteOrSplice = true
108100
val body1 = transform(body)(spliceContext)
109-
inQuoteOrSplice = inQuoteOrSpliceOld
110101
splice match {
111102
case Apply(fun @ TypeApply(_, _ :: Nil), _) if splice.isTerm =>
112103
// Type of the splice itsel must also be healed
@@ -154,9 +145,8 @@ class PCPCheckAndHeal(@constructorOnly ictx: Context) extends TreeMapWithStages(
154145
tryHeal(tp.symbol, tp, pos).getOrElse(tp)
155146
case _ =>
156147
mapOver(tp)
157-
case tp: ThisType if level != levelOf(tp.cls) =>
158-
if level != -1 then // Ok after inlined
159-
assert(levelError(tp.cls, tp, pos, "").isEmpty)
148+
case tp: ThisType if level != -1 && level != levelOf(tp.cls) =>
149+
levelError(tp.cls, tp, pos, "")
160150
tp
161151
case tp: AnnotatedType =>
162152
val newAnnotTree = transform(tp.annot.tree)
@@ -170,22 +160,17 @@ class PCPCheckAndHeal(@constructorOnly ictx: Context) extends TreeMapWithStages(
170160
tp match
171161
case tp @ TypeRef(NoPrefix, _) if level > levelOf(tp.symbol) =>
172162
tryHeal(tp.symbol, tp, pos).getOrElse(tp)
163+
case tp @ TermRef(NoPrefix, _) if !tp.symbol.isStatic && level != levelOf(tp.symbol) =>
164+
levelError(tp.symbol, tp, pos, "")
165+
tp
166+
case tp: ThisType if level != -1 && level != levelOf(tp.cls) =>
167+
levelError(tp.cls, tp, pos, "")
168+
tp
173169
case _ =>
174170
if tp.typeSymbol.is(Package) then tp
175171
else mapOver(tp)
176172
}
177173

178-
private def checkTermLevel(tree: Tree)(using Context): tree.type = {
179-
new TypeTraverser {
180-
def traverse(tp: Type): Unit =
181-
tp match
182-
case tp @ TermRef(NoPrefix, _) if !tp.symbol.isStatic && level != levelOf(tp.symbol) =>
183-
levelError(tree.symbol, tree.tpe, tree.sourcePos, "")
184-
case _ => traverseChildren(tp)
185-
}.traverse(tree.tpe)
186-
tree
187-
}
188-
189174
// TODO return new type or else old?
190175
protected def tryHeal(sym: Symbol, tp: TypeRef, pos: SourcePosition)(implicit ctx: Context): Option[TypeRef] = {
191176
val reqType = defn.QuotedTypeClass.typeRef.appliedTo(tp)

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

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,17 +35,23 @@ abstract class TreeMapWithStages(@constructorOnly ictx: Context) extends TreeMap
3535
import TreeMapWithStages._
3636

3737
/** A map from locally defined symbols to their definition quotation level */
38-
private val levelOfMap: mutable.HashMap[Symbol, Int] = ictx.property(LevelOfKey).get
38+
private[this] val levelOfMap: mutable.HashMap[Symbol, Int] = ictx.property(LevelOfKey).get
3939

4040
/** A stack of entered symbols, to be unwound after scope exit */
41-
private var enteredSyms: List[Symbol] = Nil
41+
private[this] var enteredSyms: List[Symbol] = Nil
42+
43+
/** If we are inside a quote or a splice */
44+
private[this] var inQuoteOrSplice = false
4245

4346
/** The quotation level of the definition of the locally defined symbol */
4447
protected def levelOf(sym: Symbol): Int = levelOfMap.getOrElse(sym, 0)
4548

4649
/** Localy defined symbols seen so far by `StagingTransformer.transform` */
4750
protected def localSymbols: List[Symbol] = enteredSyms
4851

52+
/** If we are inside a quote or a splice */
53+
protected def isInQuoteOrSplice: Boolean = inQuoteOrSplice
54+
4955
/** Enter staging level of symbol defined by `tree` */
5056
private def markSymbol(sym: Symbol)(implicit ctx: Context): Unit =
5157
if (!levelOfMap.contains(sym))
@@ -88,19 +94,25 @@ abstract class TreeMapWithStages(@constructorOnly ictx: Context) extends TreeMap
8894
tree match {
8995

9096
case Quoted(quotedTree) =>
91-
dropEmptyBlocks(quotedTree) match {
97+
val old = inQuoteOrSplice
98+
inQuoteOrSplice = true
99+
try dropEmptyBlocks(quotedTree) match {
92100
case Spliced(t) =>
93101
// '{ $x } --> x
94102
// and adapt the refinment of `QuoteContext { type tasty: ... } ?=> Expr[T]`
95103
transform(t).asInstance(tree.tpe)
96104
case _ => transformQuotation(quotedTree, tree)
97105
}
106+
finally inQuoteOrSplice = old
98107

99108
case tree @ Spliced(splicedTree) =>
100-
dropEmptyBlocks(splicedTree) match {
109+
val old = inQuoteOrSplice
110+
inQuoteOrSplice = true
111+
try dropEmptyBlocks(splicedTree) match {
101112
case Quoted(t) => transform(t) // ${ 'x } --> x
102113
case _ => transformSplice(splicedTree, tree)
103114
}
115+
finally inQuoteOrSplice = old
104116

105117
case Block(stats, _) =>
106118
val last = enteredSyms

0 commit comments

Comments
 (0)