summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@typesafe.com>2016-03-29 19:25:06 -0700
committerAdriaan Moors <adriaan.moors@typesafe.com>2016-03-29 23:09:39 -0700
commit62d97d7f110894a0c2f36b1ed9dd7ad59c0115fa (patch)
tree084f8abe0d8dea5165e03289870dc8d6adeea6bc
parent63f017586f31de11bc6004dca7cea0c26ceb5ff5 (diff)
downloadscala-62d97d7f110894a0c2f36b1ed9dd7ad59c0115fa.tar.gz
scala-62d97d7f110894a0c2f36b1ed9dd7ad59c0115fa.tar.bz2
scala-62d97d7f110894a0c2f36b1ed9dd7ad59c0115fa.zip
LMF cannot run trait's "initializer" (constructor)
Thus, rule out traits that have a constructor (which we use as a proxy for having potentially side-effecting statements), and create an anonymous subclass for them at compile time.
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala4
-rw-r--r--test/files/run/sammy_restrictions_LMF.check2
-rw-r--r--test/files/run/sammy_restrictions_LMF.scala8
3 files changed, 13 insertions, 1 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index cdf3e18b5a..ebb55afca9 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -1213,6 +1213,10 @@ abstract class Erasure extends AddInterfaces
// When we delay sam expansion until after explicit outer & lambda lift, we could decide there whether
// to expand sam at compile time or use LMF, and this implementation restriction could be lifted.
sym.isStatic &&
+ // HACK: this is to rule out traits with an effectful initializer.
+ // The constructor only exists if the trait's template has statements.
+ // Sadly, we can't be more precise without access to the tree that defines the SAM's owner.
+ !sym.primaryConstructor.exists &&
(sym.isInterface || sym.info.decls.forall(mem => mem.isMethod || mem.isType)) // TODO OPT: && {sym setFlag INTERFACE; true})
// we still need to check our ancestors even if the INTERFACE flag is set, as it doesn't take inheritance into account
diff --git a/test/files/run/sammy_restrictions_LMF.check b/test/files/run/sammy_restrictions_LMF.check
new file mode 100644
index 0000000000..6ed281c757
--- /dev/null
+++ b/test/files/run/sammy_restrictions_LMF.check
@@ -0,0 +1,2 @@
+1
+1
diff --git a/test/files/run/sammy_restrictions_LMF.scala b/test/files/run/sammy_restrictions_LMF.scala
index 40bb234a72..27a3d21dad 100644
--- a/test/files/run/sammy_restrictions_LMF.scala
+++ b/test/files/run/sammy_restrictions_LMF.scala
@@ -3,6 +3,11 @@ trait TInt extends T[Int]
trait TWithVal { val x: Any = 1; def apply(x: Int): String }
+trait TImpure { def apply(x: Int): String ; println(1) }
+
+trait Println { println(1) }
+trait TImpureSuper extends Println { def apply(x: Int): String }
+
object Test extends App {
final val AnonFunClass = "$anonfun$"
final val LMFClass = "$$Lambda$" // LambdaMetaFactory names classes like this
@@ -38,5 +43,6 @@ object Test extends App {
notLMF(fVal)
assert(fVal.x == 1)
-
+ notLMF((x => "a"): TImpure)
+ notLMF((x => "a"): TImpureSuper)
}