diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2015-10-23 16:25:02 +1000 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2016-01-19 14:27:31 +1000 |
commit | 549a656fa22af5f7f0c5e89dd6e0a19ed4b604f5 (patch) | |
tree | 7a7c778a24143923a674acb9db30ecdc5e3f8f5e /src/main/scala/scala/async/internal/TransformUtils.scala | |
parent | 634c454dbd546e2f3db6321b4047b3cebd2f899a (diff) | |
download | scala-async-549a656fa22af5f7f0c5e89dd6e0a19ed4b604f5.tar.gz scala-async-549a656fa22af5f7f0c5e89dd6e0a19ed4b604f5.tar.bz2 scala-async-549a656fa22af5f7f0c5e89dd6e0a19ed4b604f5.zip |
Various fixes to late expansion
- Detect cross-state symbol references where the RefTree is nested
in a LabelDef. Failure to do so led to ill-scoped local variable
references which sometimes manifest as VerifyErrors.
- Emit a default case in the Match intended to be a tableswitch.
We have to do this ourselves if we expand after pattern matcher
- Cleanup generated code to avoid redundant blocks
- Avoid unnecessary `matchRes` temporary variable for unit-typed
pattern matches
- Fix the trace level logging in the ANF transform to restore
indented output.
- Emit `{ state = nextState; ... }` rather than
`try { ... } finally { state = nextState }` in state handlers.
This simplifies generated code and has the same meaning, as the
code in the state machine isn't reentrant and can't observe the
"early" transition of the state.
Diffstat (limited to 'src/main/scala/scala/async/internal/TransformUtils.scala')
-rw-r--r-- | src/main/scala/scala/async/internal/TransformUtils.scala | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/src/main/scala/scala/async/internal/TransformUtils.scala b/src/main/scala/scala/async/internal/TransformUtils.scala index e15ef1b..2999be2 100644 --- a/src/main/scala/scala/async/internal/TransformUtils.scala +++ b/src/main/scala/scala/async/internal/TransformUtils.scala @@ -167,8 +167,8 @@ private[async] trait TransformUtils { val NonFatalClass = rootMirror.staticModule("scala.util.control.NonFatal") val ThrowableClass = rootMirror.staticClass("java.lang.Throwable") - val Async_async = asyncBase.asyncMethod(c.universe)(c.macroApplication.symbol).ensuring(_ != NoSymbol) - val Async_await = asyncBase.awaitMethod(c.universe)(c.macroApplication.symbol).ensuring(_ != NoSymbol) + lazy val Async_async = asyncBase.asyncMethod(c.universe)(c.macroApplication.symbol) + lazy val Async_await = asyncBase.awaitMethod(c.universe)(c.macroApplication.symbol) val IllegalStateExceptionClass = rootMirror.staticClass("java.lang.IllegalStateException") } @@ -190,6 +190,10 @@ private[async] trait TransformUtils { val LABEL = 1L << 17 // not in the public reflection API. (internal.flags(sym).asInstanceOf[Long] & LABEL) != 0L } + def isSynth(sym: Symbol): Boolean = { + val SYNTHETIC = 1 << 21 // not in the public reflection API. + (internal.flags(sym).asInstanceOf[Long] & SYNTHETIC) != 0L + } def symId(sym: Symbol): Int = { val symtab = this.c.universe.asInstanceOf[reflect.internal.SymbolTable] sym.asInstanceOf[symtab.Symbol].id @@ -388,7 +392,7 @@ private[async] trait TransformUtils { catch { case _: ScalaReflectionException => NoSymbol } } final def uncheckedBounds(tp: Type): Type = { - if (tp.typeArgs.isEmpty || UncheckedBoundsClass == NoSymbol) tp + if ((tp.typeArgs.isEmpty && (tp match { case _: TypeRef => true; case _ => false}))|| UncheckedBoundsClass == NoSymbol) tp else withAnnotation(tp, Annotation(UncheckedBoundsClass.asType.toType, Nil, ListMap())) } // ===================================== @@ -402,6 +406,8 @@ private[async] trait TransformUtils { * in search of a sub tree that was decorated with the cached answer. */ final def containsAwaitCached(t: Tree): Tree => Boolean = { + if (c.macroApplication.symbol == null) return (t => false) + def treeCannotContainAwait(t: Tree) = t match { case _: Ident | _: TypeTree | _: Literal => true case _ => isAsync(t) |