Skip to content

Commit 3fddedd

Browse files
committed
Fix scala#5503: Keep outermost inlined call
1 parent 4c5ca04 commit 3fddedd

19 files changed

+139
-8
lines changed

compiler/src/dotty/tools/dotc/ast/TreeTypeMap.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,8 @@ class TreeTypeMap(
107107
val expr1 = tmap1.transform(expr)
108108
cpy.Block(blk)(stats1, expr1)
109109
case inlined @ Inlined(call, bindings, expanded) =>
110-
val (tmap1, bindings1) = transformDefs(bindings)
111-
val expanded1 = tmap1.transform(expanded)
110+
val (tmap1, bindings1) = transformDefs(bindings)(inlinedTreeContext)
111+
val expanded1 = tmap1.transform(expanded)(inlineContext(call))
112112
cpy.Inlined(inlined)(call, bindings1, expanded1)
113113
case cdef @ CaseDef(pat, guard, rhs) =>
114114
val tmap = withMappedSyms(patVars(pat))

compiler/src/dotty/tools/dotc/ast/Trees.scala

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1203,6 +1203,9 @@ object Trees {
12031203
*/
12041204
protected def inlineContext(call: Tree)(implicit ctx: Context): Context = ctx
12051205

1206+
/** Return a contexts marked as inside an Inlined tree */
1207+
protected def inlinedTreeContext(implicit ctx: Context): Context = ctx
1208+
12061209
abstract class TreeMap(val cpy: TreeCopier = inst.cpy) { self =>
12071210

12081211
def transform(tree: Tree)(implicit ctx: Context): Tree =
@@ -1325,7 +1328,7 @@ object Trees {
13251328
transform(trees).asInstanceOf[List[Tr]]
13261329

13271330
protected def transformMoreCases(tree: Tree)(implicit ctx: Context): Tree = {
1328-
assert(ctx.reporter.errorsReported)
1331+
assert(ctx.reporter.errorsReported, tree)
13291332
tree
13301333
}
13311334
}

compiler/src/dotty/tools/dotc/ast/tpd.scala

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1113,6 +1113,9 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
11131113
/** A key to be used in a context property that tracks enclosing inlined calls */
11141114
private val InlinedCalls = new Property.Key[List[Tree]]
11151115

1116+
/** A key to be used in a context property that tracks if the current tree is inside an Inlined tree */
1117+
private val IsInInlinedTree = new Property.Key[Boolean]
1118+
11161119
/** Record an enclosing inlined call.
11171120
* EmptyTree calls (for parameters) cancel the next-enclosing call in the list instead of being added to it.
11181121
* We assume parameters are never nested inside parameters.
@@ -1126,14 +1129,24 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
11261129
ts2
11271130
case _ => call :: oldIC
11281131
}
1129-
ctx.fresh.setProperty(InlinedCalls, newIC)
1132+
ctx.fresh.setProperty(InlinedCalls, newIC).setProperty(IsInInlinedTree, true)
1133+
}
1134+
1135+
/** Return a contexts marked as inside an Inlined tree */
1136+
override def inlinedTreeContext(implicit ctx: Context): Context = {
1137+
if (isInInlinedTree) ctx
1138+
else ctx.fresh.setProperty(IsInInlinedTree, true)
11301139
}
11311140

11321141
/** All enclosing calls that are currently inlined, from innermost to outermost.
11331142
*/
11341143
def enclosingInlineds(implicit ctx: Context): List[Tree] =
11351144
ctx.property(InlinedCalls).getOrElse(Nil)
11361145

1146+
/** Returns true iff this the current contexts is inside of an Inliend tree */
1147+
def isInInlinedTree(implicit ctx: Context): Boolean =
1148+
ctx.property(IsInInlinedTree).getOrElse(false)
1149+
11371150
/** The source file where the symbol of the `inline` method referred to by `call`
11381151
* is defined
11391152
*/

compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import dotty.tools.dotc.core.Types.Type
1414
import dotty.tools.dotc.core.tasty.TreePickler.Hole
1515
import dotty.tools.dotc.core.tasty.{PositionPickler, TastyPickler, TastyPrinter, TastyString}
1616
import dotty.tools.dotc.core.tasty.TreeUnpickler.UnpickleMode
17+
import dotty.tools.dotc.typer.Inliner
1718

1819
import scala.quoted.Types._
1920
import scala.quoted.Exprs._

compiler/src/dotty/tools/dotc/transform/PostTyper.scala

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -244,8 +244,10 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase
244244
super.transform(tree1)
245245
}
246246
case Inlined(call, bindings, expansion) if !call.isEmpty =>
247-
val callTrace = Inliner.inlineCallTrace(call.symbol, call.sourcePos)
248-
cpy.Inlined(tree)(callTrace, transformSub(bindings), transform(expansion)(inlineContext(call)))
247+
val callTrace =
248+
if (!isInInlinedTree) Inliner.outlineCallTrace(call)
249+
else Inliner.inlineCallTrace(call.symbol, call.sourcePos)
250+
cpy.Inlined(tree)(callTrace, transformSub(bindings)(inlinedTreeContext), transform(expansion)(inlineContext(call)))
249251
case tree: Template =>
250252
withNoCheckNews(tree.parents.flatMap(newPart)) {
251253
val templ1 = paramFwd.forwardParamAccessors(tree)

compiler/src/dotty/tools/dotc/transform/Staging.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -622,6 +622,9 @@ class Staging extends MacroTransformWithImplicits {
622622
""".stripMargin, tree.rhs.sourcePos)
623623
EmptyTree
624624
}
625+
case tree @ Inlined(call, bindings, expansion) if !call.isEmpty && inQuote =>
626+
// Remove inline call (and keep trace) of quoted trees that will be pickled
627+
super.transform(cpy.Inlined(tree)(Inliner.inlineCallTrace(call.symbol, call.sourcePos), bindings, expansion))
625628
case _ =>
626629
markDef(tree)
627630
checkLevel(mapOverTree(enteredSyms))

compiler/src/dotty/tools/dotc/typer/Inliner.scala

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,22 @@ object Inliner {
161161
implicit val src = pos.source
162162
Ident(callSym.topLevelClass.typeRef).withSpan(pos.span)
163163
}
164+
165+
/** Reconstruct the original (non-inlined) call.
166+
* Assumes that `inlineCallTrace` has not been used on any nested `Inlined`.
167+
*/
168+
def outlineCallTrace(call: Tree)(implicit ctx: Context): Tree = {
169+
val outline = new TreeTypeMap(
170+
oldOwners = ctx.owner :: Nil, newOwners = ctx.owner :: Nil, // To clone the definitions
171+
treeMap = {
172+
case tree @ Inlined(call, _, _) =>
173+
if (tree.tpe <:< call.tpe) call
174+
else call.asInstance(tree.tpe) // add casts explicitly for inlined methods that refined their return type
175+
case tree => tree
176+
}
177+
)
178+
outline.transform(call)
179+
}
164180
}
165181

166182
/** Produces an inlined version of `call` via its `inlined` method.

compiler/test/dotc/pos-from-tasty.blacklist

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,8 @@ i4006c.scala
2525
implicit-match.scala
2626
implicit-match-nested.scala
2727
implicit-match-and-inline-match.scala
28+
29+
# Inlined import generates wrong tasty or unreadable tasty.
30+
# It only seams to happen if the inlined methods redefined in the DottyPredef
31+
inline-import.scala
32+
t8301b.scala

compiler/test/dotc/pos-test-pickling.blacklist

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,10 @@ t3249
1010
t3486
1111
t3612.scala
1212
typelevel0.scala
13+
14+
# Inlined import generates wrong tasty or unreadable tasty.
15+
# It only seams to happen if the inlined methods redefined in the DottyPredef
16+
inline-import.scala
17+
t8301b.scala
18+
typedIdents
19+
i3955.scala

compiler/test/dotc/run-from-tasty.blacklist

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,5 @@ typeclass-derivation3.scala
1313
derive-generic.scala
1414
deriving-interesting-prefixes.scala
1515

16+
# assertion failed: owner discrepancy for value a, expected: class <refinement>, found: class <refinement>
17+
i4496a.scala

compiler/test/dotc/run-test-pickling.blacklist

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,6 @@ typeclass-derivation2a.scala
1010
typeclass-derivation3.scala
1111
derive-generic.scala
1212
deriving-interesting-prefixes.scala
13+
14+
# assertion failed: owner discrepancy for value a, expected: class <refinement>
15+
i4496a.scala

tests/pos/inline-import-b.scala

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
2+
object Test {
3+
4+
@inline def locally[T](x: T): T = x
5+
6+
locally {
7+
import Test._
8+
val bool: Boolean = true
9+
}
10+
11+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
2+
object Predef2 {
3+
4+
@inline def locally[T](x: T): T = x
5+
6+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
2+
object Test {
3+
4+
Predef2.locally {
5+
import Test._
6+
val bool: Boolean = true
7+
}
8+
9+
}

tests/pos/inline-import.scala

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
2+
object Test {
3+
4+
locally {
5+
import Test._
6+
val bool: Boolean = true
7+
}
8+
9+
}

tests/run-custom-args/Yretain-trees/tasty-extractors-owners.check

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
foo
2-
DefDef("main", Nil, List(List(ValDef("args", TypeTree.Applied(TypeTree.Ident("Array"), List(TypeTree.Ident("String"))), None))), TypeTree.Ident("Unit"), Some(Term.Block(Nil, Term.Inlined(Some(TypeTree.Ident("Macros$")), Nil, Term.Typed(Term.Select(Term.Apply(Term.Apply(Term.TypeApply(Term.Ident("impl"), List(TypeTree.Inferred())), List(Term.Apply(Term.TypeApply(Term.Ident("apply"), List(TypeTree.Inferred())), List(Term.Inlined(None, Nil, Term.Block(List(DefDef("foo", Nil, Nil, TypeTree.Inferred(), Some(Term.Block(List(DefDef("bar", Nil, Nil, TypeTree.Inferred(), Some(Term.Literal(Constant.Int(1)))), ValDef("bar2", TypeTree.Inferred(), Some(Term.Literal(Constant.Int(2))))), Term.Typed(Term.Ident("bar"), TypeTree.Inferred())))), ValDef("foo2", TypeTree.Inferred(), Some(Term.Block(List(DefDef("baz", Nil, Nil, TypeTree.Inferred(), Some(Term.Literal(Constant.Int(3)))), ValDef("baz2", TypeTree.Inferred(), Some(Term.Literal(Constant.Int(4))))), Term.Typed(Term.Ident("baz"), TypeTree.Inferred())))), ClassDef("A", DefDef("<init>", Nil, List(Nil), TypeTree.Inferred(), None), List(Term.Apply(Term.Select(Term.New(TypeTree.Inferred()), "<init>"), Nil)), Nil, None, List(TypeDef("B", TypeTree.Ident("Int")), DefDef("b", Nil, Nil, TypeTree.Inferred(), Some(Term.Literal(Constant.Int(5)))), ValDef("b2", TypeTree.Inferred(), Some(Term.Literal(Constant.Int(6))))))), Term.Literal(Constant.Unit()))))))), List(Term.Ident("macroContext"))), "unary_~"), TypeTree.Ident("Unit"))))))
2+
DefDef("main", Nil, List(List(ValDef("args", TypeTree.Applied(TypeTree.Ident("Array"), List(TypeTree.Ident("String"))), None))), TypeTree.Ident("Unit"), Some(Term.Block(Nil, Term.Inlined(Some(Term.Apply(Term.TypeApply(Term.Ident("printOwners"), List(TypeTree.Inferred())), List(Term.Block(List(DefDef("foo", Nil, Nil, TypeTree.Inferred(), Some(Term.Block(List(DefDef("bar", Nil, Nil, TypeTree.Inferred(), Some(Term.Literal(Constant.Int(1)))), ValDef("bar2", TypeTree.Inferred(), Some(Term.Literal(Constant.Int(2))))), Term.Typed(Term.Ident("bar"), TypeTree.Inferred())))), ValDef("foo2", TypeTree.Inferred(), Some(Term.Block(List(DefDef("baz", Nil, Nil, TypeTree.Inferred(), Some(Term.Literal(Constant.Int(3)))), ValDef("baz2", TypeTree.Inferred(), Some(Term.Literal(Constant.Int(4))))), Term.Typed(Term.Ident("baz"), TypeTree.Inferred())))), ClassDef("A", DefDef("<init>", Nil, List(Nil), TypeTree.Inferred(), None), List(Term.Apply(Term.Select(Term.New(TypeTree.Inferred()), "<init>"), Nil)), Nil, None, List(TypeDef("B", TypeTree.Ident("Int")), DefDef("b", Nil, Nil, TypeTree.Inferred(), Some(Term.Literal(Constant.Int(5)))), ValDef("b2", TypeTree.Inferred(), Some(Term.Literal(Constant.Int(6))))))), Term.Literal(Constant.Unit()))))), Nil, Term.Typed(Term.Select(Term.Apply(Term.Apply(Term.TypeApply(Term.Ident("impl"), List(TypeTree.Inferred())), List(Term.Apply(Term.TypeApply(Term.Ident("apply"), List(TypeTree.Inferred())), List(Term.Inlined(None, Nil, Term.Block(List(DefDef("foo", Nil, Nil, TypeTree.Inferred(), Some(Term.Block(List(DefDef("bar", Nil, Nil, TypeTree.Inferred(), Some(Term.Literal(Constant.Int(1)))), ValDef("bar2", TypeTree.Inferred(), Some(Term.Literal(Constant.Int(2))))), Term.Typed(Term.Ident("bar"), TypeTree.Inferred())))), ValDef("foo2", TypeTree.Inferred(), Some(Term.Block(List(DefDef("baz", Nil, Nil, TypeTree.Inferred(), Some(Term.Literal(Constant.Int(3)))), ValDef("baz2", TypeTree.Inferred(), Some(Term.Literal(Constant.Int(4))))), Term.Typed(Term.Ident("baz"), TypeTree.Inferred())))), ClassDef("A", DefDef("<init>", Nil, List(Nil), TypeTree.Inferred(), None), List(Term.Apply(Term.Select(Term.New(TypeTree.Inferred()), "<init>"), Nil)), Nil, None, List(TypeDef("B", TypeTree.Ident("Int")), DefDef("b", Nil, Nil, TypeTree.Inferred(), Some(Term.Literal(Constant.Int(5)))), ValDef("b2", TypeTree.Inferred(), Some(Term.Literal(Constant.Int(6))))))), Term.Literal(Constant.Unit()))))))), List(Term.Ident("macroContext"))), "unary_~"), TypeTree.Ident("Unit"))))))
33

44
bar
55
DefDef("foo", Nil, Nil, TypeTree.Inferred(), Some(Term.Block(List(DefDef("bar", Nil, Nil, TypeTree.Inferred(), Some(Term.Literal(Constant.Int(1)))), ValDef("bar2", TypeTree.Inferred(), Some(Term.Literal(Constant.Int(2))))), Term.Typed(Term.Ident("bar"), TypeTree.Inferred()))))
@@ -8,7 +8,7 @@ bar2
88
DefDef("foo", Nil, Nil, TypeTree.Inferred(), Some(Term.Block(List(DefDef("bar", Nil, Nil, TypeTree.Inferred(), Some(Term.Literal(Constant.Int(1)))), ValDef("bar2", TypeTree.Inferred(), Some(Term.Literal(Constant.Int(2))))), Term.Typed(Term.Ident("bar"), TypeTree.Inferred()))))
99

1010
foo2
11-
DefDef("main", Nil, List(List(ValDef("args", TypeTree.Applied(TypeTree.Ident("Array"), List(TypeTree.Ident("String"))), None))), TypeTree.Ident("Unit"), Some(Term.Block(Nil, Term.Inlined(Some(TypeTree.Ident("Macros$")), Nil, Term.Typed(Term.Select(Term.Apply(Term.Apply(Term.TypeApply(Term.Ident("impl"), List(TypeTree.Inferred())), List(Term.Apply(Term.TypeApply(Term.Ident("apply"), List(TypeTree.Inferred())), List(Term.Inlined(None, Nil, Term.Block(List(DefDef("foo", Nil, Nil, TypeTree.Inferred(), Some(Term.Block(List(DefDef("bar", Nil, Nil, TypeTree.Inferred(), Some(Term.Literal(Constant.Int(1)))), ValDef("bar2", TypeTree.Inferred(), Some(Term.Literal(Constant.Int(2))))), Term.Typed(Term.Ident("bar"), TypeTree.Inferred())))), ValDef("foo2", TypeTree.Inferred(), Some(Term.Block(List(DefDef("baz", Nil, Nil, TypeTree.Inferred(), Some(Term.Literal(Constant.Int(3)))), ValDef("baz2", TypeTree.Inferred(), Some(Term.Literal(Constant.Int(4))))), Term.Typed(Term.Ident("baz"), TypeTree.Inferred())))), ClassDef("A", DefDef("<init>", Nil, List(Nil), TypeTree.Inferred(), None), List(Term.Apply(Term.Select(Term.New(TypeTree.Inferred()), "<init>"), Nil)), Nil, None, List(TypeDef("B", TypeTree.Ident("Int")), DefDef("b", Nil, Nil, TypeTree.Inferred(), Some(Term.Literal(Constant.Int(5)))), ValDef("b2", TypeTree.Inferred(), Some(Term.Literal(Constant.Int(6))))))), Term.Literal(Constant.Unit()))))))), List(Term.Ident("macroContext"))), "unary_~"), TypeTree.Ident("Unit"))))))
11+
DefDef("main", Nil, List(List(ValDef("args", TypeTree.Applied(TypeTree.Ident("Array"), List(TypeTree.Ident("String"))), None))), TypeTree.Ident("Unit"), Some(Term.Block(Nil, Term.Inlined(Some(Term.Apply(Term.TypeApply(Term.Ident("printOwners"), List(TypeTree.Inferred())), List(Term.Block(List(DefDef("foo", Nil, Nil, TypeTree.Inferred(), Some(Term.Block(List(DefDef("bar", Nil, Nil, TypeTree.Inferred(), Some(Term.Literal(Constant.Int(1)))), ValDef("bar2", TypeTree.Inferred(), Some(Term.Literal(Constant.Int(2))))), Term.Typed(Term.Ident("bar"), TypeTree.Inferred())))), ValDef("foo2", TypeTree.Inferred(), Some(Term.Block(List(DefDef("baz", Nil, Nil, TypeTree.Inferred(), Some(Term.Literal(Constant.Int(3)))), ValDef("baz2", TypeTree.Inferred(), Some(Term.Literal(Constant.Int(4))))), Term.Typed(Term.Ident("baz"), TypeTree.Inferred())))), ClassDef("A", DefDef("<init>", Nil, List(Nil), TypeTree.Inferred(), None), List(Term.Apply(Term.Select(Term.New(TypeTree.Inferred()), "<init>"), Nil)), Nil, None, List(TypeDef("B", TypeTree.Ident("Int")), DefDef("b", Nil, Nil, TypeTree.Inferred(), Some(Term.Literal(Constant.Int(5)))), ValDef("b2", TypeTree.Inferred(), Some(Term.Literal(Constant.Int(6))))))), Term.Literal(Constant.Unit()))))), Nil, Term.Typed(Term.Select(Term.Apply(Term.Apply(Term.TypeApply(Term.Ident("impl"), List(TypeTree.Inferred())), List(Term.Apply(Term.TypeApply(Term.Ident("apply"), List(TypeTree.Inferred())), List(Term.Inlined(None, Nil, Term.Block(List(DefDef("foo", Nil, Nil, TypeTree.Inferred(), Some(Term.Block(List(DefDef("bar", Nil, Nil, TypeTree.Inferred(), Some(Term.Literal(Constant.Int(1)))), ValDef("bar2", TypeTree.Inferred(), Some(Term.Literal(Constant.Int(2))))), Term.Typed(Term.Ident("bar"), TypeTree.Inferred())))), ValDef("foo2", TypeTree.Inferred(), Some(Term.Block(List(DefDef("baz", Nil, Nil, TypeTree.Inferred(), Some(Term.Literal(Constant.Int(3)))), ValDef("baz2", TypeTree.Inferred(), Some(Term.Literal(Constant.Int(4))))), Term.Typed(Term.Ident("baz"), TypeTree.Inferred())))), ClassDef("A", DefDef("<init>", Nil, List(Nil), TypeTree.Inferred(), None), List(Term.Apply(Term.Select(Term.New(TypeTree.Inferred()), "<init>"), Nil)), Nil, None, List(TypeDef("B", TypeTree.Ident("Int")), DefDef("b", Nil, Nil, TypeTree.Inferred(), Some(Term.Literal(Constant.Int(5)))), ValDef("b2", TypeTree.Inferred(), Some(Term.Literal(Constant.Int(6))))))), Term.Literal(Constant.Unit()))))))), List(Term.Ident("macroContext"))), "unary_~"), TypeTree.Ident("Unit"))))))
1212

1313
baz
1414
ValDef("foo2", TypeTree.Inferred(), Some(Term.Block(List(DefDef("baz", Nil, Nil, TypeTree.Inferred(), Some(Term.Literal(Constant.Int(3)))), ValDef("baz2", TypeTree.Inferred(), Some(Term.Literal(Constant.Int(4))))), Term.Typed(Term.Ident("baz"), TypeTree.Inferred()))))

tests/run/tasty-outermost-call.check

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
Term.Inlined(None, Nil, Term.Inlined(Some(TypeTree.Ident("Test$")), Nil, Term.Typed(Term.Literal(Constant.Int(54)), TypeTree.Ident("Int"))))
2+
Term.Inlined(None, Nil, Term.Inlined(Some(TypeTree.Ident("Test$")), Nil, Term.Typed(Term.Literal(Constant.Int(8)), TypeTree.Ident("Int"))))
3+
Term.Inlined(None, Nil, Term.Inlined(Some(TypeTree.Ident("Test$")), List(ValDef("i", TypeTree.Inferred(), Some(Term.Inlined(Some(TypeTree.Ident("Test$")), Nil, Term.Typed(Term.Literal(Constant.Int(54)), TypeTree.Ident("Int")))))), Term.Typed(Term.Apply(Term.Select(Term.Ident("i"), "+"), List(Term.Ident("i"))), TypeTree.Ident("Int"))))
4+
Term.Inlined(None, Nil, Term.Inlined(Some(TypeTree.Ident("Test$")), Nil, Term.Typed(Term.Inlined(Some(TypeTree.Ident("Test$")), Nil, Term.Typed(Term.Literal(Constant.Int(10)), TypeTree.Ident("Int"))), TypeTree.Ident("Int"))))
5+
Term.Inlined(None, Nil, Term.Inlined(Some(TypeTree.Ident("Test$")), List(ValDef("i", TypeTree.Inferred(), Some(Term.Inlined(Some(TypeTree.Ident("Test$")), Nil, Term.Typed(Term.Literal(Constant.Int(54)), TypeTree.Ident("Int")))))), Term.Typed(Term.Inlined(Some(TypeTree.Ident("Test$")), Nil, Term.Typed(Term.Apply(Term.Select(Term.Ident("i"), "+"), List(Term.Ident("i"))), TypeTree.Ident("Int"))), TypeTree.Ident("Int"))))
6+
Term.Inlined(None, Nil, Term.Inlined(Some(TypeTree.Ident("Test$")), List(ValDef("i", TypeTree.Inferred(), Some(Term.Inlined(Some(TypeTree.Ident("Test$")), List(ValDef("i", TypeTree.Inferred(), Some(Term.Inlined(Some(TypeTree.Ident("Test$")), Nil, Term.Typed(Term.Literal(Constant.Int(54)), TypeTree.Ident("Int")))))), Term.Typed(Term.Apply(Term.Select(Term.Ident("i"), "+"), List(Term.Ident("i"))), TypeTree.Ident("Int")))))), Term.Typed(Term.Inlined(Some(TypeTree.Ident("Test$")), Nil, Term.Typed(Term.Apply(Term.Select(Term.Ident("i"), "+"), List(Term.Ident("i"))), TypeTree.Ident("Int"))), TypeTree.Ident("Int"))))
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import scala.quoted._
2+
3+
import scala.tasty._
4+
5+
object Macros {
6+
7+
inline def show(x: => Any): String = ~impl('(x))
8+
9+
def impl(x: Expr[Any])(implicit reflect: Reflection): Expr[String] = {
10+
import reflect._
11+
x.unseal.show.toExpr
12+
}
13+
14+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
2+
import Macros._
3+
4+
object Test {
5+
def main(args: Array[String]): Unit = {
6+
println(show(foo0))
7+
println(show(foo1(4)))
8+
println(show(foo1(foo0)))
9+
println(show(foo2(5)))
10+
println(show(foo2(foo0)))
11+
println(show(foo2(foo1(foo0))))
12+
foo1(foo0)
13+
foo2(foo0)
14+
foo2(foo1(foo0))
15+
}
16+
17+
inline def foo0: Int = 54
18+
inline def foo1(i: Int): Int = i + i
19+
inline def foo2(i: Int): Int = foo1(i)
20+
21+
}

0 commit comments

Comments
 (0)