aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/transform/ExpandSAMs.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2015-04-30 15:09:06 +0200
committerMartin Odersky <odersky@gmail.com>2015-05-02 19:07:39 +0200
commitdbe0456b740e841ddd35fd0d9802aff95c7c4426 (patch)
treea48e95fdbd11bf7166e411595ff71559d6425616 /src/dotty/tools/dotc/transform/ExpandSAMs.scala
parent9be27ae2750b2554cf8d0719a4737f6420042995 (diff)
downloaddotty-dbe0456b740e841ddd35fd0d9802aff95c7c4426.tar.gz
dotty-dbe0456b740e841ddd35fd0d9802aff95c7c4426.tar.bz2
dotty-dbe0456b740e841ddd35fd0d9802aff95c7c4426.zip
More conditions under which SAMs are converted to anonymous classes
Also included are - Closures implementing classes that inherit from a class other than Object - Closures that implement traits which run initialization code.
Diffstat (limited to 'src/dotty/tools/dotc/transform/ExpandSAMs.scala')
-rw-r--r--src/dotty/tools/dotc/transform/ExpandSAMs.scala20
1 files changed, 15 insertions, 5 deletions
diff --git a/src/dotty/tools/dotc/transform/ExpandSAMs.scala b/src/dotty/tools/dotc/transform/ExpandSAMs.scala
index 3b151dc31..bba42f403 100644
--- a/src/dotty/tools/dotc/transform/ExpandSAMs.scala
+++ b/src/dotty/tools/dotc/transform/ExpandSAMs.scala
@@ -5,15 +5,19 @@ import core._
import Contexts._, Symbols._, Types._, Flags._, Decorators._, StdNames._, Constants._
import SymDenotations.SymDenotation
import TreeTransforms._
+import SymUtils._
import ast.untpd
import ast.Trees._
-/** Expand SAM closures that cannot be represented by the JVM to anonymous classes.
- * These fall into three categories
+/** Expand SAM closures that cannot be represented by the JVM as lambdas to anonymous classes.
+ * These fall into five categories
*
* 1. Partial function closures, we need to generate a isDefinedAt method for these.
- * 2. Closures implementaing non-trait classes.
- * 3. Closures that get synthesized abstract methods in the transformation pipeline. These methods can be
+ * 2. Closures implementing non-trait classes.
+ * 3. Closures implementing classes that inherit from a class other than Object
+ * (a lambda cannot not be a run-time subtype of such a class)
+ * 4. Closures that implement traits which run initialization code.
+ * 5. Closures that get synthesized abstract methods in the transformation pipeline. These methods can be
* (1) superaccessors, (2) outer references, (3) accessors for fields.
*/
class ExpandSAMs extends MiniPhaseTransform { thisTransformer =>
@@ -22,7 +26,13 @@ class ExpandSAMs extends MiniPhaseTransform { thisTransformer =>
import ast.tpd._
def noJvmSam(cls: ClassSymbol)(implicit ctx: Context): Boolean =
- !cls.is(Trait) || ExplicitOuter.needsOuterIfReferenced(cls) || cls.typeRef.fields.nonEmpty
+ !cls.is(Trait) ||
+ cls.superClass != defn.ObjectClass ||
+ !cls.is(NoInits) ||
+ !cls.directlyInheritedTraits.forall(_.is(NoInits)) ||
+ ExplicitOuter.needsOuterIfReferenced(cls) ||
+ cls.typeRef.fields.nonEmpty // Superaccessors already show up as abstract methods here, so no test necessary
+
override def transformBlock(tree: Block)(implicit ctx: Context, info: TransformerInfo): Tree = tree match {
case Block(stats @ (fn: DefDef) :: Nil, Closure(_, fnRef, tpt)) if fnRef.symbol == fn.symbol =>