Skip to content

Unencode quote and splice trees #17342

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 46 commits into from
May 2, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
c2f6362
Rename `Spliced` to `SplicedExpr`
nicolasstucki Apr 21, 2023
938d3ae
Split `Quoted` extractor into `QuotedExpr` and `QuotedTypeOf`
nicolasstucki Apr 21, 2023
b7ca9b1
Split `transformQuotation` into `transformQuotedExpr` and `transformQ…
nicolasstucki Apr 21, 2023
deb03a7
Add `QuotedExpr` to encode quotes directly in the AST
nicolasstucki Apr 21, 2023
b7a7227
Add `SplicedExpr` to encode splices directly in the AST
nicolasstucki Apr 21, 2023
fe64a3e
Remove splice outer quotes context
nicolasstucki Apr 25, 2023
161ef49
Rename `SplicedExpr.{spliced=>expr}`
nicolasstucki Apr 25, 2023
cf30d30
Use QuotedExpr instead of Quote trees
nicolasstucki Apr 25, 2023
f0d758b
Use SplicedExpr instead of Splice trees
nicolasstucki Apr 25, 2023
c6adab8
Move typedQuotedExpr/typedSplicedExpr to QuotesAndSplices
nicolasstucki Apr 25, 2023
3a045c4
Rename QuotedExpr to Quote and SplicedExpr to Splice
nicolasstucki Apr 25, 2023
76d0daf
Add documentation
nicolasstucki Apr 25, 2023
75bacdb
Backwards compatibility support for quotes and splice in reflection API
nicolasstucki Apr 25, 2023
0e6dc2e
Add regression test
nicolasstucki Apr 25, 2023
cdd5ffb
Adapt REPL test output
nicolasstucki Apr 26, 2023
04f020f
Remove `Splice.isInBraces`
nicolasstucki Apr 27, 2023
35db4a1
Move Quote/Splice retyping into ReTyper
nicolasstucki Apr 27, 2023
1ef7f59
Add documentation
nicolasstucki Apr 27, 2023
687d06e
Transform Quote/Splice in MiniPhase
nicolasstucki Apr 27, 2023
1f62049
Add TODOs and fix typos
nicolasstucki Apr 28, 2023
5ae7861
Remove `tpt` from `Quote`
nicolasstucki Apr 28, 2023
3976d06
Remove `tpt` from `Splice`
nicolasstucki Apr 28, 2023
d4b2f09
Rename `Quote.{expr=>body}`
nicolasstucki Apr 28, 2023
35408ec
Fix staging level tracking in Transformer
nicolasstucki Apr 28, 2023
e73eab7
Cleanup unnecessary staging level updates
nicolasstucki Apr 28, 2023
e06b0f9
Use `Quote to encode `Type.of` in the `staging phase`
nicolasstucki May 1, 2023
095a7f1
Remove state from TreeMapWithStages
nicolasstucki May 1, 2023
10cbc60
Fix wrong staging level error message
nicolasstucki May 1, 2023
3097f49
Simplify quoted type transformation in CrossStageSafety
nicolasstucki May 1, 2023
8a9871f
Simplify Quote/Splice transformations in CrossStageSafety
nicolasstucki May 1, 2023
966835b
Deduplicate code that transforms `Quote`, `Splice`, `Type.of`
nicolasstucki May 1, 2023
95c39bc
Cleanup
nicolasstucki May 1, 2023
0ca6066
Remove redundant case
nicolasstucki May 1, 2023
e3735fa
Refactor
nicolasstucki May 1, 2023
6956c43
Refactor quote cancellation logic
nicolasstucki May 1, 2023
859f6e6
Remove unnecessary quotation level change
nicolasstucki May 1, 2023
e4ddc88
Add missing change of staging level
nicolasstucki May 1, 2023
7e8d2b1
Simplify macroDependencies using level from context
nicolasstucki May 1, 2023
a3c657b
Fix typo
nicolasstucki May 1, 2023
be3cd48
Refactor use of Quote
nicolasstucki May 1, 2023
7bd7c92
Do not traverse type trees to find inline method calls
nicolasstucki May 1, 2023
b991b40
Remove post-condition that is already checked by Staging
nicolasstucki May 1, 2023
e611139
Refactor quote pickling case
nicolasstucki May 1, 2023
37200be
Cleanup
nicolasstucki May 1, 2023
e75cafe
Remove unnecessary widening
nicolasstucki May 1, 2023
9214daa
Apply suggestions from code review
nicolasstucki May 1, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 0 additions & 10 deletions compiler/src/dotty/tools/dotc/ast/TreeInfo.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1039,16 +1039,6 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] =>
else None
}

