Skip to content

Commit b7e5e57

Browse files
committed
Separate tree nodes for ByNames
ByName nodes in arguments are not pickled, which means that we can use the same Tasty version as before.
1 parent 3f51f11 commit b7e5e57

24 files changed

+102
-83
lines changed

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -623,6 +623,12 @@ object Trees {
623623
def name: Name = bind.name
624624
}
625625

626+
/** By-name wrapper; created by Typer and TreUnpickler, eliminated in TreePickler and ByNameLambda */
627+
case class ByName[-T >: Untyped] private[ast] (expr: Tree[T])(implicit @constructorOnly src: SourceFile)
628+
extends TermTree[T] {
629+
type ThisTree[-T >: Untyped] = ByName[T]
630+
}
631+
626632
/** return expr
627633
* where `from` refers to the method or label from which the return takes place
628634
* After program transformations this is not necessarily the enclosing method, because
@@ -1075,6 +1081,7 @@ object Trees {
10751081
type InlineMatch = Trees.InlineMatch[T]
10761082
type CaseDef = Trees.CaseDef[T]
10771083
type Labeled = Trees.Labeled[T]
1084+
type ByName = Trees.ByName[T]
10781085
type Return = Trees.Return[T]
10791086
type WhileDo = Trees.WhileDo[T]
10801087
type Try = Trees.Try[T]
@@ -1228,6 +1235,10 @@ object Trees {
12281235
case tree: Labeled if (bind eq tree.bind) && (expr eq tree.expr) => tree
12291236
case _ => finalize(tree, untpd.Labeled(bind, expr)(sourceFile(tree)))
12301237
}
1238+
def ByName(tree: Tree)(expr: Tree)(using Context): ByName = tree match {
1239+
case tree: ByName if expr eq tree.expr => tree
1240+
case _ => finalize(tree, untpd.ByName(expr)(sourceFile(tree)))
1241+
}
12311242
def Return(tree: Tree)(expr: Tree, from: Tree)(using Context): Return = tree match {
12321243
case tree: Return if (expr eq tree.expr) && (from eq tree.from) => tree
12331244
case _ => finalize(tree, untpd.Return(expr, from)(sourceFile(tree)))
@@ -1411,6 +1422,8 @@ object Trees {
14111422
cpy.CaseDef(tree)(transform(pat), transform(guard), transform(body))
14121423
case Labeled(bind, expr) =>
14131424
cpy.Labeled(tree)(transformSub(bind), transform(expr))
1425+
case ByName(expr) =>
1426+
cpy.ByName(tree)(transform(expr))
14141427
case Return(expr, from) =>
14151428
cpy.Return(tree)(transform(expr), transformSub(from))
14161429
case WhileDo(cond, body) =>
@@ -1556,6 +1569,8 @@ object Trees {
15561569
this(this(this(x, pat), guard), body)
15571570
case Labeled(bind, expr) =>
15581571
this(this(x, bind), expr)
1572+
case ByName(expr) =>
1573+
this(x, expr)
15591574
case Return(expr, from) =>
15601575
this(this(x, expr), from)
15611576
case WhileDo(cond, body) =>

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

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -128,14 +128,6 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
128128
Closure(meth, tss => rhsFn(tss.head).changeOwner(ctx.owner, meth))
129129
}
130130

131-
/** A <byname>(...) application */
132-
object ByName:
133-
def apply(tree: Tree)(using Context): Apply =
134-
Apply(ref(defn.byNameMethod), tree :: Nil)
135-
def unapply(tree: Apply)(using Context): Option[Tree] =
136-
if tree.fun.symbol == defn.byNameMethod then Some(tree.args.head)
137-
else None
138-
139131
def CaseDef(pat: Tree, guard: Tree, body: Tree)(using Context): CaseDef =
140132
ta.assignType(untpd.CaseDef(pat, guard, body), pat, body)
141133

