aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilipp Haller <hallerp@gmail.com>2014-03-27 16:06:51 +0100
committerPhilipp Haller <hallerp@gmail.com>2014-03-27 16:06:51 +0100
commit9b3bbe4e06994af25c11a4c9210915772171a9d9 (patch)
treec3962002aecdbd1f49799433e87450b99b95a045
parent6808ce4a4023becd984ebe06805d1eeb844694e1 (diff)
parentcf19f02966fc427be26404b7f8ddd5d05bfe3127 (diff)
downloadscala-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
-rw-r--r--src/main/scala/scala/async/internal/AsyncAnalysis.scala5
-rw-r--r--src/main/scala/scala/async/internal/AsyncTransform.scala8
-rw-r--r--src/test/scala/scala/async/neg/NakedAwait.scala4
-rw-r--r--src/test/scala/scala/async/run/lazyval/LazyValSpec.scala29
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
+ }
+}
+