@@ -27,7 +27,7 @@ import EtaExpansion.etaExpand
2727import util .Spans ._
2828import util .common ._
2929import util .Property
30- import Applications .{ExtMethodApply , wrapDefs , productSelectorTypes }
30+ import Applications .{ExtMethodApply , productSelectorTypes , wrapDefs }
3131
3232import collection .mutable
3333import annotation .tailrec
@@ -36,6 +36,7 @@ import util.Stats.{record, track}
3636import config .Printers .{gadts , typr }
3737import rewrites .Rewrites .patch
3838import NavigateAST ._
39+ import dotty .tools .dotc .transform .{PCPCheckAndHeal , Staging , TreeMapWithStages }
3940import transform .SymUtils ._
4041import transform .TypeUtils ._
4142import reporting .trace
@@ -1555,7 +1556,39 @@ class Typer extends Namer
15551556 if (sym.isInlineMethod) rhsCtx = rhsCtx.addMode(Mode .InlineableBody )
15561557 val rhs1 = typedExpr(ddef.rhs, tpt1.tpe)(rhsCtx)
15571558
1558- if (sym.isInlineMethod) PrepareInlineable .registerInlineInfo(sym, ddef.rhs, _ => rhs1)
1559+ if (sym.isInlineMethod) {
1560+ if (ctx.phase.isTyper) {
1561+ import PCPCheckAndHeal .InlineSplice
1562+ import TreeMapWithStages ._
1563+ var isMacro = false
1564+ new TreeMapWithStages (freshStagingContext){
1565+ override protected def splice (splice : tpd.Select )(implicit ctx : Context ): tpd.Tree = {
1566+ isMacro = true
1567+ splice
1568+ }
1569+ }.transform(rhs1)
1570+
1571+ if (isMacro) {
1572+ sym.setFlag(Macro )
1573+ if (TreeMapWithStages .level == 0 )
1574+ rhs1 match {
1575+ case InlineSplice (_) =>
1576+ new PCPCheckAndHeal (freshStagingContext).transform(rhs1) // Ignore output, only check PCP
1577+ case _ =>
1578+ ctx.error(
1579+ """ Malformed macro.
1580+ |
1581+ |Expected the ~ to be at the top of the RHS:
1582+ | inline def foo(inline x: X, ..., y: Y): Int = ~impl(x, ... '(y))
1583+ |
1584+ | * The contents of the splice must call a static method
1585+ | * All arguments must be quoted or inline
1586+ """ .stripMargin, ddef.sourcePos)
1587+ }
1588+ }
1589+ }
1590+ PrepareInlineable .registerInlineInfo(sym, _ => rhs1)
1591+ }
15591592
15601593 if (sym.isConstructor && ! sym.isPrimaryConstructor)
15611594 for (param <- tparams1 ::: vparamss1.flatten)
@@ -1930,6 +1963,16 @@ class Typer extends Namer
19301963 }
19311964 }
19321965
1966+ /** Translate `'(expr)`/`'{ expr* }` into `scala.quoted.Expr.apply(expr)` and `'[T]` into `scala.quoted.Type.apply[T]`
1967+ * while tracking the quotation level in the context.
1968+ */
1969+ def typedQuote (tree : untpd.Quote , pt : Type )(implicit ctx : Context ): Tree = track(" typedQuote" ) {
1970+ if (tree.expr.isType)
1971+ typedTypeApply(untpd.TypeApply (untpd.ref(defn.QuotedType_applyR ), List (tree.expr)), pt)(TreeMapWithStages .quoteContext).withSpan(tree.span)
1972+ else
1973+ typedApply(untpd.Apply (untpd.ref(defn.QuotedExpr_applyR ), tree.expr), pt)(TreeMapWithStages .quoteContext).withSpan(tree.span)
1974+ }
1975+
19331976 /** Retrieve symbol attached to given tree */
19341977 protected def retrieveSym (tree : untpd.Tree )(implicit ctx : Context ): Symbol = tree.removeAttachment(SymOfTree ) match {
19351978 case Some (sym) =>
@@ -2022,6 +2065,7 @@ class Typer extends Namer
20222065 case tree : untpd.InfixOp if ctx.mode.isExpr => typedInfixOp(tree, pt)
20232066 case tree @ untpd.PostfixOp (qual, Ident (nme.WILDCARD )) => typedAsFunction(tree, pt)
20242067 case untpd.EmptyTree => tpd.EmptyTree
2068+ case tree : untpd.Quote => typedQuote(tree, pt)
20252069 case _ => typedUnadapted(desugar(tree), pt, locked)
20262070 }
20272071
0 commit comments