@@ -151,6 +143,9 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
151143
def Labeled(sym: TermSymbol, expr: Tree)(using Context): Labeled =
152144
Labeled(Bind(sym, EmptyTree), expr)
153145

146+
def ByName(expr: Tree)(using Context): ByName =
147+
ta.assignType(untpd.ByName(expr), expr)
148+
154149
def Return(expr: Tree, from: Tree)(using Context): Return =
155150
ta.assignType(untpd.Return(expr, from))
156151

@@ -706,6 +701,9 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
706701
override def Labeled(tree: Tree)(bind: Bind, expr: Tree)(using Context): Labeled =
707702
ta.assignType(untpdCpy.Labeled(tree)(bind, expr))
708703

704+
override def ByName(tree: Tree)(expr: Tree)(using Context): ByName =
705+
ta.assignType(untpdCpy.ByName(tree)(expr), expr)
706+
709707
override def Return(tree: Tree)(expr: Tree, from: Tree)(using Context): Return =
710708
ta.assignType(untpdCpy.Return(tree)(expr, from))
711709

@@ -963,11 +961,6 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
963961
def ensureApplied(using Context): Tree =
964962
if (tree.tpe.widen.isParameterless) tree else tree.appliedToNone
965963

966-
/** Is tree a by-name application `<byname>(arg)`? */
967-
def isByName(using Context): Boolean = tree match
968-
case Apply(fun, _) => fun.symbol == defn.byNameMethod
969-
case _ => false
970-
971964
/** If tree is a by-name application `<byname>(arg)` return `arg`, otherwise the original tree */
972965
def dropByName(using Context): Tree = tree match
973966
case ByName(body) => body
@@ -980,7 +973,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
980973

981974
/** Make sure tree is by-name application if `formal` is a by-name parameter type */
982975
def alignByName(formal: Type)(using Context) = formal match
983-
case ByNameType(underlying) => wrapByName
976+
case ByNameType(_) if !tree.tpe.widen.isByName => ByName(tree)
984977
case _ => tree
985978

986979
/** `tree == that` */

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,7 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
383383
def InlineMatch(selector: Tree, cases: List[CaseDef])(implicit src: SourceFile): Match = new InlineMatch(selector, cases)
384384
def CaseDef(pat: Tree, guard: Tree, body: Tree)(implicit src: SourceFile): CaseDef = new CaseDef(pat, guard, body)
385385
def Labeled(bind: Bind, expr: Tree)(implicit src: SourceFile): Labeled = new Labeled(bind, expr)
386+
def ByName(expr: Tree)(implicit src: SourceFile): ByName = new ByName(expr)
386387
def Return(expr: Tree, from: Tree)(implicit src: SourceFile): Return = new Return(expr, from)
387388
def WhileDo(cond: Tree, body: Tree)(implicit src: SourceFile): WhileDo = new WhileDo(cond, body)
388389
def Try(expr: Tree, cases: List[CaseDef], finalizer: Tree)(implicit src: SourceFile): Try = new Try(expr, cases, finalizer)

