diff options
author | Martin Odersky <odersky@gmail.com> | 2016-07-27 14:22:59 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2016-07-27 14:23:23 +0200 |
commit | 2e725908c3bd340daf140906885fdb43fba13a0f (patch) | |
tree | dbfa85317ade1dcf8db45a7f30b1b68a5d6f9ffc /src | |
parent | aa0bf126cee8c738e7dba2494ce62b70b9aefb1e (diff) | |
download | dotty-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).
Diffstat (limited to 'src')
-rw-r--r-- | src/dotty/tools/dotc/transform/ElimByName.scala | 3 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/LambdaLift.scala | 16 | ||||
-rw-r--r-- | src/strawman/collections/CollectionStrawMan6.scala | 10 |
3 files changed, 16 insertions, 13 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 |