@@ -5,15 +5,19 @@ import core._
5
5
import Contexts ._ , Symbols ._ , Types ._ , Flags ._ , Decorators ._ , StdNames ._ , Constants ._
6
6
import SymDenotations .SymDenotation
7
7
import TreeTransforms ._
8
+ import SymUtils ._
8
9
import ast .untpd
9
10
import ast .Trees ._
10
11
11
- /** Expand SAM closures that cannot be represented by the JVM to anonymous classes.
12
- * These fall into three categories
12
+ /** Expand SAM closures that cannot be represented by the JVM as lambdas to anonymous classes.
13
+ * These fall into five categories
13
14
*
14
15
* 1. Partial function closures, we need to generate a isDefinedAt method for these.
15
- * 2. Closures implementaing non-trait classes.
16
- * 3. Closures that get synthesized abstract methods in the transformation pipeline. These methods can be
16
+ * 2. Closures implementing non-trait classes.
17
+ * 3. Closures implementing classes that inherit from a class other than Object
18
+ * (a lambda cannot not be a run-time subtype of such a class)
19
+ * 4. Closures that implement traits which run initialization code.
20
+ * 5. Closures that get synthesized abstract methods in the transformation pipeline. These methods can be
17
21
* (1) superaccessors, (2) outer references, (3) accessors for fields.
18
22
*/
19
23
class ExpandSAMs extends MiniPhaseTransform { thisTransformer =>
@@ -22,7 +26,13 @@ class ExpandSAMs extends MiniPhaseTransform { thisTransformer =>
22
26
import ast .tpd ._
23
27
24
28
def noJvmSam (cls : ClassSymbol )(implicit ctx : Context ): Boolean =
25
- ! cls.is(Trait ) || ExplicitOuter .needsOuterIfReferenced(cls) || cls.typeRef.fields.nonEmpty
29
+ ! cls.is(Trait ) ||
30
+ cls.superClass != defn.ObjectClass ||
31
+ ! cls.is(NoInits ) ||
32
+ ! cls.directlyInheritedTraits.forall(_.is(NoInits )) ||
33
+ ExplicitOuter .needsOuterIfReferenced(cls) ||
34
+ cls.typeRef.fields.nonEmpty // Superaccessors already show up as abstract methods here, so no test necessary
35
+
26
36
27
37
override def transformBlock (tree : Block )(implicit ctx : Context , info : TransformerInfo ): Tree = tree match {
28
38
case Block (stats @ (fn : DefDef ) :: Nil , Closure (_, fnRef, tpt)) if fnRef.symbol == fn.symbol =>
0 commit comments