@@ -20,27 +20,12 @@ import ast.Trees._
20
20
*
21
21
* For the types of parameter symbols:
22
22
*
23
- * => T ==> () => T
23
+ * => T ==> () => T
24
24
*
25
- * Note that `=> T` types are not eliminated in MethodTypes. This is done later at erasure.
26
- * Terms are rewritten as follows:
25
+ * For cbn parameter values
27
26
*
28
- * x ==> x.apply() if x is a parameter that had type => T
29
- *
30
- * Arguments to call-by-name parameters are translated as follows. First, the argument is
31
- * rewritten by the rules
32
- *
33
- * e.apply() ==> e if e.apply() is an argument to a call-by-name parameter
34
- * expr ==> () => expr if other expr is an argument to a call-by-name parameter
35
- *
36
- * This makes the argument compatible with a parameter type of () => T, which will be the
37
- * formal parameter type at erasure. But to be -Ycheckable until then, any argument
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.
27
+ * x ==> x()
28
+ * CbnArg(x) ==> DummyApply(x)
44
29
*
45
30
* Note: This scheme to have inconsistent types between method types (whose formal types are still
46
31
* ExprTypes and parameter valdefs (which are now FunctionTypes) is not pretty. There are two
@@ -53,7 +38,7 @@ import ast.Trees._
53
38
* Option 2: Merge ElimByName with erasure, or have it run immediately before. This has not been
54
39
* tried yet.
55
40
*/
56
- class ElimByName extends MiniPhaseTransform with InfoTransformer { thisTransformer =>
41
+ class ElimByName extends ByNameClosures with InfoTransformer { thisTransformer =>
57
42
import ast .tpd ._
58
43
59
44
override def phaseName : String = " elimByName"
@@ -62,52 +47,10 @@ class ElimByName extends MiniPhaseTransform with InfoTransformer { thisTransform
62
47
// assumes idents and selects have symbols; interferes with splitter distribution
63
48
// that's why it's "after group".
64
49
65
- /** The info of the tree's symbol at phase Nullarify (i.e. before transformation) */
66
- private def originalDenotation (tree : Tree )(implicit ctx : Context ) =
67
- tree.symbol.denot(ctx.withPhase(thisTransformer))
68
-
69
- override def transformApply (tree : Apply )(implicit ctx : Context , info : TransformerInfo ): Tree =
70
- ctx.traceIndented(s " transforming ${tree.show} at phase ${ctx.phase}" , show = true ) {
71
-
72
- def transformArg (arg : Tree , formal : Type ): Tree = formal.dealias match {
73
- case formalExpr : ExprType =>
74
- var argType = arg.tpe.widenIfUnstable
75
- if (defn.isBottomType(argType)) argType = formal.widenExpr
76
- val argFun = arg match {
77
- case Apply (Select (qual, nme.apply), Nil )
78
- if qual.tpe.derivesFrom(defn.FunctionClass (0 )) && isPureExpr(qual) =>
79
- qual
80
- case _ =>
81
- val inSuper = if (ctx.mode.is(Mode .InSuperCall )) InSuperCall else EmptyFlags
82
- val meth = ctx.newSymbol(
83
- ctx.owner, nme.ANON_FUN , Synthetic | Method | inSuper, MethodType (Nil , Nil , argType))
84
- Closure (meth, _ =>
85
- atGroupEnd { implicit ctx : Context =>
86
- arg.changeOwner(ctx.owner, meth)
87
- }
88
- )
89
- }
90
- ref(defn.dummyApply).appliedToType(argType).appliedTo(argFun)
91
- case _ =>
92
- arg
93
- }
94
-
95
- val mt @ MethodType (_) = tree.fun.tpe.widen
96
- val args1 = tree.args.zipWithConserve(mt.paramInfos)(transformArg)
97
- cpy.Apply (tree)(tree.fun, args1)
98
- }
99
-
100
- /** If denotation had an ExprType before, it now gets a function type */
101
- private def exprBecomesFunction (symd : SymDenotation )(implicit ctx : Context ) =
102
- (symd is Param ) || (symd is (ParamAccessor , butNot = Method ))
103
-
104
50
/** Map `tree` to `tree.apply()` is `ftree` was of ExprType and becomes now a function */
105
- private def applyIfFunction (tree : Tree , ftree : Tree )(implicit ctx : Context ) = {
106
- val origDenot = originalDenotation(ftree)
107
- if (exprBecomesFunction(origDenot) && (origDenot.info.isInstanceOf [ExprType ]))
108
- tree.select(defn.Function0_apply ).appliedToNone
51
+ private def applyIfFunction (tree : Tree , ftree : Tree )(implicit ctx : Context ) =
52
+ if (isByNameRef(ftree)) tree.select(defn.Function0_apply ).appliedToNone
109
53
else tree
110
- }
111
54
112
55
override def transformIdent (tree : Ident )(implicit ctx : Context , info : TransformerInfo ): Tree =
113
56
applyIfFunction(tree, tree)
0 commit comments