aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/typer/EtaExpansion.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2013-12-28 21:46:05 +0100
committerMartin Odersky <odersky@gmail.com>2013-12-28 21:46:05 +0100
commit3c8196300d65738d6779ba8703e2a86ee3390ec7 (patch)
treed8edb5ee7eff6c2e012c0fef9e73938d7f3eeacc /src/dotty/tools/dotc/typer/EtaExpansion.scala
parent53c0d8996c5d065bff2f860948e5c563b187d221 (diff)
downloaddotty-3c8196300d65738d6779ba8703e2a86ee3390ec7.tar.gz
dotty-3c8196300d65738d6779ba8703e2a86ee3390ec7.tar.bz2
dotty-3c8196300d65738d6779ba8703e2a86ee3390ec7.zip
New version of eta-expansion.
This version expands a method ref p.m to the untyped tree p.m(_, ..., _) (after lifting impure expressions from p). Afterwards the usual application mechanisms kick in. This fixes problems also present in Scala 2.x, where an eta-expanded function was not as flexible as an explicitly expanded one (for instance, eta expansion did not honor default parameters).
Diffstat (limited to 'src/dotty/tools/dotc/typer/EtaExpansion.scala')
-rw-r--r--src/dotty/tools/dotc/typer/EtaExpansion.scala36
1 files changed, 17 insertions, 19 deletions
diff --git a/src/dotty/tools/dotc/typer/EtaExpansion.scala b/src/dotty/tools/dotc/typer/EtaExpansion.scala
index 16a02ba5c..46a1d3583 100644
--- a/src/dotty/tools/dotc/typer/EtaExpansion.scala
+++ b/src/dotty/tools/dotc/typer/EtaExpansion.scala
@@ -94,33 +94,31 @@ object EtaExpansion {
}
/** Eta-expanding a tree means converting a method reference to a function value.
- * @param tree The tree to expand
- * @param wtp The widened type of the tree, which is always a MethodType
- * Let `wtp` be the method type
- *
- * (x1: T1, ..., xn: Tn): R
- *
+ * @param tree The tree to expand
+ * @param paramNames The names of the parameters to use in the expansion
+ * Let `paramNames` be x1, ..., xn
* and assume the lifted application of `tree` (@see liftApp) is
*
* { val xs = es; expr }
*
* Then the eta-expansion is
*
- * { val xs = es;
- * { def $anonfun(x1: T1, ..., xn: Tn): T = expr; Closure($anonfun) }}
+ * { val xs = es; (x1, ..., xn) => expr(xx1, ..., xn) }
+ *
+ * This is an untyped tree, with `es` and `expr` as typed splices.
*/
- def etaExpand(tree: Tree, tpe: MethodType)(implicit ctx: Context): Tree = {
- def expand(lifted: Tree): Tree = {
- val meth = ctx.newSymbol(ctx.owner, nme.ANON_FUN, Synthetic, tpe, coord = tree.pos)
- Closure(meth, argss => (lifted /: argss)(Apply(_, _)))
- }
- val defs = new mutable.ListBuffer[Tree]
- val lifted = liftApp(defs, tree)
- wrapDefs(defs, expand(lifted))
+ def etaExpand(tree: Tree, paramNames: List[TermName])(implicit ctx: Context): untpd.Tree = {
+ import untpd._
+ val defs = new mutable.ListBuffer[tpd.Tree]
+ val lifted: Tree = TypedSplice(liftApp(defs, tree))
+ val params = paramNames map (name =>
+ ValDef(Modifiers(Synthetic | Param), name, TypeTree(), EmptyTree).withPos(tree.pos))
+ val ids = paramNames map (name =>
+ Ident(name).withPos(tree.pos))
+ val body = Apply(lifted, ids)
+ val fn = untpd.Function(params, body)
+ if (defs.nonEmpty) untpd.Block(defs.toList map untpd.TypedSplice, fn) else fn
}
-
- def wrapDefs(defs: mutable.ListBuffer[Tree], tree: Tree)(implicit ctx: Context): Tree =
- if (defs != null && defs.nonEmpty) tpd.Block(defs.toList, tree) else tree
}
/** <p> not needed