Skip to content

Commit 53b75e6

Browse files
committed
Keep QuotePattern until staging
1 parent c3484c6 commit 53b75e6

File tree

10 files changed

+62
-4
lines changed

10 files changed

+62
-4
lines changed

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -740,6 +740,11 @@ object Trees {
740740
case class QuotePattern[+T <: Untyped] private[ast] (bindings: List[Tree[T]], body: Tree[T], quotes: Tree[T])(implicit @constructorOnly src: SourceFile)
741741
extends PatternTree[T] {
742742
type ThisTree[+T <: Untyped] = QuotePattern[T]
743+
744+
/** Type of the quoted expression as seen from outside the quote */
745+
def bodyType(using Context): Type =
746+
val quoteType = typeOpt // `Expr[T]` or `Type[T]`
747+
quoteType.argInfos.head // T
743748
}
744749

745750
/** A tree representing a pattern splice `${ pattern }`, `$ident` or `$ident(args*)` in a quote pattern.

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import config.Config
1919
import collection.mutable
2020
import reporting.{Profile, NoProfile}
2121
import dotty.tools.tasty.TastyFormat.ASTsSection
22+
import quoted.QuotePatterns
2223

2324
object TreePickler:
2425
class StackSizeExceeded(val mdef: tpd.MemberDef) extends Exception
@@ -685,6 +686,9 @@ class TreePickler(pickler: TastyPickler) {
685686
.appliedTo(expr)
686687
.withSpan(tree.span)
687688
)
689+
case tree: QuotePattern =>
690+
// TODO: Add QUOTEPATTERN tag to TASTy
691+
pickleTree(QuotePatterns.encode(tree))
688692
case Hole(_, idx, args, _) =>
689693
writeByte(HOLE)
690694
withLength {

compiler/src/dotty/tools/dotc/quoted/QuotePatterns.scala

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,9 @@ object QuotePatterns:
6767
val patternTypes = quotePattern.bindings.map { binding =>
6868
val sym = binding.symbol
6969
val typeSym = newSymbol(ctx.owner, sym.name ++ "$inPattern" /* TODO remove $inPattern */, EmptyFlags, sym.info, NoSymbol, binding.span)
70-
typeSym.addAnnotation(Annotation(New(ref(defn.QuotedRuntimePatterns_patternTypeAnnot.typeRef)).withSpan(binding.span)))
70+
typeSym.addAnnotation(defn.QuotedRuntimePatterns_patternTypeAnnot)
71+
for fromAbove <- sym.getAnnotation(defn.QuotedRuntimePatterns_fromAboveAnnot) do
72+
typeSym.addAnnotation(fromAbove)
7173
TypeDef(typeSym.asType).withSpan(binding.span)
7274
}
7375
new TreeTypeMap(
@@ -195,6 +197,9 @@ object QuotePatterns:
195197
case _ => false
196198
}
197199
val shapeBindingSyms = tdef.symbol :: tdefs.map(_.symbol)
200+
for (binding, shapeBinding) <- bindings.zip(shapeBindingSyms) do
201+
if shapeBinding.hasAnnotation(defn.QuotedRuntimePatterns_fromAboveAnnot) then
202+
binding.symbol.addAnnotation(defn.QuotedRuntimePatterns_fromAboveAnnot)
198203
val body1 = if stats.isEmpty then expr else cpy.Block(block)(stats, expr)
199204
body1.subst(shapeBindingSyms, bindings.map(_.symbol))
200205
case body => body

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

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@ import dotty.tools.dotc.core.NameKinds._
1010
import dotty.tools.dotc.core.StdNames._
1111
import dotty.tools.dotc.core.Symbols._
1212
import dotty.tools.dotc.core.Types._
13-
import dotty.tools.dotc.staging.StagingLevel.*
13+
import dotty.tools.dotc.quoted.QuotePatterns
1414
import dotty.tools.dotc.staging.QuoteTypeTags.*
15+
import dotty.tools.dotc.staging.StagingLevel.*
1516
import dotty.tools.dotc.util.Property
1617
import dotty.tools.dotc.util.Spans._
1718
import dotty.tools.dotc.util.SrcPos
@@ -104,6 +105,16 @@ class CrossStageSafety extends TreeMapWithStages {
104105
case _: DefDef if tree.symbol.isInlineMethod =>
105106
tree
106107

108+
case tree: CaseDef if level == 0 =>
109+
val pat1 = new TreeMap {
110+
override def transform(tree: tpd.Tree)(using Context): tpd.Tree = tree match
111+
case tree: QuotePattern if level == 0 =>
112+
super.transform(QuotePatterns.encode(tree))
113+
case tree => super.transform(tree)
114+
}.transform(tree.pat)
115+
val tree1 = cpy.CaseDef(tree)(pat1, tree.guard, tree.body)
116+
super.transform(tree1)
117+
107118
case _ if !inQuoteOrSpliceScope =>
108119
checkAnnotations(tree) // Check quotes in annotations
109120
super.transform(tree)

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,15 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase
488488
case _: Quote =>
489489
ctx.compilationUnit.needsStaging = true
490490
super.transform(tree)
491+
case _: QuotePattern =>
492+
if !ctx.reporter.errorsReported then
493+
Checking.checkAppliedTypesIn(TypeTree(tree.tpe).withSpan(tree.span))
494+
ctx.compilationUnit.needsStaging = true
495+
super.transform(tree)
496+
case tree: SplicePattern =>
497+
if !ctx.reporter.errorsReported then
498+
Checking.checkAppliedTypesIn(TypeTree(tree.tpe).withSpan(tree.span))
499+
super.transform(tree)
491500
case tree =>
492501
super.transform(tree)
493502
}

