@@ -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
@@ -1548,7 +1549,39 @@ class Typer extends Namer
15481549 if (sym.isInlineMethod) rhsCtx = rhsCtx.addMode(Mode .InlineableBody )
15491550 val rhs1 = typedExpr(ddef.rhs, tpt1.tpe)(rhsCtx)
15501551
1551- if (sym.isInlineMethod) PrepareInlineable .registerInlineInfo(sym, ddef.rhs, _ => rhs1)
1552+ if (sym.isInlineMethod) {
1553+ if (ctx.phase.isTyper) {
1554+ import PCPCheckAndHeal .InlineSplice
1555+ import TreeMapWithStages ._
1556+ var isMacro = false
1557+ new TreeMapWithStages (freshStagingContext){
1558+ override protected def splice (splice : tpd.Select )(implicit ctx : Context ): tpd.Tree = {
1559+ isMacro = true
1560+ splice
1561+ }
1562+ }.transform(rhs1)
1563+
1564+ if (isMacro) {
1565+ sym.setFlag(Macro )
1566+ if (TreeMapWithStages .level == 0 )
1567+ rhs1 match {
1568+ case InlineSplice (_) =>
1569+ new PCPCheckAndHeal (freshStagingContext).transform(rhs1) // Ignore output, only check PCP
1570+ case _ =>
1571+ ctx.error(
1572+ """ Malformed macro.
1573+ |
1574+ |Expected the ~ to be at the top of the RHS:
1575+ | inline def foo(inline x: X, ..., y: Y): Int = ~impl(x, ... '(y))
1576+ |
1577+ | * The contents of the splice must call a static method
1578+ | * All arguments must be quoted or inline
1579+ """ .stripMargin, ddef.sourcePos)
1580+ }
1581+ }
1582+ }
1583+ PrepareInlineable .registerInlineInfo(sym, _ => rhs1)
1584+ }
15521585
15531586 if (sym.isConstructor && ! sym.isPrimaryConstructor)
15541587 for (param <- tparams1 ::: vparamss1.flatten)
@@ -1923,6 +1956,16 @@ class Typer extends Namer
19231956 }
19241957 }
19251958
1959+ /** Translate `'(expr)`/`'{ expr* }` into `scala.quoted.Expr.apply(expr)` and `'[T]` into `scala.quoted.Type.apply[T]`
1960+ * while tracking the quotation level in the context.
1961+ */
1962+ def typedQuote (tree : untpd.Quote , pt : Type )(implicit ctx : Context ): Tree = track(" typedQuote" ) {
1963+ if (tree.expr.isType)
1964+ typedTypeApply(untpd.TypeApply (untpd.ref(defn.QuotedType_applyR ), List (tree.expr)), pt)(TreeMapWithStages .quoteContext).withSpan(tree.span)
1965+ else
1966+ typedApply(untpd.Apply (untpd.ref(defn.QuotedExpr_applyR ), tree.expr), pt)(TreeMapWithStages .quoteContext).withSpan(tree.span)
1967+ }
1968+
19261969 /** Retrieve symbol attached to given tree */
19271970 protected def retrieveSym (tree : untpd.Tree )(implicit ctx : Context ): Symbol = tree.removeAttachment(SymOfTree ) match {
19281971 case Some (sym) =>
@@ -2015,6 +2058,7 @@ class Typer extends Namer
20152058 case tree : untpd.InfixOp if ctx.mode.isExpr => typedInfixOp(tree, pt)
20162059 case tree @ untpd.PostfixOp (qual, Ident (nme.WILDCARD )) => typedAsFunction(tree, pt)
20172060 case untpd.EmptyTree => tpd.EmptyTree
2061+ case tree : untpd.Quote => typedQuote(tree, pt)
20182062 case _ => typedUnadapted(desugar(tree), pt, locked)
20192063 }
20202064
0 commit comments