Skip to content

Commit 95ef88f

Browse files
committed
Merge pull request #267 from dotty-staging/fix/byname-args
Fix by-name arguments
2 parents 8336a0d + fc23083 commit 95ef88f

File tree

4 files changed

+17
-16
lines changed

4 files changed

+17
-16
lines changed

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,11 @@ class Definitions {
172172
def ObjectMethods = List(Object_eq, Object_ne, Object_synchronized, Object_clone,
173173
Object_finalize, Object_notify, Object_notifyAll, Object_wait, Object_waitL, Object_waitLI)
174174

175+
/** Dummy method needed by elimByName */
176+
lazy val dummyApply = newPolyMethod(
177+
RootClass, nme.dummyApply, 1,
178+
pt => MethodType(List(FunctionType(Nil, PolyParam(pt, 0))), PolyParam(pt, 0)))
179+
175180
lazy val NotNullClass = ctx.requiredClass("scala.NotNull")
176181

177182
lazy val NothingClass: ClassSymbol = newCompleteClassSymbol(

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,7 @@ object StdNames {
372372
val delayedInit: N = "delayedInit"
373373
val delayedInitArg: N = "delayedInit$body"
374374
val drop: N = "drop"
375+
val dummyApply: N = "<dummy-apply>"
375376
val elem: N = "elem"
376377
val emptyValDef: N = "emptyValDef"
377378
val ensureAccessible : N = "ensureAccessible"

src/dotty/tools/dotc/transform/ElimByName.scala

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,6 @@ import util.Attachment
1515
import core.StdNames.nme
1616
import ast.Trees._
1717

18-
object ElimByName {
19-
val ByNameArg = new Attachment.Key[Unit]
20-
}
21-
2218
/** This phase eliminates ExprTypes `=> T` as types of function parameters, and replaces them by
2319
* nullary function types. More precisely:
2420
*
@@ -39,13 +35,15 @@ object ElimByName {
3935
*
4036
* This makes the argument compatible with a parameter type of () => T, which will be the
4137
* formal parameter type at erasure. But to be -Ycheckable until then, any argument
42-
* ARG rewritten by the rules above is again wrapped in an application ARG.apply(),
43-
* labelled with a `ByNameParam` attachment. Erasure will later strip wrapped
44-
* `.apply()` calls with ByNameParam attachments.
38+
* ARG rewritten by the rules above is again wrapped in an application DummyApply(ARG)
39+
* where
40+
*
41+
* DummyApply: [T](() => T): T
42+
*
43+
* is a synthetic method defined in Definitions. Erasure will later strip these DummyApply wrappers.
4544
*/
4645
class ElimByName extends MiniPhaseTransform with InfoTransformer { thisTransformer =>
4746
import ast.tpd._
48-
import ElimByName._
4947

5048
override def phaseName: String = "elimByName"
5149

@@ -64,17 +62,16 @@ class ElimByName extends MiniPhaseTransform with InfoTransformer { thisTransform
6462

6563
def transformArg(arg: Tree, formal: Type): Tree = formal.dealias match {
6664
case formalExpr: ExprType =>
65+
val argType = arg.tpe.widen
6766
val argFun = arg match {
6867
case Apply(Select(qual, nme.apply), Nil) if qual.tpe derivesFrom defn.FunctionClass(0) =>
6968
qual
7069
case _ =>
7170
val meth = ctx.newSymbol(
72-
ctx.owner, nme.ANON_FUN, Synthetic | Method, MethodType(Nil, Nil, arg.tpe.widen))
71+
ctx.owner, nme.ANON_FUN, Synthetic | Method, MethodType(Nil, Nil, argType))
7372
Closure(meth, _ => arg.changeOwner(ctx.owner, meth))
7473
}
75-
val argApplied = argFun.select(defn.Function0_apply).appliedToNone
76-
argApplied.putAttachment(ByNameArg, ())
77-
argApplied
74+
ref(defn.dummyApply).appliedToType(argType).appliedTo(argFun)
7875
case _ =>
7976
arg
8077
}

src/dotty/tools/dotc/transform/Erasure.scala

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -370,10 +370,8 @@ object Erasure extends TypeTestsCasts{
370370

371371
override def typedApply(tree: untpd.Apply, pt: Type)(implicit ctx: Context): Tree = {
372372
val Apply(fun, args) = tree
373-
if (tree.removeAttachment(ElimByName.ByNameArg).isDefined) {
374-
val Select(qual, nme.apply) = fun
375-
typedUnadapted(qual, pt)
376-
}
373+
if (fun.symbol == defn.dummyApply)
374+
typedUnadapted(args.head, pt)
377375
else typedExpr(fun, FunProto(args, pt, this)) match {
378376
case fun1: Apply => // arguments passed in prototype were already passed
379377
fun1

0 commit comments

Comments
 (0)