@@ -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
@@ -1552,7 +1553,39 @@ class Typer extends Namer
15521553 if (sym.isInlineMethod) rhsCtx = rhsCtx.addMode(Mode .InlineableBody )
15531554 val rhs1 = typedExpr(ddef.rhs, tpt1.tpe)(rhsCtx)
15541555
1555- if (sym.isInlineMethod) PrepareInlineable .registerInlineInfo(sym, ddef.rhs, _ => rhs1)
1556+ if (sym.isInlineMethod) {
1557+ if (ctx.phase.isTyper) {
1558+ import PCPCheckAndHeal .InlineSplice
1559+ import TreeMapWithStages ._
1560+ var isMacro = false
1561+ new TreeMapWithStages (freshStagingContext) {
1562+ override protected def transformSplice (splice : tpd.Select )(implicit ctx : Context ): tpd.Tree = {
1563+ isMacro = true
1564+ splice
1565+ }
1566+ }.transform(rhs1)
1567+
1568+ if (isMacro) {
1569+ sym.setFlag(Macro )
1570+ if (TreeMapWithStages .level == 0 )
1571+ rhs1 match {
1572+ case InlineSplice (_) =>
1573+ new PCPCheckAndHeal (freshStagingContext).transform(rhs1) // Ignore output, only check PCP
1574+ case _ =>
1575+ ctx.error(
1576+ """ Malformed macro.
1577+ |
1578+ |Expected the ~ to be at the top of the RHS:
1579+ | inline def foo(inline x: X, ..., y: Y): Int = ~impl(x, ... '(y))
1580+ |
1581+ | * The contents of the splice must call a static method
1582+ | * All arguments must be quoted or inline
1583+ """ .stripMargin, ddef.sourcePos)
1584+ }
1585+ }
1586+ }
1587+ PrepareInlineable .registerInlineInfo(sym, _ => rhs1)
1588+ }
15561589
15571590 if (sym.isConstructor && ! sym.isPrimaryConstructor)
15581591 for (param <- tparams1 ::: vparamss1.flatten)
@@ -1927,6 +1960,16 @@ class Typer extends Namer
19271960 }
19281961 }
19291962
1963+ /** Translate `'(expr)`/`'{ expr* }` into `scala.quoted.Expr.apply(expr)` and `'[T]` into `scala.quoted.Type.apply[T]`
1964+ * while tracking the quotation level in the context.
1965+ */
1966+ def typedQuote (tree : untpd.Quote , pt : Type )(implicit ctx : Context ): Tree = track(" typedQuote" ) {
1967+ if (tree.t.isType)
1968+ typedTypeApply(untpd.TypeApply (untpd.ref(defn.QuotedType_applyR ), List (tree.t)), pt)(TreeMapWithStages .quoteContext).withSpan(tree.span)
1969+ else
1970+ typedApply(untpd.Apply (untpd.ref(defn.QuotedExpr_applyR ), tree.t), pt)(TreeMapWithStages .quoteContext).withSpan(tree.span)
1971+ }
1972+
19301973 /** Retrieve symbol attached to given tree */
19311974 protected def retrieveSym (tree : untpd.Tree )(implicit ctx : Context ): Symbol = tree.removeAttachment(SymOfTree ) match {
19321975 case Some (sym) =>
@@ -2017,6 +2060,7 @@ class Typer extends Namer
20172060 case tree : untpd.InfixOp if ctx.mode.isExpr => typedInfixOp(tree, pt)
20182061 case tree @ untpd.PostfixOp (qual, Ident (nme.WILDCARD )) => typedAsFunction(tree, pt)
20192062 case untpd.EmptyTree => tpd.EmptyTree
2063+ case tree : untpd.Quote => typedQuote(tree, pt)
20202064 case _ => typedUnadapted(desugar(tree), pt, locked)
20212065 }
20222066
0 commit comments