Skip to content

Commit 35db4a1

Browse files
committed
Move Quote/Splice retyping into ReTyper
1 parent 04f020f commit 35db4a1

File tree

2 files changed

+24
-27
lines changed

2 files changed

+24
-27
lines changed

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

Lines changed: 10 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -31,34 +31,12 @@ trait QuotesAndSplices {
3131

3232
import tpd._
3333

34-
def typedQuote(tree: untpd.Quote, pt: Type)(using Context): Tree =
35-
if tree.tpt.isEmpty then
36-
typedQuoteSyntactic(tree, pt)
37-
else
38-
val tpt1 = checkSimpleKinded(typedType(tree.tpt, mapPatternBounds = true))
39-
val expr1 = typed(tree.expr, tpt1.tpe.widenSkolem)(using quoteContext)
40-
assignType(untpd.cpy.Quote(tree)(expr1, tpt1), tpt1)
41-
42-
def typedSplice(tree: untpd.Splice, pt: Type)(using Context): Tree =
43-
if tree.tpt.isEmpty then
44-
typedSpliceSyntactic(tree, pt)
45-
else
46-
val tpt1 = checkSimpleKinded(typedType(tree.tpt, mapPatternBounds = true))
47-
val splicedType = // Quotes ?=> Expr[T]
48-
defn.FunctionType(1, isContextual = true)
49-
.appliedTo(defn.QuotesClass.typeRef, defn.QuotedExprClass.typeRef.appliedTo(tpt1.tpe.widenSkolem))
50-
val expr1 = typed(tree.expr, splicedType)(using spliceContext)
51-
assignType(untpd.cpy.Splice(tree)(expr1, tpt1), tpt1)
52-
53-
def typedHole(tree: untpd.Hole, pt: Type)(using Context): Tree =
54-
val tpt = typedType(tree.tpt)
55-
assignType(tree, tpt)
56-
5734
/** Translate `'{ e }` into `scala.quoted.Expr.apply(e)` and `'[T]` into `scala.quoted.Type.apply[T]`
5835
* while tracking the quotation level in the context.
5936
*/
60-
private def typedQuoteSyntactic(tree: untpd.Quote, pt: Type)(using Context): Tree = {
37+
def typedQuote(tree: untpd.Quote, pt: Type)(using Context): Tree = {
6138
record("typedQuote")
39+
assert(tree.tpt.isEmpty)
6240
tree.expr match {
6341
case untpd.Splice(innerExpr, _) if tree.isTerm && !ctx.mode.is(Mode.Pattern) =>
6442
report.warning("Canceled splice directly inside a quote. '{ ${ XYZ } } is equivalent to XYZ.", tree.srcPos)
@@ -93,8 +71,9 @@ trait QuotesAndSplices {
9371
}
9472

9573
/** Translate `${ t: Expr[T] }` into expression `t.splice` while tracking the quotation level in the context */
96-
private def typedSpliceSyntactic(tree: untpd.Splice, pt: Type)(using Context): Tree = {
74+
def typedSplice(tree: untpd.Splice, pt: Type)(using Context): Tree = {
9775
record("typedSplice")
76+
assert(tree.tpt.isEmpty)
9877
checkSpliceOutsideQuote(tree)
9978
tree.expr match {
10079
case untpd.Quote(innerExpr, _) if innerExpr.isTerm =>
@@ -137,6 +116,10 @@ trait QuotesAndSplices {
137116
}
138117
}
139118

119+
def typedHole(tree: untpd.Hole, pt: Type)(using Context): Tree =
120+
val tpt = typedType(tree.tpt)
121+
assignType(tree, tpt)
122+
140123
/** Types a splice applied to some arguments `$f(arg1, ..., argn)` in a quote pattern.
141124
*
142125
* The tree is desugared into `$f.apply(arg1, ..., argn)` where the expression `$f`
@@ -154,7 +137,7 @@ trait QuotesAndSplices {
154137
else if isInBraces then // ${x}(...) match an application
155138
val typedArgs = args.map(arg => typedExpr(arg))
156139
val argTypes = typedArgs.map(_.tpe.widenTermRefExpr)
157-
val splice1 = typedSpliceSyntactic(splice, defn.FunctionOf(argTypes, pt))
140+
val splice1 = typedSplice(splice, defn.FunctionOf(argTypes, pt))
158141
Apply(splice1.select(nme.apply), typedArgs).withType(pt).withSpan(tree.span)
159142
else // $x(...) higher-order quasipattern
160143
val typedArgs = args.map {
@@ -167,7 +150,7 @@ trait QuotesAndSplices {
167150
if args.isEmpty then
168151
report.error("Missing arguments for open pattern", tree.srcPos)
169152
val argTypes = typedArgs.map(_.tpe.widenTermRefExpr)
170-
val typedPat = typedSpliceSyntactic(splice, defn.FunctionOf(argTypes, pt))
153+
val typedPat = typedSplice(splice, defn.FunctionOf(argTypes, pt))
171154
ref(defn.QuotedRuntimePatterns_patternHigherOrderHole).appliedToType(pt).appliedTo(typedPat, SeqLiteral(typedArgs, TypeTree(defn.AnyType)))
172155
}
173156

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import ast.{tpd, untpd}
1212
import scala.util.control.NonFatal
1313
import util.Spans.Span
1414
import Nullables._
15+
import staging.StagingLevel.*
1516

1617
/** A version of Typer that keeps all symbols defined and referenced in a
1718
* previously typed tree.
@@ -94,6 +95,19 @@ class ReTyper(nestingLevel: Int = 0) extends Typer(nestingLevel) with ReChecking
9495
override def typedUnApply(tree: untpd.Apply, selType: Type)(using Context): Tree =
9596
typedApply(tree, selType)
9697

98+
override def typedQuote(tree: untpd.Quote, pt: Type)(using Context): Tree =
99+
val tpt1 = checkSimpleKinded(typedType(tree.tpt, mapPatternBounds = true))
100+
val expr1 = typed(tree.expr, tpt1.tpe.widenSkolem)(using quoteContext)
101+
assignType(untpd.cpy.Quote(tree)(expr1, tpt1), tpt1)
102+
103+
override def typedSplice(tree: untpd.Splice, pt: Type)(using Context): Tree =
104+
val tpt1 = checkSimpleKinded(typedType(tree.tpt, mapPatternBounds = true))
105+
val splicedType = // Quotes ?=> Expr[T]
106+
defn.FunctionType(1, isContextual = true)
107+
.appliedTo(defn.QuotesClass.typeRef, defn.QuotedExprClass.typeRef.appliedTo(tpt1.tpe.widenSkolem))
108+
val expr1 = typed(tree.expr, splicedType)(using spliceContext)
109+
assignType(untpd.cpy.Splice(tree)(expr1, tpt1), tpt1)
110+
97111
override def localDummy(cls: ClassSymbol, impl: untpd.Template)(using Context): Symbol = impl.symbol
98112

99113
override def retrieveSym(tree: untpd.Tree)(using Context): Symbol = tree.symbol

0 commit comments

Comments
 (0)