diff options
author | Philipp Haller <hallerp@gmail.com> | 2014-03-27 16:06:51 +0100 |
---|---|---|
committer | Philipp Haller <hallerp@gmail.com> | 2014-03-27 16:06:51 +0100 |
commit | 9b3bbe4e06994af25c11a4c9210915772171a9d9 (patch) | |
tree | c3962002aecdbd1f49799433e87450b99b95a045 | |
parent | 6808ce4a4023becd984ebe06805d1eeb844694e1 (diff) | |
parent | cf19f02966fc427be26404b7f8ddd5d05bfe3127 (diff) | |
download | scala-async-9b3bbe4e06994af25c11a4c9210915772171a9d9.tar.gz scala-async-9b3bbe4e06994af25c11a4c9210915772171a9d9.tar.bz2 scala-async-9b3bbe4e06994af25c11a4c9210915772171a9d9.zip |
Merge pull request #69 from retronym/backport/ticket/52-lazy-val
[backport] Allow lazy vals without await in the initializer
4 files changed, 39 insertions, 7 deletions
diff --git a/src/main/scala/scala/async/internal/AsyncAnalysis.scala b/src/main/scala/scala/async/internal/AsyncAnalysis.scala index 76c2dba..15ddf48 100644 --- a/src/main/scala/scala/async/internal/AsyncAnalysis.scala +++ b/src/main/scala/scala/async/internal/AsyncAnalysis.scala @@ -60,9 +60,8 @@ trait AsyncAnalysis { super.traverse(tree) case Return(_) => abort(tree.pos, "return is illegal within a async block") - case ValDef(mods, _, _, _) if mods.hasFlag(Flag.LAZY) => - // TODO lift this restriction - abort(tree.pos, "lazy vals are illegal within an async block") + case DefDef(mods, _, _, _, _, _) if mods.hasFlag(Flag.LAZY) && containsAwait => + 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 ca53ff1..c8d2234 100644 --- a/src/main/scala/scala/async/internal/AsyncTransform.scala +++ b/src/main/scala/scala/async/internal/AsyncTransform.scala @@ -55,8 +55,7 @@ trait AsyncTransform { val template = Template(List(tryToUnit, typeOf[() => Unit]).map(TypeTree(_)), emptyValDef, body) val t = ClassDef(NoMods, name.stateMachineT, Nil, template) - callSiteTyper.typedPos(macroPos)(Block(t :: Nil, Literal(Constant(())))) - t + typecheckClassDef(t) } val stateMachineClass = stateMachine.symbol @@ -218,4 +217,9 @@ trait AsyncTransform { } result } + + def typecheckClassDef(cd: ClassDef): ClassDef = { + val Block(cd1 :: Nil, _) = callSiteTyper.typedPos(macroPos)(Block(cd :: Nil, Literal(Constant(())))) + cd1.asInstanceOf[ClassDef] + } } diff --git a/src/test/scala/scala/async/neg/NakedAwait.scala b/src/test/scala/scala/async/neg/NakedAwait.scala index 9778c72..2af691f 100644 --- a/src/test/scala/scala/async/neg/NakedAwait.scala +++ b/src/test/scala/scala/async/neg/NakedAwait.scala @@ -163,10 +163,10 @@ class NakedAwait { @Test def lazyValIllegal() { - expectError("lazy vals are illegal") { + expectError("await must not be used under a lazy val initializer") { """ | import _root_.scala.async.internal.AsyncId._ - | def foo(): Any = async { val x = { lazy val y = 0; y } } + | def foo(): Any = async { val x = { lazy val y = await(0); y } } | () | |""".stripMargin diff --git a/src/test/scala/scala/async/run/lazyval/LazyValSpec.scala b/src/test/scala/scala/async/run/lazyval/LazyValSpec.scala new file mode 100644 index 0000000..701d5d6 --- /dev/null +++ b/src/test/scala/scala/async/run/lazyval/LazyValSpec.scala @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2012-2014 Typesafe Inc. <http://www.typesafe.com> + */ + +package scala.async +package run +package lazyval + +import org.junit.Test +import scala.async.internal.AsyncId._ + +class LazyValSpec { + @Test + def lazyValAllowed() { + val result = async { + var x = 0 + lazy val y = { x += 1; 42 } + assert(x == 0, x) + val z = await(1) + val result = y + x + assert(x == 1, x) + identity(y) + assert(x == 1, x) + result + } + result mustBe 43 + } +} + |