summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/transform/UnCurry.scala
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@typesafe.com>2016-03-30 17:17:34 -0700
committerAdriaan Moors <adriaan.moors@typesafe.com>2016-03-30 20:07:34 -0700
commit8e32d00e1679114ee1b3f9a90f235d2ab9feba2e (patch)
treeb7bb9f449797b561baf0a10a7eab004f01a8cf24 /src/compiler/scala/tools/nsc/transform/UnCurry.scala
parent7025be9a468419ca6076d78f8da32c6a667fc829 (diff)
downloadscala-8e32d00e1679114ee1b3f9a90f235d2ab9feba2e.tar.gz
scala-8e32d00e1679114ee1b3f9a90f235d2ab9feba2e.tar.bz2
scala-8e32d00e1679114ee1b3f9a90f235d2ab9feba2e.zip
Keep Function when CBN arg thunk targets a SAM
The body of `def delay[T](v: => T) = (v _): F0[T]` becomes `() => v` during `typedEta`, and then uncurry considers whether to strip the function wrapper since `v` is known to be a `Function0` thunk. Stripping is sound when the expected type is `Function0` for this expression, but that's no longer a given, since we could be expecting any nullary SAM. Also sweep up a bit around `typedEta`. Encapsulate the, erm, creative encoding of `m _` as `Typed(m, Function(Nil, EmptyTree))`.
Diffstat (limited to 'src/compiler/scala/tools/nsc/transform/UnCurry.scala')
-rw-r--r--src/compiler/scala/tools/nsc/transform/UnCurry.scala7
1 files changed, 5 insertions, 2 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
index 44d2469621..628090dba5 100644
--- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala
+++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
@@ -205,8 +205,11 @@ abstract class UnCurry extends InfoTransform
*
*/
def transformFunction(fun: Function): Tree =
- // Undo eta expansion for parameterless and nullary methods
- if (fun.vparams.isEmpty && isByNameRef(fun.body)) { noApply += fun.body ; fun.body }
+ // Undo eta expansion for parameterless and nullary methods, EXCEPT if `fun` targets a SAM.
+ // Normally, we can unwrap `() => cbn` to `cbn` where `cbn` refers to a CBN argument (typically `cbn` is an Ident),
+ // because we know `cbn` will already be a `Function0` thunk. When we're targeting a SAM,
+ // the types don't align and we must preserve the function wrapper.
+ if (fun.vparams.isEmpty && isByNameRef(fun.body) && fun.attachments.get[SAMFunction].isEmpty) { noApply += fun.body ; fun.body }
else if (forceExpandFunction || inConstructorFlag != 0) {
// Expand the function body into an anonymous class
gen.expandFunction(localTyper)(fun, inConstructorFlag)