Skip to content

Commit f77ddf1

Browse files
committed
Fix scala#5503: Keep outermost inlined call
1 parent c444f1a commit f77ddf1

19 files changed

+140
-10
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: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1201,6 +1201,9 @@ object Trees {
12011201
*/
12021202
protected def inlineContext(call: Tree)(implicit ctx: Context): Context = ctx
12031203

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

12061209
def transform(tree: Tree)(implicit ctx: Context): Tree = {
@@ -1254,7 +1257,7 @@ object Trees {
12541257
case SeqLiteral(elems, elemtpt) =>
12551258
cpy.SeqLiteral(tree)(transform(elems), transform(elemtpt))
12561259
case Inlined(call, bindings, expansion) =>
1257-
cpy.Inlined(tree)(call, transformSub(bindings), transform(expansion)(inlineContext(call)))
1260+
cpy.Inlined(tree)(call, transformSub(bindings)(inlinedTreeContext), transform(expansion)(inlineContext(call)))
12581261
case TypeTree() =>
12591262
tree
12601263
case SingletonTypeTree(ref) =>
@@ -1321,7 +1324,7 @@ object Trees {
13211324
transform(trees).asInstanceOf[List[Tr]]
13221325

13231326
protected def transformMoreCases(tree: Tree)(implicit ctx: Context): Tree = {
1324-
assert(ctx.reporter.errorsReported)
1327+
assert(ctx.reporter.errorsReported, tree)
13251328
tree
13261329
}
13271330
}
@@ -1380,7 +1383,7 @@ object Trees {
13801383
case SeqLiteral(elems, elemtpt) =>
13811384
this(this(x, elems), elemtpt)
13821385
case Inlined(call, bindings, expansion) =>
1383-
this(this(x, bindings), expansion)(inlineContext(call))
1386+
this(this(x, bindings)(inlinedTreeContext), expansion)(inlineContext(call))
13841387
case TypeTree() =>
13851388
x
13861389
case SingletonTypeTree(ref) =>

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

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

1113+
/** A key to be used in a context property that tracks if the current tree is inside an Inlined tree */
1114+
private val IsInInlinedTree = new Property.Key[Boolean]
1115+
11131116
/** Record an enclosing inlined call.
11141117
* EmptyTree calls (for parameters) cancel the next-enclosing call in the list instead of being added to it.
11151118
* We assume parameters are never nested inside parameters.
@@ -1123,14 +1126,24 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
11231126
ts2
11241127
case _ => call :: oldIC
11251128
}
1126-
ctx.fresh.setProperty(InlinedCalls, newIC)
1129+
ctx.fresh.setProperty(InlinedCalls, newIC).setProperty(IsInInlinedTree, true)
1130+
}
1131+
1132+
/** Return a contexts marked as inside an Inlined tree */
1133+
override def inlinedTreeContext(implicit ctx: Context): Context = {
1134+
if (isInInlinedTree) ctx
1135+
else ctx.fresh.setProperty(IsInInlinedTree, true)
11271136
}
11281137

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

1143+
/** Returns true iff this the current contexts is inside of an Inliend tree */
1144+
def isInInlinedTree(implicit ctx: Context): Boolean =
1145+
ctx.property(IsInInlinedTree).getOrElse(false)
1146+
11341147
/** The source file where the symbol of the `inline` method referred to by `call`
11351148
* is defined
11361149
*/

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
@@ -239,8 +239,10 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase
239239
super.transform(tree1)
240240
}
241241
case Inlined(call, bindings, expansion) if !call.isEmpty =>
242-
val callTrace = Inliner.inlineCallTrace(call.symbol, call.pos)
243-
cpy.Inlined(tree)(callTrace, transformSub(bindings), transform(expansion)(inlineContext(call)))
242+
val callTrace =
243+
if (!isInInlinedTree) Inliner.outlineCallTrace(call)
244+
else Inliner.inlineCallTrace(call.symbol, call.pos)
245+
cpy.Inlined(tree)(callTrace, transformSub(bindings)(inlinedTreeContext), transform(expansion)(inlineContext(call)))
244246
case tree: Template =>
245247
withNoCheckNews(tree.parents.flatMap(newPart)) {
246248
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
@@ -620,6 +620,9 @@ class Staging extends MacroTransformWithImplicits {
620620
""".stripMargin, tree.rhs.pos)
621621
EmptyTree
622622
}
623+
case tree @ Inlined(call, bindings, expansion) if !call.isEmpty && inQuote =>
624+
// Remove inline call (and keep trace) of quoted trees that will be pickled
625+
super.transform(cpy.Inlined(tree)(Inliner.inlineCallTrace(call.symbol, call.pos), bindings, expansion))
623626
case _ =>
624627
markDef(tree)
625628
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
@@ -158,6 +158,22 @@ object Inliner {
158158
*/
159159
def inlineCallTrace(callSym: Symbol, pos: Position)(implicit ctx: Context): Tree =
160160
Ident(callSym.topLevelClass.typeRef).withPos(pos)
161+
162+
/** Reonstruct the original (non-inlined) call.
163+
* Assumes that `inlineCallTrace` has not been used on any nested `Inlined`.
164+
*/
165+
def outlineCallTrace(call: Tree)(implicit ctx: Context): Tree = {
166+
val outline = new TreeTypeMap(
167+
oldOwners = ctx.owner :: Nil, newOwners = ctx.owner :: Nil, // To clone the definitions
168+
treeMap = {
169+
case tree @ Inlined(call, _, _) =>
170+
if (tree.tpe <:< call.tpe) call
171+
else call.asInstance(tree.tpe) // add casts explicitly for inlined methods that refined their return type
172+
case tree => tree
173+
}
174+
)
175+
outline.transform(call)
176+
}
161177
}
162178

163179
/** 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
@@ -20,3 +20,8 @@ default-super.scala
2020
i3050.scala
2121
i4006b.scala
2222
i4006c.scala
23+
24+
# Inlined import generates wrong tasty or unreadable tasty.
25+
# It only seams to happen if the inlined methods redefined in the DottyPredef
26+
inline-import.scala
27+
t8301b.scala

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,9 @@ 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

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,5 @@ implicitMatch.scala
99
typeclass-derivation1.scala
1010
typeclass-derivation2.scala
1111

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

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,6 @@ t7374
66
tuples1.scala
77
tuples1a.scala
88
typeclass-derivation2.scala
9+
10+
# assertion failed: owner discrepancy for value a, expected: class <refinement>
11+
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)), 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)), 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)), 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)), 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)), 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)), 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)