aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2016-07-27 14:22:59 +0200
committerMartin Odersky <odersky@gmail.com>2016-07-27 14:23:23 +0200
commit2e725908c3bd340daf140906885fdb43fba13a0f (patch)
treedbfa85317ade1dcf8db45a7f30b1b68a5d6f9ffc
parentaa0bf126cee8c738e7dba2494ce62b70b9aefb1e (diff)
downloaddotty-2e725908c3bd340daf140906885fdb43fba13a0f.tar.gz
dotty-2e725908c3bd340daf140906885fdb43fba13a0f.tar.bz2
dotty-2e725908c3bd340daf140906885fdb43fba13a0f.zip
Fix problem related to cbn parameters in supercalls
The closures generated by elimByName did not get the InSuperCall flag set. This caused problems in lambda lift which led to a verify error for the new version CollectionStrawMan6. That version replaces explicit function parameters in class LazyList by by-name parameters. Also: Clarify logic for liftLocals in LambdaLift (liftLocals caused the immediate problem but was in the end not to blame).
-rw-r--r--src/dotty/tools/dotc/transform/ElimByName.scala3
-rw-r--r--src/dotty/tools/dotc/transform/LambdaLift.scala16
-rw-r--r--src/strawman/collections/CollectionStrawMan6.scala10
-rw-r--r--tests/run/colltest6/CollectionStrawMan6_1.scala10
4 files changed, 21 insertions, 18 deletions
diff --git a/src/dotty/tools/dotc/transform/ElimByName.scala b/src/dotty/tools/dotc/transform/ElimByName.scala
index b65a46249..192227261 100644
--- a/src/dotty/tools/dotc/transform/ElimByName.scala
+++ b/src/dotty/tools/dotc/transform/ElimByName.scala
@@ -77,8 +77,9 @@ class ElimByName extends MiniPhaseTransform with InfoTransformer { thisTransform
if qual.tpe.derivesFrom(defn.FunctionClass(0)) && isPureExpr(qual) =>
qual
case _ =>
+ val inSuper = if (ctx.mode.is(Mode.InSuperCall)) InSuperCall else EmptyFlags
val meth = ctx.newSymbol(
- ctx.owner, nme.ANON_FUN, Synthetic | Method, MethodType(Nil, Nil, argType))
+ ctx.owner, nme.ANON_FUN, Synthetic | Method | inSuper, MethodType(Nil, Nil, argType))
Closure(meth, _ => arg.changeOwner(ctx.owner, meth))
}
ref(defn.dummyApply).appliedToType(argType).appliedTo(argFun)
diff --git a/src/dotty/tools/dotc/transform/LambdaLift.scala b/src/dotty/tools/dotc/transform/LambdaLift.scala
index 5fbe0343f..18b030913 100644
--- a/src/dotty/tools/dotc/transform/LambdaLift.scala
+++ b/src/dotty/tools/dotc/transform/LambdaLift.scala
@@ -364,13 +364,15 @@ class LambdaLift extends MiniPhase with IdentityDenotTransformer { thisTransform
if (lOwner is Package) {
val encClass = local.enclosingClass
val topClass = local.topLevelClass
- // member of a static object
- if (encClass.isStatic && encClass.isProperlyContainedIn(topClass)) {
- // though the second condition seems weird, it's not true for symbols which are defined in some
- // weird combinations of super calls.
- (encClass, EmptyFlags)
- } else if (encClass.is(ModuleClass, butNot = Package) && encClass.isStatic) // needed to not cause deadlocks in classloader. see t5375.scala
- (encClass, EmptyFlags)
+ val preferEncClass =
+ encClass.isStatic &&
+ // non-static classes can capture owners, so should be avoided
+ (encClass.isProperlyContainedIn(topClass) ||
+ // can be false for symbols which are defined in some weird combination of supercalls.
+ encClass.is(ModuleClass, butNot = Package)
+ // needed to not cause deadlocks in classloader. see t5375.scala
+ )
+ if (preferEncClass) (encClass, EmptyFlags)
else (topClass, JavaStatic)
}
else (lOwner, EmptyFlags)
diff --git a/src/strawman/collections/CollectionStrawMan6.scala b/src/strawman/collections/CollectionStrawMan6.scala
index f4d5e006b..5889782d6 100644
--- a/src/strawman/collections/CollectionStrawMan6.scala
+++ b/src/strawman/collections/CollectionStrawMan6.scala
@@ -562,14 +562,14 @@ object CollectionStrawMan6 extends LowPriority {
override def className = "ArrayBufferView"
}
- class LazyList[+A](expr: () => LazyList.Evaluated[A])
+ class LazyList[+A](expr: => LazyList.Evaluated[A])
extends LinearSeq[A] with SeqLike[A, LazyList] { self =>
private[this] var evaluated = false
private[this] var result: LazyList.Evaluated[A] = _
def force: LazyList.Evaluated[A] = {
if (!evaluated) {
- result = expr()
+ result = expr
evaluated = true
}
result
@@ -579,7 +579,7 @@ object CollectionStrawMan6 extends LowPriority {
override def head = force.get._1
override def tail = force.get._2
- def #:: [B >: A](elem: => B): LazyList[B] = new LazyList(() => Some((elem, self)))
+ def #:: [B >: A](elem: => B): LazyList[B] = new LazyList(Some((elem, self)))
def fromIterable[B](c: Iterable[B]): LazyList[B] = LazyList.fromIterable(c)
@@ -600,10 +600,10 @@ object CollectionStrawMan6 extends LowPriority {
def fromIterable[B](coll: Iterable[B]): LazyList[B] = coll match {
case coll: LazyList[B] => coll
- case _ => new LazyList(() => if (coll.isEmpty) None else Some((coll.head, fromIterable(coll.tail))))
+ case _ => new LazyList(if (coll.isEmpty) None else Some((coll.head, fromIterable(coll.tail))))
}
- object Empty extends LazyList[Nothing](() => None)
+ object Empty extends LazyList[Nothing](None)
object #:: {
def unapply[A](s: LazyList[A]): Evaluated[A] = s.force
diff --git a/tests/run/colltest6/CollectionStrawMan6_1.scala b/tests/run/colltest6/CollectionStrawMan6_1.scala
index f4d5e006b..5889782d6 100644
--- a/tests/run/colltest6/CollectionStrawMan6_1.scala
+++ b/tests/run/colltest6/CollectionStrawMan6_1.scala
@@ -562,14 +562,14 @@ object CollectionStrawMan6 extends LowPriority {
override def className = "ArrayBufferView"
}
- class LazyList[+A](expr: () => LazyList.Evaluated[A])
+ class LazyList[+A](expr: => LazyList.Evaluated[A])
extends LinearSeq[A] with SeqLike[A, LazyList] { self =>
private[this] var evaluated = false
private[this] var result: LazyList.Evaluated[A] = _
def force: LazyList.Evaluated[A] = {
if (!evaluated) {
- result = expr()
+ result = expr
evaluated = true
}
result
@@ -579,7 +579,7 @@ object CollectionStrawMan6 extends LowPriority {
override def head = force.get._1
override def tail = force.get._2
- def #:: [B >: A](elem: => B): LazyList[B] = new LazyList(() => Some((elem, self)))
+ def #:: [B >: A](elem: => B): LazyList[B] = new LazyList(Some((elem, self)))
def fromIterable[B](c: Iterable[B]): LazyList[B] = LazyList.fromIterable(c)
@@ -600,10 +600,10 @@ object CollectionStrawMan6 extends LowPriority {
def fromIterable[B](coll: Iterable[B]): LazyList[B] = coll match {
case coll: LazyList[B] => coll
- case _ => new LazyList(() => if (coll.isEmpty) None else Some((coll.head, fromIterable(coll.tail))))
+ case _ => new LazyList(if (coll.isEmpty) None else Some((coll.head, fromIterable(coll.tail))))
}
- object Empty extends LazyList[Nothing](() => None)
+ object Empty extends LazyList[Nothing](None)
object #:: {
def unapply[A](s: LazyList[A]): Evaluated[A] = s.force