From 6bf20ee474afa46564899e9f57065ad1f22fabed Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Thu, 8 Sep 2016 15:23:22 +1000 Subject: [PATCH 1/2] Compatibility with Scala 2.12.0-RC1 - method local lazy vals are now encoded as a single ValDef rather than a ValDef + DefDef pair. We need to treat ValDef-s with the LAZY flag in the same way as we used to treat the DefDef. - Rename one of the symbols `ANF,anf` in the same scope to avoid generating anonymous class names that differ only in case. The compiler warned about this one. - When patching the LabelDefs to have a `Unit` result type, propagate this other LabelDefs conclude with a jump to that label. Not sure why, but without this we now hit an error in the backend about the nonsensical attempt to emit a coercion from void to int. - Use crossScalaVersions in the build and update the Scala versions tested in CI. --- .travis.yml | 9 +++++++-- build.sbt | 4 +++- .../scala/scala/async/internal/AnfTransform.scala | 6 +++--- .../scala/scala/async/internal/AsyncAnalysis.scala | 2 ++ .../scala/scala/async/internal/AsyncTransform.scala | 11 +++++++---- src/main/scala/scala/async/internal/Lifter.scala | 5 +++-- .../scala/scala/async/internal/TransformUtils.scala | 8 ++++++++ .../scala/async/run/live/LiveVariablesSpec.scala | 1 - 8 files changed, 33 insertions(+), 13 deletions(-) diff --git a/.travis.yml b/.travis.yml index 93bfda8b..0943677f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,10 +11,15 @@ env: script: - admin/build.sh scala: - - 2.11.4 + - 2.11.8 + - 2.12.0-RC1 jdk: - openjdk6 - - openjdk7 + - oraclejdk8 +matrix: + exclude: + - scala: 2.12.0-RC1 + jdk: openjdk6 notifications: email: - jason.zaugg@typesafe.com diff --git a/build.sbt b/build.sbt index 9759fe9e..a26fec74 100644 --- a/build.sbt +++ b/build.sbt @@ -1,4 +1,6 @@ -scalaVersion := "2.11.6" +crossScalaVersions := List("2.11.8", "2.12.0-RC1") + +scalaVersion := crossScalaVersions.value.head // Uncomment to test with a locally built copy of Scala. // scalaHome := Some(file("/code/scala2/build/pack")) diff --git a/src/main/scala/scala/async/internal/AnfTransform.scala b/src/main/scala/scala/async/internal/AnfTransform.scala index dc10a953..3d14fb7e 100644 --- a/src/main/scala/scala/async/internal/AnfTransform.scala +++ b/src/main/scala/scala/async/internal/AnfTransform.scala @@ -68,7 +68,7 @@ private[async] trait AnfTransform { def transformToBlock(tree: Tree): Block = listToBlock(transformToList(tree)) def _transformToList(tree: Tree): List[Tree] = trace(tree) { - val stats :+ expr = anf.transformToList(tree) + val stats :+ expr = _anf.transformToList(tree) def statsExprUnit = stats :+ expr :+ api.typecheck(atPos(expr.pos)(Literal(Constant(())))) def statsExprThrow = @@ -163,7 +163,7 @@ private[async] trait AnfTransform { internal.valDef(sym, internal.changeOwner(lhs, api.currentOwner, sym)).setType(NoType).setPos(pos) } - object anf { + object _anf { def transformToList(tree: Tree): List[Tree] = { mode = Anf; blockToList(api.recur(tree)) } @@ -385,7 +385,7 @@ private[async] trait AnfTransform { def anfLinearize(tree: Tree): Block = { val trees: List[Tree] = mode match { - case Anf => anf._transformToList(tree) + case Anf => _anf._transformToList(tree) case Linearizing => linearize._transformToList(tree) } listToBlock(trees) diff --git a/src/main/scala/scala/async/internal/AsyncAnalysis.scala b/src/main/scala/scala/async/internal/AsyncAnalysis.scala index 6b754930..bd64f17c 100644 --- a/src/main/scala/scala/async/internal/AsyncAnalysis.scala +++ b/src/main/scala/scala/async/internal/AsyncAnalysis.scala @@ -62,6 +62,8 @@ trait AsyncAnalysis { c.abort(tree.pos, "return is illegal within a async block") case DefDef(mods, _, _, _, _, _) if mods.hasFlag(Flag.LAZY) && containsAwait(tree) => reportUnsupportedAwait(tree, "lazy val initializer") + case ValDef(mods, _, _, _) if mods.hasFlag(Flag.LAZY) && containsAwait(tree) => + reportUnsupportedAwait(tree, "lazy val initializer") case CaseDef(_, guard, _) if guard exists isAwait => // TODO lift this restriction reportUnsupportedAwait(tree, "pattern guard") diff --git a/src/main/scala/scala/async/internal/AsyncTransform.scala b/src/main/scala/scala/async/internal/AsyncTransform.scala index 2f450341..feb1ea71 100644 --- a/src/main/scala/scala/async/internal/AsyncTransform.scala +++ b/src/main/scala/scala/async/internal/AsyncTransform.scala @@ -159,10 +159,13 @@ trait AsyncTransform { case ValDef(_, _, _, rhs) if liftedSyms(tree.symbol) => api.atOwner(api.currentOwner) { val fieldSym = tree.symbol - val lhs = atPos(tree.pos) { - gen.mkAttributedStableRef(thisType(fieldSym.owner.asClass), fieldSym) + if (fieldSym.asTerm.isLazy) Literal(Constant(())) + else { + val lhs = atPos(tree.pos) { + gen.mkAttributedStableRef(thisType(fieldSym.owner.asClass), fieldSym) + } + treeCopy.Assign(tree, lhs, api.recur(rhs)).setType(definitions.UnitTpe).changeOwner(fieldSym, api.currentOwner) } - treeCopy.Assign(tree, lhs, api.recur(rhs)).setType(definitions.UnitTpe).changeOwner(fieldSym, api.currentOwner) } case _: DefTree if liftedSyms(tree.symbol) => EmptyTree @@ -176,7 +179,7 @@ trait AsyncTransform { } val liftablesUseFields = liftables.map { - case vd: ValDef => vd + case vd: ValDef if !vd.symbol.asTerm.isLazy => vd case x => typingTransform(x, stateMachineClass)(useFields) } diff --git a/src/main/scala/scala/async/internal/Lifter.scala b/src/main/scala/scala/async/internal/Lifter.scala index 9481f691..3afe6d6a 100644 --- a/src/main/scala/scala/async/internal/Lifter.scala +++ b/src/main/scala/scala/async/internal/Lifter.scala @@ -92,7 +92,7 @@ trait Lifter { // Only mark transitive references of defs, modules and classes. The RHS of lifted vals/vars // stays in its original location, so things that it refers to need not be lifted. - if (!(sym.isTerm && (sym.asTerm.isVal || sym.asTerm.isVar))) + if (!(sym.isTerm && !sym.asTerm.isLazy && (sym.asTerm.isVal || sym.asTerm.isVar))) defSymToReferenced(sym).foreach(sym2 => markForLift(sym2)) } } @@ -117,7 +117,8 @@ trait Lifter { sym.setFlag(MUTABLE | STABLE | PRIVATE | LOCAL) sym.setName(name.fresh(sym.name.toTermName)) sym.setInfo(deconst(sym.info)) - treeCopy.ValDef(vd, Modifiers(sym.flags), sym.name, TypeTree(tpe(sym)).setPos(t.pos), EmptyTree) + val rhs1 = if (sym.asTerm.isLazy) rhs else EmptyTree + treeCopy.ValDef(vd, Modifiers(sym.flags), sym.name, TypeTree(tpe(sym)).setPos(t.pos), rhs1) case dd@DefDef(_, _, tparams, vparamss, tpt, rhs) => sym.setName(this.name.fresh(sym.name.toTermName)) sym.setFlag(PRIVATE | LOCAL) diff --git a/src/main/scala/scala/async/internal/TransformUtils.scala b/src/main/scala/scala/async/internal/TransformUtils.scala index 2999be28..8b94513f 100644 --- a/src/main/scala/scala/async/internal/TransformUtils.scala +++ b/src/main/scala/scala/async/internal/TransformUtils.scala @@ -479,6 +479,14 @@ private[async] trait TransformUtils { typingTransform(t, owner) { (tree, api) => tree match { + case LabelDef(name, params, rhs) => + val rhs1 = api.recur(rhs) + if (rhs1.tpe =:= UnitTpe) { + internal.setInfo(tree.symbol, internal.methodType(tree.symbol.info.paramLists.head, UnitTpe)) + treeCopy.LabelDef(tree, name, params, rhs1) + } else { + treeCopy.LabelDef(tree, name, params, rhs1) + } case Block(stats, expr) => val stats1 = stats map api.recur val expr1 = api.recur(expr) diff --git a/src/test/scala/scala/async/run/live/LiveVariablesSpec.scala b/src/test/scala/scala/async/run/live/LiveVariablesSpec.scala index 01cf9111..af236aa9 100644 --- a/src/test/scala/scala/async/run/live/LiveVariablesSpec.scala +++ b/src/test/scala/scala/async/run/live/LiveVariablesSpec.scala @@ -266,7 +266,6 @@ class LiveVariablesSpec { // https://github.com/scala/async/issues/104 @Test def dontNullOutVarsOfTypeNothing_t104(): Unit = { - implicit val ec: scala.concurrent.ExecutionContext = null import scala.async.Async._ import scala.concurrent.duration.Duration import scala.concurrent.{Await, Future} From c15c45292b1cb858b32e3967d53126c9cc36f41b Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Thu, 8 Sep 2016 15:51:01 +1000 Subject: [PATCH 2/2] Add maintainence warning in .travis.yml --- .travis.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0943677f..df51411d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,13 +12,14 @@ script: - admin/build.sh scala: - 2.11.8 - - 2.12.0-RC1 + - 2.12.0-RC1 # !!! Duplicated below, edit with care jdk: - openjdk6 - oraclejdk8 matrix: exclude: - - scala: 2.12.0-RC1 + + - scala: 2.12.0-RC1 # !!! Duplicated above, edit with care jdk: openjdk6 notifications: email: