@@ -27,7 +27,7 @@ import EtaExpansion.etaExpand
27
27
import util .Spans ._
28
28
import util .common ._
29
29
import util .Property
30
- import Applications .{ExtMethodApply , wrapDefs , productSelectorTypes }
30
+ import Applications .{ExtMethodApply , productSelectorTypes , wrapDefs }
31
31
32
32
import collection .mutable
33
33
import annotation .tailrec
@@ -36,6 +36,7 @@ import util.Stats.{record, track}
36
36
import config .Printers .{gadts , typr }
37
37
import rewrites .Rewrites .patch
38
38
import NavigateAST ._
39
+ import dotty .tools .dotc .transform .{PCPCheckAndHeal , Staging , TreeMapWithStages }
39
40
import transform .SymUtils ._
40
41
import transform .TypeUtils ._
41
42
import reporting .trace
@@ -1548,7 +1549,39 @@ class Typer extends Namer
1548
1549
if (sym.isInlineMethod) rhsCtx = rhsCtx.addMode(Mode .InlineableBody )
1549
1550
val rhs1 = typedExpr(ddef.rhs, tpt1.tpe)(rhsCtx)
1550
1551
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
+ }
1552
1585
1553
1586
if (sym.isConstructor && ! sym.isPrimaryConstructor)
1554
1587
for (param <- tparams1 ::: vparamss1.flatten)
@@ -1923,6 +1956,16 @@ class Typer extends Namer
1923
1956
}
1924
1957
}
1925
1958
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
+
1926
1969
/** Retrieve symbol attached to given tree */
1927
1970
protected def retrieveSym (tree : untpd.Tree )(implicit ctx : Context ): Symbol = tree.removeAttachment(SymOfTree ) match {
1928
1971
case Some (sym) =>
@@ -2015,6 +2058,7 @@ class Typer extends Namer
2015
2058
case tree : untpd.InfixOp if ctx.mode.isExpr => typedInfixOp(tree, pt)
2016
2059
case tree @ untpd.PostfixOp (qual, Ident (nme.WILDCARD )) => typedAsFunction(tree, pt)
2017
2060
case untpd.EmptyTree => tpd.EmptyTree
2061
+ case tree : untpd.Quote => typedQuote(tree, pt)
2018
2062
case _ => typedUnadapted(desugar(tree), pt, locked)
2019
2063
}
2020
2064
0 commit comments