@@ -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
@@ -1552,7 +1553,39 @@ class Typer extends Namer
1552
1553
if (sym.isInlineMethod) rhsCtx = rhsCtx.addMode(Mode .InlineableBody )
1553
1554
val rhs1 = typedExpr(ddef.rhs, tpt1.tpe)(rhsCtx)
1554
1555
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
+ }
1556
1589
1557
1590
if (sym.isConstructor && ! sym.isPrimaryConstructor)
1558
1591
for (param <- tparams1 ::: vparamss1.flatten)
@@ -1927,6 +1960,16 @@ class Typer extends Namer
1927
1960
}
1928
1961
}
1929
1962
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
+
1930
1973
/** Retrieve symbol attached to given tree */
1931
1974
protected def retrieveSym (tree : untpd.Tree )(implicit ctx : Context ): Symbol = tree.removeAttachment(SymOfTree ) match {
1932
1975
case Some (sym) =>
@@ -2017,6 +2060,7 @@ class Typer extends Namer
2017
2060
case tree : untpd.InfixOp if ctx.mode.isExpr => typedInfixOp(tree, pt)
2018
2061
case tree @ untpd.PostfixOp (qual, Ident (nme.WILDCARD )) => typedAsFunction(tree, pt)
2019
2062
case untpd.EmptyTree => tpd.EmptyTree
2063
+ case tree : untpd.Quote => typedQuote(tree, pt)
2020
2064
case _ => typedUnadapted(desugar(tree), pt, locked)
2021
2065
}
2022
2066
0 commit comments