Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 7a77a6a

Browse files
committed
UnCurry byNameArgs means noApply
1 parent e7a4a4c commit 7a77a6a

File tree

1 file changed

+16
-16
lines changed

1 file changed

+16
-16
lines changed

src/compiler/scala/tools/nsc/transform/UnCurry.scala

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,6 @@ abstract class UnCurry extends InfoTransform
7878
private val forceExpandFunction = settings.Ydelambdafy.value == "inline"
7979
private var needTryLift = false
8080
private var inConstructorFlag = 0L
81-
private val byNameArgs = mutable.HashSet.empty[Tree]
8281
private val noApply = mutable.HashSet.empty[Tree]
8382
private val newMembers = mutable.Map.empty[Symbol, Buffer[Tree]]
8483

@@ -124,11 +123,14 @@ abstract class UnCurry extends InfoTransform
124123
EmptyTree
125124
}
126125

127-
/* Is tree a reference `x` to a call by name parameter that needs to be converted to
128-
* x.apply()? Note that this is not the case if `x` is used as an argument to another
129-
* call by name parameter.
126+
/* Is `tree` a reference `x` to a call by name parameter and eligible to be converted to x.apply()?
127+
*
128+
* Normally, such a reference evaluates the argument.
129+
*
130+
* This is not the case if `x` is used as an argument to a method that takes it as a call by name parameter.
131+
* Additionally, an expression `() => x` is "unwrapped" to `x` and must not be applied.
130132
*/
131-
def isByNameRef(tree: Tree) = {
133+
def isByNameRefToApply(tree: Tree) = {
132134
val sym = tree.symbol
133135
val maybe = (
134136
(sym ne null)
@@ -138,7 +140,7 @@ abstract class UnCurry extends InfoTransform
138140
tree match {
139141
case _ if !maybe => false
140142
case _: This | _: Super => false
141-
case tree => isByName(sym) && !byNameArgs(tree)
143+
case tree => isByName(sym) && !noApply(tree)
142144
}
143145
}
144146

@@ -227,7 +229,7 @@ abstract class UnCurry extends InfoTransform
227229
// Normally, we can unwrap `() => cbn` to `cbn` where `cbn` refers to a CBN argument (typically `cbn` is an Ident)
228230
// because we know `cbn` will already be a `Function0` thunk. When we're targeting a SAM,
229231
// the types don't align and we must preserve the function wrapper.
230-
if (fun.vparams.isEmpty && isByNameRef(fun.body) && !fun.attachments.contains[SAMFunction]) {
232+
if (fun.vparams.isEmpty && isByNameRefToApply(fun.body) && !fun.attachments.contains[SAMFunction]) {
231233
noApply += fun.body
232234
fun.body
233235
}
@@ -353,12 +355,12 @@ abstract class UnCurry extends InfoTransform
353355
val param0 = if (params0.hasNext) params0.next() else NoSymbol
354356
if (!isByNameParamType(param.info)) {
355357
if (param0 != NoSymbol && isByNameParamType(param0.info)) // pass 2, sig is uncurried in expansion
356-
byNameArgs += arg
358+
noApply += arg
357359
arg
358360
}
359-
else if (isByNameRef(arg)) {
361+
else if (isByNameRefToApply(arg)) {
360362
// thunk does not need to be forced because it's a reference to a by-name arg passed to a by-name param
361-
byNameArgs += arg
363+
noApply += arg
362364
arg.setType(functionType(Nil, arg.tpe))
363365
} else {
364366
log(s"Argument '$arg' at line ${arg.pos.line} is ${param.info} from ${fun.fullName}")
@@ -559,12 +561,10 @@ abstract class UnCurry extends InfoTransform
559561

560562
case _ =>
561563
val tree1 = super.transform(tree)
562-
if (isByNameRef(tree1)) {
563-
val tree2 = tree1 setType functionType(Nil, tree1.tpe)
564-
val tree3 =
565-
if (noApply(tree2)) tree2
566-
else localTyper.typedPos(tree1.pos)(Apply(Select(tree2, nme.apply), Nil))
567-
return tree3
564+
if (isByNameRefToApply(tree1)) {
565+
val tree2 = tree1.setType(functionType(Nil, tree1.tpe))
566+
val tree3 = localTyper.typedPos(tree1.pos)(Apply(Select(tree2, nme.apply), Nil))
567+
return tree3 // result type already set
568568
}
569569
tree1
570570
}

0 commit comments

Comments
 (0)