compiler/src/dotty/tools/dotc/typer/QuotesAndSplices.scala

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,9 @@ trait QuotesAndSplices {
102102
case tree => tree
103103
}
104104

105+
def typedQuotePattern(tree: untpd.QuotePattern, pt: Type)(using Context): Tree =
106+
throw new UnsupportedOperationException("cannot type check a Hole node")
107+
105108
def typedSplicePattern(tree: untpd.SplicePattern, pt: Type)(using Context): Tree = {
106109
record("typedSplicePattern")
107110
if isFullyDefined(pt, ForceDegree.flipBottom) then
@@ -448,7 +451,6 @@ trait QuotesAndSplices {
448451

449452
val decoded = QuotePatterns.decode(patternUnapply)
450453
decoded.foreach(QuotePatterns.checkPattern)
451-
val encoded = decoded.map(QuotePatterns.encode).getOrElse(patternUnapply)
452-
encoded
454+
decoded.getOrElse(patternUnapply)
453455
}
454456
}

compiler/src/dotty/tools/dotc/typer/ReTyper.scala

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,27 @@ class ReTyper(nestingLevel: Int = 0) extends Typer(nestingLevel) with ReChecking
111111
val expr1 = typed(tree.expr, quoteType)(using spliceContext)
112112
untpd.cpy.Splice(tree)(expr1).withType(tree.typeOpt)
113113

114+
override def typedQuotePattern(tree: untpd.QuotePattern, pt: Type)(using Context): Tree =
115+
assertTyped(tree)
116+
val bindings1 = tree.bindings.map(typed(_))
117+
val bodyCtx = quoteContext.retractMode(Mode.Pattern)//.addMode(Mode.QuotedPattern)
118+
val body1 = typed(tree.body, tree.bodyType)(using bodyCtx)
119+
val quotes1 = typed(tree.quotes, defn.QuotesClass.typeRef)
120+
untpd.cpy.QuotePattern(tree)(bindings1, body1, quotes1).withType(tree.typeOpt)
121+
122+
123+
override def typedSplicePattern(tree: untpd.SplicePattern, pt: Type)(using Context): Tree =
124+
assertTyped(tree)
125+
val args1 = tree.args.mapconserve(typedExpr(_))
126+
val patternTpe =
127+
if args1.isEmpty then tree.typeOpt
128+
else defn.FunctionType(args1.size).appliedTo(args1.map(_.tpe) :+ tree.typeOpt)
129+
val bodyCtx = spliceContext.addMode(Mode.Pattern)
130+
val body1 = typed(tree.body, defn.QuotedExprClass.typeRef.appliedTo(patternTpe))(using bodyCtx)
131+
val args = tree.args.mapconserve(typedExpr(_))
132+
untpd.cpy.SplicePattern(tree)(body1, args1).withType(tree.typeOpt)
133+
134+
114135
override def typedHole(tree: untpd.Hole, pt: Type)(using Context): Tree =
115136
promote(tree)
116137

compiler/src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3102,6 +3102,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
31023102
case untpd.EmptyTree => tpd.EmptyTree
31033103
case tree: untpd.Quote => typedQuote(tree, pt)
31043104
case tree: untpd.Splice => typedSplice(tree, pt)
3105+
case tree: untpd.QuotePattern => typedQuotePattern(tree, pt)
31053106
case tree: untpd.SplicePattern => typedSplicePattern(tree, pt)
31063107
case tree: untpd.MacroTree => report.error("Unexpected macro", tree.srcPos); tpd.nullLiteral // ill-formed code may reach here
31073108
case tree: untpd.Hole => typedHole(tree, pt)
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)