Skip to content

Commit bc9fd8f

Browse files
committed
Remove splice pickling type workaround
`scala.internal.Quoted.exprSplice` can be used for the same purpose by explicily setting the type parameter of `exprSplice` to a phase correct type alias.
1 parent a62a273 commit bc9fd8f

File tree

4 files changed

+34
-27
lines changed

4 files changed

+34
-27
lines changed

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

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,14 @@ class PCPCheckAndHeal(@constructorOnly ictx: Context) extends TreeMapWithStages(
5252
protected def transformSplice(body: Tree, splice: Tree)(implicit ctx: Context): Tree = {
5353
if (level >= 1) {
5454
val body1 = transform(body)(spliceContext)
55-
val splice1 = splice match {
56-
case splice: Apply => cpy.Apply(splice)(splice.fun, body1 :: Nil)
55+
splice match {
56+
case Apply(fun: TypeApply, _) if splice.isTerm =>
57+
// Type of the splice itsel must also be healed
58+
// internal.Quoted.expr[F[T]](... T ...) --> internal.Quoted.expr[F[$t]](... T ...)
59+
val tp = checkType(splice.sourcePos).apply(splice.tpe.widenTermRefExpr)
60+
cpy.Apply(splice)(cpy.TypeApply(fun)(fun.fun, tpd.TypeTree(tp) :: Nil), body1 :: Nil)
5761
case splice: Select => cpy.Select(splice)(body1, splice.name)
5862
}
59-
60-
if (splice1.isType) splice1
61-
else addSpliceCast(splice1)
6263
}
6364
else {
6465
assert(!enclosingInlineds.nonEmpty, "unexpanded macro")
@@ -76,15 +77,6 @@ class PCPCheckAndHeal(@constructorOnly ictx: Context) extends TreeMapWithStages(
7677
}
7778
}
7879

79-
80-
/** Add cast to force boundaries where T and $t (an alias of T) are used to ensure PCP.
81-
* '{ ${...: T} } --> '{ ${...: T}.asInstanceOf[T] } --> '{ ${...: T}.asInstanceOf[$t] }
82-
*/
83-
protected def addSpliceCast(tree: Tree)(implicit ctx: Context): Tree = {
84-
val tp = checkType(tree.sourcePos).apply(tree.tpe.widenTermRefExpr)
85-
tree.cast(tp).withSpan(tree.span)
86-
}
87-
8880
/** If `tree` refers to a locally defined symbol (either directly, or in a pickled type),
8981
* check that its staging level matches the current level. References to types
9082
* that are phase-incorrect can still be healed as follows:

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

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ class ReifyQuotes extends MacroTransform {
170170
*/
171171
override protected def transformQuotation(body: Tree, quote: Tree)(implicit ctx: Context): Tree = {
172172
val isType = quote.symbol eq defn.InternalQuoted_typeQuote
173-
assert(!body.symbol.isSplice)
173+
assert(!(body.symbol.isSplice && (body.isInstanceOf[GenericApply[_]] || body.isInstanceOf[Select])))
174174
if (level > 0) {
175175
val body1 = nested(isQuote = true).transform(body)(quoteContext)
176176
super.transformQuotation(body1, quote)
@@ -349,12 +349,6 @@ class ReifyQuotes extends MacroTransform {
349349
override def transform(tree: Tree)(implicit ctx: Context): Tree =
350350
reporting.trace(i"Reifier.transform $tree at $level", show = true) {
351351
tree match {
352-
case TypeApply(Select(spliceTree @ Spliced(spliced), _), tp) if tree.symbol.isTypeCast =>
353-
// TODO this branch should be removable with the new splice
354-
// Splice term which should be in the form `${x}.asInstanceOf[T]` where T is an artifact of
355-
// typer to allow pickling/unpickling phase consistent types
356-
transformSplice(spliced, spliceTree)
357-
358352
case tree: RefTree if isCaptured(tree.symbol, level) =>
359353
val body = capturers(tree.symbol).apply(tree)
360354
val splice: Tree =

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

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,6 @@ class Staging extends MacroTransform {
4444
tree match {
4545
case PackageDef(pid, _) if tree.symbol.owner == defn.RootClass =>
4646
val checker = new PCPCheckAndHeal(freshStagingContext) {
47-
override protected def addSpliceCast(tree: Tree)(implicit ctx: Context): Tree = tree
48-
4947
override protected def tryHeal(sym: Symbol, tp: Type, pos: SourcePosition)(implicit ctx: Context): Option[tpd.Tree] = {
5048
def symStr =
5149
if (!tp.isInstanceOf[ThisType]) sym.show

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

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1929,7 +1929,7 @@ class Typer extends Namer
19291929
}
19301930
}
19311931

1932-
/** Translate '{ t }` into `scala.quoted.Expr.apply(t)` and `'[T]` into `scala.quoted.Type.apply[T]`
1932+
/** Translate `'{ t }` into `scala.quoted.Expr.apply(t)` and `'[T]` into `scala.quoted.Type.apply[T]`
19331933
* while tracking the quotation level in the context.
19341934
*/
19351935
def typedQuote(tree: untpd.Quote, pt: Type)(implicit ctx: Context): Tree = track("typedQuote") {
@@ -1941,11 +1941,34 @@ class Typer extends Namer
19411941
tree1.withSpan(tree.span)
19421942
}
19431943

1944-
/** Translate `${ t: Expr[T] }` into expresiion `t.splice` while tracking the quotation level in the context */
1944+
/** Translate `${ t: Expr[T] }` into expression `t.splice` while tracking the quotation level in the context */
19451945
def typedSplice(tree: untpd.Splice, pt: Type)(implicit ctx: Context): Tree = track("typedSplice") {
19461946
checkSpliceOutsideQuote(tree)
1947-
if (tree.isType) typedSelect(untpd.Select(tree.expr, nme.splice), pt)(spliceContext).withSpan(tree.span)
1948-
else typedApply(untpd.Apply(untpd.ref(defn.InternalQuoted_exprSpliceR), tree.expr), pt)(spliceContext)
1947+
val direct = true
1948+
if (direct) {
1949+
// fails: tests/pos/quote-whitebox
1950+
typedApply(untpd.Apply(untpd.ref(defn.InternalQuoted_exprSpliceR), tree.expr), pt)(spliceContext)
1951+
} else {
1952+
// Compile dotty with `direct = true` before switching this branch
1953+
1954+
// fails
1955+
// src from tastyBootstrap/lib
1956+
// tests/neg/i4493-b.scala
1957+
// tests/neg/i4493.scala
1958+
// tests/neg/quote-interpolator-core-old.scala
1959+
// tests/run/quote-change-owner
1960+
// tests/pos/i4493-c.scala
1961+
// tests/pos/i3912-2
1962+
val spliced = typed(tree.expr, defn.QuotedExprType.appliedTo(pt))(spliceContext)
1963+
spliced.tpe.widenTermRefExpr match {
1964+
case exprTpe: AppliedType =>
1965+
assert(exprTpe.classSymbol == defn.QuotedExprClass)
1966+
tpd.ref(defn.InternalQuoted_exprSpliceR).appliedToTypes(exprTpe.args).appliedTo(spliced).withSpan(tree.span)
1967+
case tp: ErrorType =>
1968+
tree.withType(tp)
1969+
}
1970+
}
1971+
19491972
}
19501973

19511974
/** Translate ${ t: Type[T] }` into type `t.splice` while tracking the quotation level in the context */

0 commit comments

Comments
 (0)