aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2014-03-12 10:36:36 +0100
committerJason Zaugg <jzaugg@gmail.com>2014-03-12 10:36:36 +0100
commit6f6546ebfc26564843621e79d840209a5103d3c8 (patch)
tree6b81b4c1da5f79bf930508e49abb0e8c1e495057
parent6ced55dceca6b92b30cafc145c952345c87708c3 (diff)
downloadscala-async-6f6546ebfc26564843621e79d840209a5103d3c8.tar.gz
scala-async-6f6546ebfc26564843621e79d840209a5103d3c8.tar.bz2
scala-async-6f6546ebfc26564843621e79d840209a5103d3c8.zip
Fix "not a class" crasher in live variable analysis
Predicate the `asClass` cast with an `isClass` check. Fixes #63
-rw-r--r--src/main/scala/scala/async/internal/LiveVariables.scala3
-rw-r--r--src/test/scala/scala/async/run/toughtype/ToughType.scala28
2 files changed, 30 insertions, 1 deletions
diff --git a/src/main/scala/scala/async/internal/LiveVariables.scala b/src/main/scala/scala/async/internal/LiveVariables.scala
index 6c67e99..7f386c8 100644
--- a/src/main/scala/scala/async/internal/LiveVariables.scala
+++ b/src/main/scala/scala/async/internal/LiveVariables.scala
@@ -55,7 +55,8 @@ trait LiveVariables {
// determine which fields should be live also at the end (will not be nulled out)
val noNull: Set[Symbol] = liftedSyms.filter { sym =>
- tpe(sym).typeSymbol.asClass.isPrimitive || liftables.exists { tree =>
+ val typeSym = tpe(sym).typeSymbol
+ (typeSym.isClass && typeSym.asClass.isPrimitive) || liftables.exists { tree =>
!liftedSyms.contains(tree.symbol) && tree.exists(_.symbol == sym)
}
}
diff --git a/src/test/scala/scala/async/run/toughtype/ToughType.scala b/src/test/scala/scala/async/run/toughtype/ToughType.scala
index 6159f7b..458157c 100644
--- a/src/test/scala/scala/async/run/toughtype/ToughType.scala
+++ b/src/test/scala/scala/async/run/toughtype/ToughType.scala
@@ -184,6 +184,34 @@ class ToughTypeSpec {
}
Bippy
}
+
+ @Test
+ def ticket63(): Unit = {
+ import scala.async.Async._
+ import scala.concurrent.{ ExecutionContext, Future }
+
+ object SomeExecutionContext extends ExecutionContext {
+ def reportFailure(t: Throwable): Unit = ???
+ def execute(runnable: Runnable): Unit = ???
+ }
+
+ trait FunDep[W, S, R] {
+ def method(w: W, s: S): Future[R]
+ }
+
+ object FunDep {
+ implicit def `Something to do with List`[W, S, R](implicit funDep: FunDep[W, S, R]) =
+ new FunDep[W, List[S], W] {
+ def method(w: W, l: List[S]) = async {
+ val it = l.iterator
+ while (it.hasNext) {
+ await(funDep.method(w, it.next()))
+ }
+ w
+ }(SomeExecutionContext)
+ }
+ }
+ }
}
trait A