compiler/src/dotty/tools/dotc/core/Definitions.scala

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -451,10 +451,6 @@ class Definitions {
451451
@tu lazy val throwMethod: TermSymbol = enterMethod(OpsPackageClass, nme.THROWkw,
452452
MethodType(List(ThrowableType), NothingType))
453453

454-
/** Method wrapping by-name arguments; created by Typer, eliminated in ByNameLambda */
455-
@tu lazy val byNameMethod: TermSymbol = enterMethod(OpsPackageClass, nme.BYNAME,
456-
MethodType(List(AnyType))(mt => FunctionOf(Nil, mt.paramRefs(0), isContextual = true)))
457-
458454
@tu lazy val NothingClass: ClassSymbol = enterCompleteClassSymbol(
459455
ScalaPackageClass, tpnme.Nothing, AbstractFinal, List(AnyType))
460456
def NothingType: TypeRef = NothingClass.typeRef
@@ -1812,7 +1808,7 @@ class Definitions {
18121808

18131809
/** Lists core methods that don't have underlying bytecode, but are synthesized on-the-fly in every reflection universe */
18141810
@tu lazy val syntheticCoreMethods: List[TermSymbol] =
1815-
AnyMethods ++ ObjectMethods ++ List(String_+, throwMethod, byNameMethod)
1811+
AnyMethods ++ ObjectMethods ++ List(String_+, throwMethod)
18161812

18171813
@tu lazy val reservedScalaClassNames: Set[Name] = syntheticScalaClasses.map(_.name).toSet
18181814

compiler/src/dotty/tools/dotc/core/StdNames.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,6 @@ object StdNames {
119119
val BITMAP_TRANSIENT: N = s"${BITMAP_PREFIX}trans$$" // initialization bitmap for transient lazy vals
120120
val BITMAP_CHECKINIT: N = s"${BITMAP_PREFIX}init$$" // initialization bitmap for checkinit values
121121
val BITMAP_CHECKINIT_TRANSIENT: N = s"${BITMAP_PREFIX}inittrans$$" // initialization bitmap for transient checkinit values
122-
val BYNAME: N = "<byname>"
123122
val DEFAULT_GETTER: N = str.DEFAULT_GETTER
124123
val DEFAULT_GETTER_INIT: N = "$lessinit$greater"
125124
val DO_WHILE_PREFIX: N = "doWhile$"

compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -417,15 +417,13 @@ class TreePickler(pickler: TastyPickler) {
417417
if fun.symbol eq defn.throwMethod then
418418
writeByte(THROW)
419419
pickleTree(args.head)
420-
else if fun.symbol eq defn.byNameMethod then
421-
pickleTree(args.head)
422-
// <by-name>(...) applications are re-constituted when unpickling
423-
// based on formal parameter types.
424420
else
425421
writeByte(APPLY)
426422
withLength {
427423
pickleTree(fun)
428-
args.foreach(pickleTree)
424+
args.foreach(arg => pickleTree(arg.dropByName))
425+
// <by-name>(...) applications are re-constituted when unpickling
426+
// based on formal parameter types.
429427
}
430428
case TypeApply(fun, args) =>
431429
writeByte(TYPEAPPLY)
@@ -458,7 +456,7 @@ class TreePickler(pickler: TastyPickler) {
458456
case NamedArg(name, arg) =>
459457
writeByte(NAMEDARG)
460458
pickleName(name)
461-
pickleTree(arg)
459+
pickleTree(arg.dropByName)
462460
case Assign(lhs, rhs) =>
463461
writeByte(ASSIGN)
464462
withLength { pickleTree(lhs); pickleTree(rhs) }
@@ -493,6 +491,11 @@ class TreePickler(pickler: TastyPickler) {
493491
case CaseDef(pat, guard, rhs) =>
494492
writeByte(CASEDEF)
495493
withLength { pickleTree(pat); pickleTree(rhs); pickleTreeUnlessEmpty(guard) }
494+
case ByName(expr) =>
495+
assert(false, i"ByName tree is not a method argument: $tree")
496+
// If we do allow ByName types that are not parameters in a future 3.x version,
497+
// we'd have to replace the assert with a -release check that these types are
498+
// not issued in earlier Tasty versions.
496499
case Return(expr, from) =>
497500
writeByte(RETURN)
498501
withLength { pickleSymRef(from.symbol); pickleTreeUnlessEmpty(expr) }

compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1142,11 +1142,14 @@ class TreeUnpickler(reader: TastyReader,
11421142
val (mixId, mixTpe) = ifBefore(end)(readQualId(), (untpd.EmptyTypeIdent, NoType))
11431143
tpd.Super(qual, mixId, mixTpe.typeSymbol)
11441144
case APPLY =>
1145+
def restoreByName(arg: Tree, formal: Type): Tree = arg match
1146+
case NamedArg(name, arg1) => cpy.NamedArg(arg)(name, restoreByName(arg1, formal))
1147+
case _ => arg.alignByName(formal)
11451148
val fn = readTerm()
11461149
var args = until(end)(readTerm())
11471150
fn.tpe.widen match
11481151
case mt: MethodType =>
1149-
args = args.zipWithConserve(mt.paramInfos)(_.alignByName(_))
1152+
args = args.zipWithConserve(mt.paramInfos)(restoreByName)
11501153
case _ =>
11511154
tpd.Apply(fn, args)
11521155
case TYPEAPPLY =>

compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -428,8 +428,6 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
428428
changePrec (GlobalPrec) {
429429
keywordStr("throw ") ~ toText(args.head)
430430
}
431-
else if fun.symbol == defn.byNameMethod && !printDebug && !ctx.settings.YtestPickler.value then
432-
toText(args.head)
433431
else if (!printDebug && fun.hasType && fun.symbol == defn.QuotedRuntime_exprQuote)
434432
keywordStr("'{") ~ toTextGlobal(args, ", ") ~ keywordStr("}")
435433
else if (!printDebug && fun.hasType && fun.symbol.isExprSplice)
@@ -501,6 +499,11 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
501499
keywordStr("case ") ~ inPattern(toText(pat)) ~ optText(guard)(keywordStr(" if ") ~ _) ~ " => " ~ caseBlockText(body)
502500
case Labeled(bind, expr) =>
503501
changePrec(GlobalPrec) { toText(bind.name) ~ keywordStr("[") ~ toText(bind.symbol.info) ~ keywordStr("]: ") ~ toText(expr) }
502+
case ByName(expr) =>
503+
if printDebug || ctx.settings.YtestPickler.value then
504+
"<ByName>(" ~ toText(expr) ~ ")"
505+
else
506+
toText(expr)
504507
case Return(expr, from) =>
505508
val sym = from.symbol
506509
if (sym.is(Label))

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

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,11 @@ class ByNameLambda extends MiniPhase, IdentityDenotTransformer:
2323
// works on ByName arguments but not converted closures, and it sees the arguments
2424
// after transformations by subsequent miniphases in the same group.
2525

26-
override def transformApply(app: Apply)(using Context): Tree = app match
27-
case ByName(body) =>
28-
body match
29-
case Apply(Select(fn, nme.apply), Nil) if isPurePath(fn) && fn.tpe.widen.isByName =>
30-
fn
31-
case _ =>
32-
byNameClosure(body)
33-
case _ => app
26+
override def transformByName(tree: ByName)(using Context): Tree = tree.expr match
27+
case Apply(Select(fn, nme.apply), Nil) if isPurePath(fn) && fn.tpe.widen.isByName =>
28+
fn
29+
case _ =>
30+
byNameClosure(tree.expr)
3431

3532
def byNameClosure(body: Tree)(using Context): Block =
3633
val restpe = body.tpe.widenIfUnstable.deskolemized

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

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,7 @@ class CheckLoopingImplicits extends MiniPhase:
4545
checkNotLooping(qual)
4646
case Apply(fn, args) =>
4747
checkNotLooping(fn)
48-
if fn.symbol != defn.Boolean_&&
49-
&& fn.symbol != defn.Boolean_||
50-
&& fn.symbol != defn.byNameMethod then
48+
if fn.symbol != defn.Boolean_&& && fn.symbol != defn.Boolean_|| then
5149
args.foreach(checkNotLooping)
5250
case TypeApply(fn, _) =>
5351
checkNotLooping(fn)

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ class ElimRepeated extends MiniPhase with InfoTransformer { thisPhase =>
138138
else
139139
expr
140140
case arg @ ByName(arg1) =>
141-
cpy.Apply(arg)(arg.fun, transformArg(arg1, toArray) :: Nil)
141+
cpy.ByName(arg)(transformArg(arg1, toArray))
142142
case arg => arg
143143

144144
private def adaptToArray(tree: Tree)(implicit ctx: Context): Tree = tree match

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@ object ExplicitOuter {
235235
* fully qualified name `outerAccName` will fail, because the `outerAccName`'s
236236
* result is phase dependent. In that case we use a backup strategy where we search all
237237
* definitions in the class to find the one with the OuterAccessor flag.
238+
* ^^^ check whether this is still needed
238239
*/
239240
def outerAccessor(cls: ClassSymbol)(using Context): Symbol =
240241
if (cls.isStatic) NoSymbol // fast return to avoid scanning package decls

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ class HoistSuperArgs extends MiniPhase with IdentityDenotTransformer { thisPhase
4646
def phaseName: String = HoistSuperArgs.name
4747

4848
override def runsAfter: Set[String] = Set(ByNameLambda.name)
49-
// Assumes by-name argments are already converted to closures. ^^^ or maybe run before ByNameLambda?
49+
// Assumes by-name argments are already converted to closures.
5050

5151
/** Defines methods for hoisting complex supercall arguments out of
5252
* parent super calls and constructor definitions.

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

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ object MegaPhase {
6262
def prepareForMatch(tree: Match)(using Context): Context = ctx
6363
def prepareForCaseDef(tree: CaseDef)(using Context): Context = ctx
6464
def prepareForLabeled(tree: Labeled)(using Context): Context = ctx
65+
def prepareForByName(tree: ByName)(using Context): Context = ctx
6566
def prepareForReturn(tree: Return)(using Context): Context = ctx
6667
def prepareForWhileDo(tree: WhileDo)(using Context): Context = ctx
6768
def prepareForTry(tree: Try)(using Context): Context = ctx
@@ -96,6 +97,7 @@ object MegaPhase {
9697
def transformMatch(tree: Match)(using Context): Tree = tree
9798
def transformCaseDef(tree: CaseDef)(using Context): Tree = tree
9899
def transformLabeled(tree: Labeled)(using Context): Tree = tree
100+
def transformByName(tree: ByName)(using Context): Tree = tree
99101
def transformReturn(tree: Return)(using Context): Tree = tree
100102
def transformWhileDo(tree: WhileDo)(using Context): Tree = tree
101103
def transformTry(tree: Try)(using Context): Tree = tree
@@ -198,6 +200,7 @@ class MegaPhase(val miniPhases: Array[MiniPhase]) extends Phase {
198200
case tree: PackageDef => goPackageDef(tree, start)
199201
case tree: Try => goTry(tree, start)
200202
case tree: Inlined => goInlined(tree, start)
203+
case tree: ByName => goByName(tree, start)
201204
case tree: Return => goReturn(tree, start)
202205
case tree: WhileDo => goWhileDo(tree, start)
203206
case tree: Alternative => goAlternative(tree, start)
@@ -397,6 +400,11 @@ class MegaPhase(val miniPhases: Array[MiniPhase]) extends Phase {
397400
val expansion = transformTree(tree.expansion, start)(using inlineContext(tree.call))
398401
goInlined(cpy.Inlined(tree)(tree.call, bindings, expansion), start)
399402
}
403+
case tree: ByName =>
404+
inContext(prepByName(tree, start)(using outerCtx)) {
405+
val expr = transformTree(tree.expr, start)
406+
goByName(cpy.ByName(tree)(expr), start)
407+
}
400408
case tree: Return =>
401409
inContext(prepReturn(tree, start)(using outerCtx)) {
402410
val expr = transformTree(tree.expr, start)
@@ -535,6 +543,8 @@ class MegaPhase(val miniPhases: Array[MiniPhase]) extends Phase {
535543
private val nxCaseDefTransPhase = init("transformCaseDef")
536544
private val nxLabeledPrepPhase = init("prepareForLabeled")
537545
private val nxLabeledTransPhase = init("transformLabeled")
546+
private val nxByNamePrepPhase = init("prepareForByName")
547+
private val nxByNameTransPhase = init("transformByName")
538548
private val nxReturnPrepPhase = init("prepareForReturn")
539549
private val nxReturnTransPhase = init("transformReturn")
540550
private val nxWhileDoPrepPhase = init("prepareForWhileDo")
@@ -812,6 +822,21 @@ class MegaPhase(val miniPhases: Array[MiniPhase]) extends Phase {
812822
}
813823
}
814824

825+
def prepByName(tree: ByName, start: Int)(using Context): Context = {
826+
val phase = nxByNamePrepPhase(start)
827+
if (phase == null) ctx
828+
else prepByName(tree, phase.idxInGroup + 1)(using phase.prepareForByName(tree))
829+
}
830+
831+
def goByName(tree: ByName, start: Int)(using Context): Tree = {
832+
val phase = nxByNameTransPhase(start)
833+
if (phase == null) tree
834+
else phase.transformByName(tree) match {
835+
case tree1: ByName => goByName(tree1, phase.idxInGroup + 1)
836+
case tree1 => transformNode(tree1, phase.idxInGroup + 1)
837+
}
838+
}
839+
815840
def prepReturn(tree: Return, start: Int)(using Context): Context = {
816841
val phase = nxReturnPrepPhase(start)
817842
if (phase == null) ctx

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,10 @@ class ResolveSuper extends MiniPhase with IdentityDenotTransformer { thisPhase =
3535

3636
override def phaseName: String = ResolveSuper.name
3737

38-
override def runsAfter: Set[String] = Set(ByNameLambda.name, // verified empirically, need to figure out what the reason is.
39-
PruneErasedDefs.name) // Erased decls make `isCurrent` work incorrectly
38+
override def runsAfter: Set[String] = Set(
39+
ByNameLambda.name, // verified empirically for ElimByName
40+
//^^^ check whether this is also needed for ByNameLambda
41+
PruneErasedDefs.name) // Erased decls make `isCurrent` work incorrectly
4042

4143
override def changesMembers: Boolean = true // the phase adds super accessors
4244

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -144,9 +144,10 @@ object Splicer {
144144
summon[Env]
145145
}
146146

147-
def checkIfValidArgument(tree: Tree)(using Env): Unit = tree.dropByName match {
147+
def checkIfValidArgument(tree: Tree)(using Env): Unit = tree match {
148148
case Block(Nil, expr) => checkIfValidArgument(expr)
149149
case Typed(expr, _) => checkIfValidArgument(expr)
150+
case ByName(expr) => checkIfValidArgument(expr)
150151

151152
case Apply(Select(Apply(fn, quoted :: Nil), nme.apply), _) if fn.symbol == defn.QuotedRuntime_exprQuote =>
152153
val noSpliceChecker = new TreeTraverser {
@@ -259,9 +260,7 @@ object Splicer {
259260

260261
// TODO disallow interpreted method calls as arguments
261262
case Call(fn, args) =>
262-
if fn.symbol == defn.byNameMethod then
263-
() => interpretTree(args.head.head)
264-
else if (fn.symbol.isConstructor && fn.symbol.owner.owner.is(Package))
263+
if (fn.symbol.isConstructor && fn.symbol.owner.owner.is(Package))
265264
interpretNew(fn.symbol, args.flatten.map(interpretTree))
266265
else if (fn.symbol.is(Module))
267266
interpretModuleAccess(fn.symbol)
@@ -293,6 +292,7 @@ object Splicer {
293292
// `val j$1 = x; val i$1 = y; foo(i = i$1, j = j$1)`
294293
case Block(stats, expr) => interpretBlock(stats, expr)
295294
case NamedArg(_, arg) => interpretTree(arg)
295+
case ByName(arg) => () => interpretTree(arg)
296296

297297
case Inlined(_, bindings, expansion) => interpretBlock(bindings, expansion)
298298

0 commit comments

Comments
 (0)