/** Extractors for splices */
object SplicedExpr {
/** Extracts the content of a spliced expression tree.
* The result can be the contents of a term splice, which
* will return a term tree.
*/
def unapply(tree: tpd.Apply)(using Context): Option[tpd.Tree] =
if tree.symbol.isExprSplice then Some(tree.args.head) else None
}

/** Extractors for type splices */
object SplicedType {
/** Extracts the content of a spliced type tree.
Expand Down
16 changes: 16 additions & 0 deletions compiler/src/dotty/tools/dotc/ast/Trees.scala
Original file line number Diff line number Diff line change
Expand Up @@ -682,6 +682,11 @@ object Trees {
type ThisTree[+T <: Untyped] = QuotedExpr[T]
}

case class SplicedExpr[+T <: Untyped] private[ast] (spliced: Tree[T], tpt: Tree[T], outerQuotes: Tree[T])(implicit @constructorOnly src: SourceFile)
extends TermTree[T] {
type ThisTree[+T <: Untyped] = SplicedExpr[T]
}

/** A type tree that represents an existing or inferred type */
case class TypeTree[+T <: Untyped]()(implicit @constructorOnly src: SourceFile)
extends DenotingTree[T] with TypTree[T] {
Expand Down Expand Up @@ -1093,6 +1098,7 @@ object Trees {
type JavaSeqLiteral = Trees.JavaSeqLiteral[T]
type Inlined = Trees.Inlined[T]
type QuotedExpr = Trees.QuotedExpr[T]
type SplicedExpr = Trees.SplicedExpr[T]
type TypeTree = Trees.TypeTree[T]
type InferredTypeTree = Trees.InferredTypeTree[T]
type SingletonTypeTree = Trees.SingletonTypeTree[T]
Expand Down Expand Up @@ -1267,6 +1273,10 @@ object Trees {
case tree: QuotedExpr if (expr eq tree.expr) && (tpt eq tree.tpt) => tree
case _ => finalize(tree, untpd.QuotedExpr(expr, tpt)(sourceFile(tree)))
}
def SplicedExpr(tree: Tree)(spliced: Tree, tpt: Tree, outerQuotes: Tree)(using Context): SplicedExpr = tree match {
case tree: SplicedExpr if (spliced eq tree.spliced) && (tpt eq tree.tpt) && (outerQuotes eq tree.outerQuotes) => tree
case _ => finalize(tree, untpd.SplicedExpr(spliced, tpt, outerQuotes)(sourceFile(tree)))
}
def SingletonTypeTree(tree: Tree)(ref: Tree)(using Context): SingletonTypeTree = tree match {
case tree: SingletonTypeTree if (ref eq tree.ref) => tree
case _ => finalize(tree, untpd.SingletonTypeTree(ref)(sourceFile(tree)))
Expand Down Expand Up @@ -1372,6 +1382,8 @@ object Trees {
TypeDef(tree: Tree)(name, rhs)
def Template(tree: Template)(using Context)(constr: DefDef = tree.constr, parents: List[Tree] = tree.parents, derived: List[untpd.Tree] = tree.derived, self: ValDef = tree.self, body: LazyTreeList = tree.unforcedBody): Template =
Template(tree: Tree)(constr, parents, derived, self, body)
def SplicedExpr(tree: SplicedExpr)(spliced: Tree = tree.spliced, tpt: Tree = tree.tpt, outerQuotes: Tree = tree.outerQuotes)(using Context): SplicedExpr =
SplicedExpr(tree: Tree)(spliced, tpt, outerQuotes)
def Hole(tree: Hole)(isTerm: Boolean = tree.isTerm, idx: Int = tree.idx, args: List[Tree] = tree.args, content: Tree = tree.content, tpt: Tree = tree.tpt)(using Context): Hole =
Hole(tree: Tree)(isTerm, idx, args, content, tpt)

Expand Down Expand Up @@ -1506,6 +1518,8 @@ object Trees {
if (trees1 eq trees) tree else Thicket(trees1)
case tree @ QuotedExpr(expr, tpt) =>
cpy.QuotedExpr(tree)(transform(expr), transform(tpt))
case tree @ SplicedExpr(spliced, tpt, outerQuotes) =>
cpy.SplicedExpr(tree)(transform(spliced), transform(tpt), transform(outerQuotes))
case tree @ Hole(_, _, args, content, tpt) =>
cpy.Hole(tree)(args = transform(args), content = transform(content), tpt = transform(tpt))
case _ =>
Expand Down Expand Up @@ -1649,6 +1663,8 @@ object Trees {
this(x, ts)
case QuotedExpr(expr, tpt) =>
this(this(x, expr), tpt)
case SplicedExpr(spliced, tpt, outerQuotes) =>
this(this(this(x, spliced), tpt), outerQuotes)
case Hole(_, _, args, content, tpt) =>
this(this(this(x, args), content), tpt)
case _ =>
Expand Down
3 changes: 3 additions & 0 deletions compiler/src/dotty/tools/dotc/ast/tpd.scala
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,9 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
def QuotedExpr(expr: Tree, tpt: Tree)(using Context): QuotedExpr =
ta.assignType(untpd.QuotedExpr(expr, tpt), tpt)

def SplicedExpr(spliced: Tree, tpt: Tree, outerQuotes: Tree)(using Context): SplicedExpr =
ta.assignType(untpd.SplicedExpr(spliced, tpt, outerQuotes), tpt)

def TypeTree(tp: Type, inferred: Boolean = false)(using Context): TypeTree =
(if inferred then untpd.InferredTypeTree() else untpd.TypeTree()).withType(tp)

Expand Down
1 change: 1 addition & 0 deletions compiler/src/dotty/tools/dotc/ast/untpd.scala
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,7 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
def JavaSeqLiteral(elems: List[Tree], elemtpt: Tree)(implicit src: SourceFile): JavaSeqLiteral = new JavaSeqLiteral(elems, elemtpt)
def Inlined(call: tpd.Tree, bindings: List[MemberDef], expansion: Tree)(implicit src: SourceFile): Inlined = new Inlined(call, bindings, expansion)
def QuotedExpr(expr: Tree, tpt: Tree)(implicit src: SourceFile): QuotedExpr = new QuotedExpr(expr, tpt)
def SplicedExpr(spliced: Tree, tpt: Tree, outerQuotes: Tree)(implicit src: SourceFile): SplicedExpr = new SplicedExpr(spliced, tpt, outerQuotes)
def TypeTree()(implicit src: SourceFile): TypeTree = new TypeTree()
def InferredTypeTree()(implicit src: SourceFile): TypeTree = new InferredTypeTree()
def SingletonTypeTree(ref: Tree)(implicit src: SourceFile): SingletonTypeTree = new SingletonTypeTree(ref)
Expand Down
17 changes: 17 additions & 0 deletions compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,23 @@ class TreePickler(pickler: TastyPickler) {
.appliedTo(expr)
.withSpan(tree.span)
)
case SplicedExpr(spliced, tpt, EmptyTree) =>
pickleTree(
// scala.quoted.runtime.Expr.splice[<tpt>](<spliced>)
ref(defn.QuotedRuntime_exprSplice)
.appliedToTypeTree(tpt)
.appliedTo(spliced)
.withSpan(tree.span)
)
case SplicedExpr(spliced, tpt, quotes) =>
pickleTree(
// scala.quoted.runtime.Expr.nestedSplice[<tpt>](<quotes>)(<spliced>)
ref(defn.QuotedRuntime_exprNestedSplice)
.appliedToTypeTree(tpt)
.appliedTo(quotes)
.appliedTo(spliced)
.withSpan(tree.span)
)
case Hole(_, idx, args, _, tpt) =>
writeByte(HOLE)
withLength {
Expand Down
13 changes: 13 additions & 0 deletions compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1271,6 +1271,17 @@ class TreeUnpickler(reader: TastyReader,
val TypeApply(_, targs) = fn: @unchecked
QuotedExpr(args.head, targs.head)

def splicedExpr(fn: Tree, args: List[Tree]): Tree =
val TypeApply(_, targs) = fn: @unchecked
SplicedExpr(args.head, targs.head, EmptyTree)

def nestedSpliceExpr(fn: Tree, args: List[Tree]): Tree =
fn match
case Apply(TypeApply(_, targs), outerQuotes :: Nil) =>
SplicedExpr(args.head, targs.head, outerQuotes)
case _ => // nestedSplice[T](quotes)
tpd.Apply(fn, args)

def simplifyLub(tree: Tree): Tree =
tree.overwriteType(tree.tpe.simplified)
tree
Expand All @@ -1288,6 +1299,8 @@ class TreeUnpickler(reader: TastyReader,
val args = until(end)(readTree())
if fn.symbol.isConstructor then constructorApply(fn, args)
else if fn.symbol == defn.QuotedRuntime_exprQuote then quotedExpr(fn, args)
else if fn.symbol == defn.QuotedRuntime_exprSplice then splicedExpr(fn, args)
else if fn.symbol == defn.QuotedRuntime_exprNestedSplice then nestedSpliceExpr(fn, args)
else tpd.Apply(fn, args)
case TYPEAPPLY =>
tpd.TypeApply(readTree(), until(end)(readTpt()))
Expand Down
35 changes: 17 additions & 18 deletions compiler/src/dotty/tools/dotc/inlines/Inliner.scala
Original file line number Diff line number Diff line change
Expand Up @@ -815,22 +815,8 @@ class Inliner(val call: tpd.Tree)(using Context):
super.typedValDef(vdef1, sym)

override def typedApply(tree: untpd.Apply, pt: Type)(using Context): Tree =
def cancelQuotes(tree: Tree): Tree =
tree match
case QuotedExpr(SplicedExpr(inner), _) => inner
case _ => tree
val locked = ctx.typerState.ownedVars
val res = cancelQuotes(constToLiteral(BetaReduce(super.typedApply(tree, pt)))) match {
case res: Apply if res.symbol == defn.QuotedRuntime_exprSplice
&& StagingLevel.level == 0
&& !hasInliningErrors =>
val expanded = expandMacro(res.args.head, tree.srcPos)
transform.TreeChecker.checkMacroGeneratedTree(res, expanded)
typedExpr(expanded) // Inline calls and constant fold code generated by the macro
case res =>
specializeEq(inlineIfNeeded(res, pt, locked))
}
res
specializeEq(inlineIfNeeded(constToLiteral(BetaReduce(super.typedApply(tree, pt))), pt, locked))

override def typedTypeApply(tree: untpd.TypeApply, pt: Type)(using Context): Tree =
val locked = ctx.typerState.ownedVars
Expand All @@ -840,8 +826,21 @@ class Inliner(val call: tpd.Tree)(using Context):
tree1

override def typedQuotedExpr(tree: untpd.QuotedExpr, pt: Type)(using Context): Tree =
ctx.compilationUnit.needsStaging = true
super.typedQuotedExpr(tree, pt)
super.typedQuotedExpr(tree, pt) match
case QuotedExpr(SplicedExpr(inner, _, _), _) => inner
case tree1 =>
ctx.compilationUnit.needsStaging = true
tree1

override def typedSplicedExpr(tree: untpd.SplicedExpr, pt: Type)(using Context): Tree =
super.typedSplicedExpr(tree, pt) match
case tree1 @ SplicedExpr(spliced, tpt, EmptyTree)
if StagingLevel.level == 0
&& !hasInliningErrors =>
val expanded = expandMacro(spliced, tree1.srcPos)
transform.TreeChecker.checkMacroGeneratedTree(tree1, expanded)
typedExpr(expanded) // Inline calls and constant fold code generated by the macro
case tree1 => tree1

override def typedMatch(tree: untpd.Match, pt: Type)(using Context): Tree =
val tree1 =
Expand Down Expand Up @@ -1079,7 +1078,7 @@ class Inliner(val call: tpd.Tree)(using Context):
level += 1
try apply(syms, body)
finally level -= 1
case SplicedExpr(body) =>
case SplicedExpr(body, _, _) =>
level -= 1
try apply(syms, body)
finally level += 1
Expand Down
6 changes: 3 additions & 3 deletions compiler/src/dotty/tools/dotc/inlines/PrepareInlineable.scala
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ object PrepareInlineable {
private def stagingContext(tree: Tree)(using Context): Context = tree match
case tree: QuotedExpr => StagingLevel.quoteContext
case tree: Apply if tree.symbol eq defn.QuotedTypeModule_of => StagingLevel.quoteContext
case tree: Apply if tree.symbol.isExprSplice => StagingLevel.spliceContext
case tree: SplicedExpr => StagingLevel.spliceContext
case _ => ctx
}

Expand Down Expand Up @@ -155,7 +155,7 @@ object PrepareInlineable {
val qual = qualifier(refPart)
inlining.println(i"adding receiver passing inline accessor for $tree/$refPart -> (${qual.tpe}, $refPart: ${refPart.getClass}, $argss%, %")

// Need to dealias in order to cagtch all possible references to abstracted over types in
// Need to dealias in order to catch all possible references to abstracted over types in
// substitutions
val dealiasMap = new TypeMap {
def apply(t: Type) = mapOver(t.dealias)
Expand Down Expand Up @@ -291,7 +291,7 @@ object PrepareInlineable {
if (inlined.is(Macro) && !ctx.isAfterTyper) {

def checkMacro(tree: Tree): Unit = tree match {
case SplicedExpr(code) =>
case SplicedExpr(code, _, _) =>
if (code.symbol.flags.is(Inline))
report.error("Macro cannot be implemented with an `inline` method", code.srcPos)
Splicer.checkValidMacroBody(code)
Expand Down
6 changes: 4 additions & 2 deletions compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -432,8 +432,6 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
changePrec (GlobalPrec) {
keywordStr("throw ") ~ toText(args.head)
}
else if (!printDebug && fun.hasType && fun.symbol.isExprSplice)
keywordStr("${") ~ toTextGlobal(args, ", ") ~ keywordStr("}")
else
toTextLocal(fun)
~ "("
Expand Down Expand Up @@ -725,6 +723,10 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
case QuotedExpr(expr, tpt) =>
val tptText = (keywordStr("[") ~ toTextGlobal(tpt) ~ keywordStr("]")).provided(printDebug)
keywordStr("'") ~ tptText ~ keywordStr("{") ~ toTextGlobal(expr) ~ keywordStr("}")
case SplicedExpr(spliced, tpt, quotes) =>
val tptText = (keywordStr("[") ~ toTextGlobal(tpt) ~ keywordStr("]")).provided(printDebug)
val quotesText = (keywordStr("(using ") ~ toTextGlobal(quotes) ~ keywordStr(")")).provided(printDebug)
keywordStr("$") ~ tptText ~ keywordStr("{") ~ toTextGlobal(spliced) ~ keywordStr("}") ~ quotesText
case Hole(isTermHole, idx, args, content, tpt) =>
val (prefix, postfix) = if isTermHole then ("{{{", "}}}") else ("[[[", "]]]")
val argsText = toTextGlobal(args, ", ")
Expand Down
20 changes: 8 additions & 12 deletions compiler/src/dotty/tools/dotc/staging/CrossStageSafety.scala
Original file line number Diff line number Diff line change
Expand Up @@ -143,20 +143,16 @@ class CrossStageSafety extends TreeMapWithStages {
* - If inside inlined code, expand the macro code.
* - If inside of a macro definition, check the validity of the macro.
*/
protected def transformSplice(body: Tree, splice: Apply)(using Context): Tree = {
protected def transformSplice(body: Tree, splice: SplicedExpr)(using Context): Tree = {
val body1 = transform(body)(using spliceContext)
splice.fun match {
case fun @ TypeApply(_, _ :: Nil) =>
// Type of the splice itself must also be healed
// `quoted.runtime.Expr.quote[F[T]](... T ...)` --> `internal.Quoted.expr[F[$t]](... T ...)`
val tpt1 =
if level == 0 then
transform(splice.tpt)
else
val tp = healType(splice.srcPos)(splice.tpe.widenTermRefExpr)
cpy.Apply(splice)(cpy.TypeApply(fun)(fun.fun, tpd.TypeTree(tp) :: Nil), body1 :: Nil)
case f @ Apply(fun @ TypeApply(_, _), quotes :: Nil) =>
// Type of the splice itself must also be healed
// `quoted.runtime.Expr.quote[F[T]](... T ...)` --> `internal.Quoted.expr[F[$t]](... T ...)`
val tp = healType(splice.srcPos)(splice.tpe.widenTermRefExpr)
cpy.Apply(splice)(cpy.Apply(f)(cpy.TypeApply(fun)(fun.fun, tpd.TypeTree(tp) :: Nil), quotes :: Nil), body1 :: Nil)
}
TypeTree(tp).withSpan(splice.tpt.span)
val outerQuotes1 = splice.outerQuotes
cpy.SplicedExpr(splice)(body1, tpt1, outerQuotes1)
}

protected def transformSpliceType(body: Tree, splice: Select)(using Context): Tree = {
Expand Down
9 changes: 5 additions & 4 deletions compiler/src/dotty/tools/dotc/staging/TreeMapWithStages.scala
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ abstract class TreeMapWithStages extends TreeMapWithImplicits {
cpy.Apply(quote)(cpy.TypeApply(quote.fun)(fun, body :: Nil), quote.args)

/** Transform the expression splice `splice` which contains the spliced `body`. */
protected def transformSplice(body: Tree, splice: Apply)(using Context): Tree
protected def transformSplice(body: Tree, splice: SplicedExpr)(using Context): Tree

/** Transform the type splice `splice` which contains the spliced `body`. */
protected def transformSpliceType(body: Tree, splice: Select)(using Context): Tree
Expand Down Expand Up @@ -66,7 +66,7 @@ abstract class TreeMapWithStages extends TreeMapWithImplicits {
val old = inQuoteOrSplice
inQuoteOrSplice = true
try dropEmptyBlocks(quotedTree) match {
case SplicedExpr(t) =>
case SplicedExpr(t, _, _) =>
// Optimization: `'{ $x }` --> `x`
// and adapt the refinement of `Quotes { type reflect: ... } ?=> Expr[T]`
transform(t).asInstance(tree.tpe)
Expand All @@ -75,14 +75,15 @@ abstract class TreeMapWithStages extends TreeMapWithImplicits {
}
finally inQuoteOrSplice = old

case tree @ SplicedExpr(splicedTree) =>
case tree @ SplicedExpr(splicedTree, _, _) =>
val old = inQuoteOrSplice
inQuoteOrSplice = true
try dropEmptyBlocks(splicedTree) match {
case QuotedExpr(t, _) =>
// Optimization: `${ 'x }` --> `x`
transform(t)
case _ => transformSplice(splicedTree, tree)
case _ =>
transformSplice(splicedTree, tree)
}
finally inQuoteOrSplice = old

Expand Down
6 changes: 6 additions & 0 deletions compiler/src/dotty/tools/dotc/transform/ElimByName.scala
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,12 @@ class ElimByName extends MiniPhase, InfoTransformer:
else tree
}

override def transformOther(tree: Tree)(using Context): Tree = tree match
case tree @ SplicedExpr(spliced, tpt, outerQuotes) =>
assert(dotty.tools.dotc.inlines.Inlines.inInlineMethod)
cpy.SplicedExpr(tree)(transformAllDeep(spliced), tpt, outerQuotes)
case tree => tree

object ElimByName:
val name: String = "elimByName"
val description: String = "map by-name parameters to functions"
3 changes: 3 additions & 0 deletions compiler/src/dotty/tools/dotc/transform/FirstTransform.scala
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,9 @@ class FirstTransform extends MiniPhase with InfoTransformer { thisPhase =>
override def transformOther(tree: Tree)(using Context): Tree = tree match {
case tree: Export => EmptyTree
case tree: NamedArg => transformAllDeep(tree.arg)
case tree @ SplicedExpr(spliced, tpt, outerQuotes) =>
assert(dotty.tools.dotc.inlines.Inlines.inInlineMethod)
cpy.SplicedExpr(tree)(transformAllDeep(spliced), transformAllDeep(tpt), outerQuotes)
case tree => if (tree.isType) toTypeTree(tree) else tree
}

Expand Down
4 changes: 2 additions & 2 deletions compiler/src/dotty/tools/dotc/transform/Inlining.scala
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class Inlining extends MacroTransform {
traverseChildren(tree)(using StagingLevel.quoteContext)
case _: GenericApply if tree.symbol == defn.QuotedTypeModule_of =>
traverseChildren(tree)(using StagingLevel.quoteContext)
case _: GenericApply if tree.symbol.isExprSplice =>
case _: SplicedExpr =>
traverseChildren(tree)(using StagingLevel.spliceContext)
case tree: RefTree if !Inlines.inInlineMethod && StagingLevel.level == 0 =>
assert(!tree.symbol.isInlineMethod, tree.show)
Expand Down Expand Up @@ -104,7 +104,7 @@ class Inlining extends MacroTransform {
super.transform(tree)(using StagingLevel.quoteContext)
case _: GenericApply if tree.symbol == defn.QuotedTypeModule_of =>
super.transform(tree)(using StagingLevel.quoteContext)
case _: GenericApply if tree.symbol.isExprSplice =>
case _: SplicedExpr =>
super.transform(tree)(using StagingLevel.spliceContext)
case _: PackageDef =>
super.transform(tree) match
Expand Down
3 changes: 2 additions & 1 deletion compiler/src/dotty/tools/dotc/transform/PickleQuotes.scala
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,10 @@ class PickleQuotes extends MacroTransform {
tree match
case tree: QuotedExpr =>
assert(Inlines.inInlineMethod)
case tree: SplicedExpr =>
assert(Inlines.inInlineMethod)
case tree: RefTree if !Inlines.inInlineMethod =>
assert(tree.symbol != defn.QuotedTypeModule_of)
assert(!tree.symbol.isExprSplice)
case _ : TypeDef if !Inlines.inInlineMethod =>
assert(!tree.symbol.hasAnnotation(defn.QuotedRuntime_SplicedTypeAnnot),
s"${tree.symbol} should have been removed by PickledQuotes because it has a @quoteTypeTag")
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/transform/Splicer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ object Splicer {
case Apply(Select(QuotedExpr(expr, tpt), nme.apply), _) =>
val noSpliceChecker = new TreeTraverser {
def traverse(tree: Tree)(using Context): Unit = tree match
case SplicedExpr(_) =>
case SplicedExpr(_, _, _) =>
report.error("Quoted argument of macros may not have splices", tree.srcPos)
case _ =>
traverseChildren(tree)
Expand Down
Loading