Skip to content

Commit 5981b8e

Browse files
committed
Remove <special-ops> methods for creating quotes
Instead we desugar 'foo to scala.quoted.Expr.apply(foo) and 'T to scala.quoted.Expr.apply[T]. This avoids storing references to the compiler-specific <special-ops> magic package in TASTY trees. This also gets rid of typedQuote by doing the desugaring early in desugar#apply instead.
1 parent 8feb596 commit 5981b8e

File tree

10 files changed

+27
-40
lines changed

10 files changed

+27
-40
lines changed

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1093,6 +1093,11 @@ object desugar {
10931093
val desugared = tree match {
10941094
case SymbolLit(str) =>
10951095
Literal(Constant(scala.Symbol(str)))
1096+
case Quote(expr) =>
1097+
if (expr.isType)
1098+
TypeApply(ref(defn.QuotedType_applyR), List(expr))
1099+
else
1100+
Apply(ref(defn.QuotedExpr_applyR), expr)
10961101
case InterpolatedString(id, segments) =>
10971102
val strs = segments map {
10981103
case ts: Thicket => ts.trees.head

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -908,7 +908,6 @@ object Trees {
908908
* so that they selectively retype themselves. Retyping needs a context.
909909
*/
910910
abstract class TreeCopier {
911-
912911
def postProcess(tree: Tree, copied: untpd.Tree): copied.ThisTree[T]
913912
def postProcess(tree: Tree, copied: untpd.MemberDef): copied.ThisTree[T]
914913

compiler/src/dotty/tools/dotc/core/Definitions.scala

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -324,16 +324,6 @@ class Definitions {
324324
lazy val throwMethod = enterMethod(OpsPackageClass, nme.THROWkw,
325325
MethodType(List(ThrowableType), NothingType))
326326

327-
/** Method representing a term quote */
328-
lazy val quoteMethod = enterPolyMethod(OpsPackageClass, nme.QUOTE, 1,
329-
pt => MethodType(pt.paramRefs(0) :: Nil, QuotedExprType.appliedTo(pt.paramRefs(0) :: Nil)),
330-
useCompleter = true)
331-
332-
/** Method representing a type quote */
333-
lazy val typeQuoteMethod = enterPolyMethod(OpsPackageClass, nme.TYPE_QUOTE, 1,
334-
pt => QuotedTypeType.appliedTo(pt.paramRefs(0) :: Nil),
335-
useCompleter = true)
336-
337327
lazy val NothingClass: ClassSymbol = enterCompleteClassSymbol(
338328
ScalaPackageClass, tpnme.Nothing, AbstractFinal, List(AnyClass.typeRef))
339329
def NothingType = NothingClass.typeRef
@@ -630,6 +620,11 @@ class Definitions {
630620
lazy val QuotedExprType = ctx.requiredClassRef("scala.quoted.Expr")
631621
def QuotedExprClass(implicit ctx: Context) = QuotedExprType.symbol.asClass
632622

623+
lazy val QuotedExprModuleType = ctx.requiredModuleRef("scala.quoted.Expr")
624+
def QuotedExprModule(implicit ctx: Context) = QuotedExprModuleType.symbol
625+
lazy val QuotedExpr_applyR = QuotedExprModule.requiredMethodRef(nme.apply)
626+
def QuotedExpr_apply(implicit ctx: Context) = QuotedExpr_applyR.symbol
627+
633628
lazy val QuotedExpr_spliceR = QuotedExprClass.requiredMethod(nme.UNARY_~)
634629
def QuotedExpr_~(implicit ctx: Context) = QuotedExpr_spliceR.symbol
635630
lazy val QuotedExpr_runR = QuotedExprClass.requiredMethodRef(nme.run)
@@ -644,7 +639,8 @@ class Definitions {
644639
lazy val QuotedType_spliceR = QuotedTypeClass.requiredType(tpnme.UNARY_~).typeRef
645640
def QuotedType_~ = QuotedType_spliceR.symbol
646641

647-
lazy val QuotedTypeModule = QuotedTypeClass.companionModule
642+
lazy val QuotedTypeModuleType = ctx.requiredModuleRef("scala.quoted.Type")
643+
def QuotedTypeModule(implicit ctx: Context) = QuotedTypeModuleType.symbol
648644
lazy val QuotedType_applyR = QuotedTypeModule.requiredMethodRef(nme.apply)
649645
def QuotedType_apply(implicit ctx: Context) = QuotedType_applyR.symbol
650646

@@ -1183,7 +1179,7 @@ class Definitions {
11831179

11841180
/** Lists core methods that don't have underlying bytecode, but are synthesized on-the-fly in every reflection universe */
11851181
lazy val syntheticCoreMethods =
1186-
AnyMethods ++ ObjectMethods ++ List(String_+, throwMethod, quoteMethod, typeQuoteMethod)
1182+
AnyMethods ++ ObjectMethods ++ List(String_+, throwMethod)
11871183

11881184
lazy val reservedScalaClassNames: Set[Name] = syntheticScalaClasses.map(_.name).toSet
11891185

compiler/src/dotty/tools/dotc/printing/DecompilerPrinter.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,8 @@ class DecompilerPrinter(_ctx: Context) extends RefinedPrinter(_ctx) {
6060
}
6161

6262
override protected def typeApplyText[T >: Untyped](tree: TypeApply[T]): Text = {
63-
if (tree.symbol eq defn.quoteMethod) "'"
64-
else if (tree.symbol eq defn.typeQuoteMethod) "'[" ~ toTextGlobal(tree.args, ", ") ~ "]"
63+
if (tree.symbol eq defn.QuotedExpr_apply) "'"
64+
else if (tree.symbol eq defn.QuotedType_apply) "'[" ~ toTextGlobal(tree.args, ", ") ~ "]"
6565
else super.typeApplyText(tree)
6666
}
6767
}

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,7 @@ class ReifyQuotes extends MacroTransformWithImplicits with InfoTransformer {
360360
* core and splices as arguments.
361361
*/
362362
private def quotation(body: Tree, quote: Tree)(implicit ctx: Context): Tree = {
363-
val isType = quote.symbol eq defn.typeQuoteMethod
363+
val isType = quote.symbol eq defn.QuotedType_apply
364364
if (body.symbol.isSplice) {
365365
// simplify `'(~x)` to `x` and then transform it
366366
val Select(splice, _) = body
@@ -369,8 +369,8 @@ class ReifyQuotes extends MacroTransformWithImplicits with InfoTransformer {
369369
else if (level > 0) {
370370
val body1 = nested(isQuote = true).transform(body)
371371
// Keep quotes as trees to reduce pickled size and have a Expr.show without pickled quotes
372-
if (isType) ref(defn.typeQuoteMethod).appliedToType(body1.tpe.widen)
373-
else ref(defn.quoteMethod).appliedToType(body1.tpe.widen).appliedTo(body1)
372+
if (isType) ref(defn.QuotedType_apply).appliedToType(body1.tpe.widen)
373+
else ref(defn.QuotedExpr_apply).appliedToType(body1.tpe.widen).appliedTo(body1)
374374
}
375375
else body match {
376376
case body: RefTree if isCaptured(body, level + 1) =>

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ class SymUtils(val self: Symbol) extends AnyVal {
175175

176176
/** Is symbol a quote operation? */
177177
def isQuote(implicit ctx: Context): Boolean =
178-
self == defn.quoteMethod || self == defn.typeQuoteMethod
178+
self == defn.QuotedExpr_apply || self == defn.QuotedType_apply
179179

180180
/** Is symbol a splice operation? */
181181
def isSplice(implicit ctx: Context): Boolean =

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -587,7 +587,7 @@ trait Implicits { self: Typer =>
587587
}
588588
}
589589
val tag = bindFreeVars(arg)
590-
if (bindFreeVars.ok) ref(defn.typeQuoteMethod).appliedToType(tag)
590+
if (bindFreeVars.ok) ref(defn.QuotedType_apply).appliedToType(tag)
591591
else EmptyTree
592592
case _ =>
593593
EmptyTree

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

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1106,25 +1106,6 @@ class Typer extends Namer
11061106
Throw(expr1).withPos(tree.pos)
11071107
}
11081108

1109-
def typedQuote(tree: untpd.Quote, pt: Type)(implicit ctx: Context): Tree = track("typedQuote") {
1110-
val untpd.Quote(body) = tree
1111-
val isType = body.isType
1112-
val resultClass = if (isType) defn.QuotedTypeClass else defn.QuotedExprClass
1113-
val proto1 = pt.baseType(resultClass) match {
1114-
case AppliedType(_, argType :: Nil) => argType
1115-
case _ => WildcardType
1116-
}
1117-
val nestedCtx = ctx.fresh.setTree(tree)
1118-
if (isType) {
1119-
val body1 = typedType(body, proto1)(nestedCtx)
1120-
ref(defn.typeQuoteMethod).appliedToTypeTrees(body1 :: Nil)
1121-
}
1122-
else {
1123-
val body1 = typed(body, proto1)(nestedCtx)
1124-
ref(defn.quoteMethod).appliedToType(body1.tpe.widen).appliedTo(body1)
1125-
}
1126-
}
1127-
11281109
def typedSeqLiteral(tree: untpd.SeqLiteral, pt: Type)(implicit ctx: Context): SeqLiteral = track("typedSeqLiteral") {
11291110
val proto1 = pt.elemType match {
11301111
case NoType => WildcardType
@@ -1794,7 +1775,6 @@ class Typer extends Namer
17941775
case tree: untpd.Super => typedSuper(tree, pt)
17951776
case tree: untpd.SeqLiteral => typedSeqLiteral(tree, pt)
17961777
case tree: untpd.Inlined => typedInlined(tree, pt)
1797-
case tree: untpd.Quote => typedQuote(tree, pt)
17981778
case tree: untpd.TypeTree => typedTypeTree(tree, pt)
17991779
case tree: untpd.SingletonTypeTree => typedSingletonTypeTree(tree)
18001780
case tree: untpd.AndTypeTree => typedAndTypeTree(tree)

library/src/scala/quoted/Expr.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ sealed abstract class Expr[T] {
1010
}
1111

1212
object Expr {
13+
/** A term quote is desugared by the compiler into a call to this method */
14+
def apply[T](x: T): Expr[T] =
15+
throw new Error("Internal error: this method call should have been replaced by the compiler")
1316

1417
implicit class AsFunction[T, U](private val f: Expr[T => U]) extends AnyVal {
1518
def apply(x: Expr[T]): Expr[U] = new Exprs.FunctionAppliedTo[T, U](f, x)

library/src/scala/quoted/Type.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ sealed abstract class Type[T] {
1010

1111
/** Some basic type tags, currently incomplete */
1212
object Type {
13+
/** A term quote is desugared by the compiler into a call to this method */
14+
def apply[T]: Type[T] =
15+
throw new Error("Internal error: this method call should have been replaced by the compiler")
16+
1317
implicit def UnitTag: Type[Unit] = new TaggedType[Unit]
1418
implicit def BooleanTag: Type[Boolean] = new TaggedType[Boolean]
1519
implicit def ByteTag: Type[Byte] = new TaggedType[Byte]

0 commit comments

Comments
 (0)