@@ -167,53 +167,37 @@ object EtaExpansion extends LiftImpure {
167
167
*
168
168
* { val xs = es; expr }
169
169
*
170
- * The result of the eta-expansion is either (1)
170
+ * If xarity matches the number of parameters in `mt`, the eta-expansion is
171
171
*
172
172
* { val xs = es; (x1, ..., xn) => expr(x1, ..., xn) }
173
173
*
174
- * or (2)
174
+ * Note that the function value's parameters are untyped, hence the type will
175
+ * be supplied by the environment (or if missing be supplied by the target
176
+ * method as a fallback). On the other hand, if `xarity` is different from
177
+ * the number of parameters in `mt`, then we cannot propagate parameter types
178
+ * from the expected type, and we fallback to using the method's original
179
+ * parameter types instead.
175
180
*
176
- * { val xs = es; (x1: T1, ..., xn: Tn) => expr(x1, ..., xn) }
177
- *
178
- * or (3)
179
- *
180
- * { val xs = es; (x1: T1, ..., xn: Tn) => expr(x1, ..., xn) _ }
181
- *
182
- * where `T1, ..., Tn` are the paremeter types of the expanded method.
183
- *
184
- * Case (3) applies if the method is curried, i.e. its result type is again a method
185
- * type. Case (2) applies if the expected arity of the function type `xarity` differs
186
- * from the number of parameters in `mt`. Case (1) applies if `mt` is uncurried
187
- * and its number of parameters equals `xarity`. In this case we can always infer
188
- * the parameter types later from the callee even if parameter types could not be
189
- * inferred from the expected type. Hence, we lose nothing by omitting parameter types
190
- * in the eta expansion. On the other hand omitting these parameters keeps the possibility
191
- * open that different parameters are inferred from the expected type, so we keep
192
- * more options open.
193
- *
194
- * In each case, the result is an untyped tree, with `es` and `expr` as typed splices.
195
- *
196
- * F[V](x) ==> (x => F[X])
181
+ * In either case, the result is an untyped tree, with `es` and `expr` as typed splices.
197
182
*/
198
183
def etaExpand (tree : Tree , mt : MethodType , xarity : Int )(implicit ctx : Context ): untpd.Tree = {
199
184
import untpd ._
200
185
assert(! ctx.isAfterTyper)
201
186
val defs = new mutable.ListBuffer [tpd.Tree ]
202
187
val lifted : Tree = TypedSplice (liftApp(defs, tree))
203
- val isLastApplication = mt.resultType match {
204
- case rt : MethodType => rt.isImplicitMethod
205
- case _ => true
206
- }
207
188
val paramTypes : List [Tree ] =
208
- if (isLastApplication && mt.paramInfos.length == xarity) mt.paramInfos map (_ => TypeTree ())
189
+ if (mt.paramInfos.length == xarity) mt.paramInfos map (_ => TypeTree ())
209
190
else mt.paramInfos map TypeTree
210
191
val params = (mt.paramNames, paramTypes).zipped.map((name, tpe) =>
211
192
ValDef (name, tpe, EmptyTree ).withFlags(Synthetic | Param ).withPos(tree.pos.startPos))
212
193
var ids : List [Tree ] = mt.paramNames map (name => Ident (name).withPos(tree.pos.startPos))
213
194
if (mt.paramInfos.nonEmpty && mt.paramInfos.last.isRepeatedParam)
214
195
ids = ids.init :+ repeated(ids.last)
215
196
var body : Tree = Apply (lifted, ids)
216
- if (! isLastApplication) body = PostfixOp (body, Ident (nme.WILDCARD ))
197
+ mt.resultType match {
198
+ case rt : MethodType if ! rt.isImplicitMethod => body = PostfixOp (body, Ident (nme.WILDCARD ))
199
+ case _ =>
200
+ }
217
201
val fn = untpd.Function (params, body)
218
202
if (defs.nonEmpty) untpd.Block (defs.toList map (untpd.TypedSplice (_)), fn) else fn
219
203
}
0 commit comments