diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2014-03-27 14:39:39 +0100 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2014-03-27 14:52:00 +0100 |
commit | ee66e081ad0dec0e0c20fbb7e40fd20122bba238 (patch) | |
tree | 354938b6e0e3ab18bf89f7d8090456fb767f3509 /src/main/scala/scala/async/internal/AsyncTransform.scala | |
parent | 6808ce4a4023becd984ebe06805d1eeb844694e1 (diff) | |
download | scala-async-ee66e081ad0dec0e0c20fbb7e40fd20122bba238.tar.gz scala-async-ee66e081ad0dec0e0c20fbb7e40fd20122bba238.tar.bz2 scala-async-ee66e081ad0dec0e0c20fbb7e40fd20122bba238.zip |
[backport] Allow lazy vals without await in the initializer
We were incorrectly typechecking the `ClassDef` of the state machine
in the macro in a way that discarded the resulting trees, and only
kept around the symbol.
The led to the the macro engine retypechecking
that node, which somehow led to duplicated lazy val initiaializer
`DefDef`-s in the template, which manifest as a `VerifyError`.
This commit:
- rescues the typechecked `ClassDef` node from the eager
typechecking by the macro
- loosens the restriction on lazy vals in async blocks. They are
still prohibited if they contain an await on the RHS
- Adds a test that shows evalution is indeed lazy.
(cherry picked from commit cc4587b1985519f7049d0feb0783d8e22c10f792)
Conflicts:
src/main/scala/scala/async/internal/AsyncAnalysis.scala
src/main/scala/scala/async/internal/AsyncTransform.scala
Diffstat (limited to 'src/main/scala/scala/async/internal/AsyncTransform.scala')
-rw-r--r-- | src/main/scala/scala/async/internal/AsyncTransform.scala | 10 |
1 files changed, 7 insertions, 3 deletions
diff --git a/src/main/scala/scala/async/internal/AsyncTransform.scala b/src/main/scala/scala/async/internal/AsyncTransform.scala index ca53ff1..beb828d 100644 --- a/src/main/scala/scala/async/internal/AsyncTransform.scala +++ b/src/main/scala/scala/async/internal/AsyncTransform.scala @@ -52,11 +52,10 @@ trait AsyncTransform { } val tryToUnit = appliedType(definitions.FunctionClass(1), futureSystemOps.tryType[Any], typeOf[Unit]) - val template = Template(List(tryToUnit, typeOf[() => Unit]).map(TypeTree(_)), emptyValDef, body) + val template = Template(List(tryToUnit, typeOf[() => Unit]).map(TypeTree(_)), emptyValDef, body).setType(NoType) 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] + } } |