aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2013-08-23 09:51:42 -0700
committerJason Zaugg <jzaugg@gmail.com>2013-08-23 09:51:42 -0700
commit0cb09c24985a063ea150c967485ac379ae4e231a (patch)
tree4c7a148b90559a3dd77cdcc3ce7dca933e25a984
parent94d7413f8514a695cfc8681ce532fe1f39e71681 (diff)
parent98e2f26000aaaf5abb527f776426c4759b95cde8 (diff)
downloadscala-async-0cb09c24985a063ea150c967485ac379ae4e231a.tar.gz
scala-async-0cb09c24985a063ea150c967485ac379ae4e231a.tar.bz2
scala-async-0cb09c24985a063ea150c967485ac379ae4e231a.zip
Merge pull request #30 from retronym/topic/unchecked-bounds
Use @uncheckedBounds to avoid introducing refchecks errors …
-rw-r--r--build.sbt27
-rw-r--r--project/build.properties2
-rw-r--r--src/main/scala/scala/async/internal/AnfTransform.scala6
-rw-r--r--src/main/scala/scala/async/internal/AsyncId.scala2
-rw-r--r--src/main/scala/scala/async/internal/AsyncTransform.scala11
-rw-r--r--src/main/scala/scala/async/internal/ExprBuilder.scala8
-rw-r--r--src/main/scala/scala/async/internal/TransformUtils.scala13
-rw-r--r--src/test/scala/scala/async/TreeInterrogation.scala3
-rw-r--r--src/test/scala/scala/async/neg/LocalClasses0Spec.scala3
-rw-r--r--src/test/scala/scala/async/neg/NakedAwait.scala3
-rw-r--r--src/test/scala/scala/async/neg/SampleNegSpec.scala3
-rw-r--r--src/test/scala/scala/async/run/anf/AnfTransformSpec.scala3
-rw-r--r--src/test/scala/scala/async/run/await0/Await0Spec.scala3
-rw-r--r--src/test/scala/scala/async/run/block0/AsyncSpec.scala3
-rw-r--r--src/test/scala/scala/async/run/block1/block1.scala3
-rw-r--r--src/test/scala/scala/async/run/cps/CPSSpec.scala3
-rw-r--r--src/test/scala/scala/async/run/exceptions/ExceptionsSpec.scala3
-rw-r--r--src/test/scala/scala/async/run/futures/FutureSpec.scala3
-rw-r--r--src/test/scala/scala/async/run/hygiene/Hygiene.scala3
-rw-r--r--src/test/scala/scala/async/run/ifelse0/IfElse0.scala3
-rw-r--r--src/test/scala/scala/async/run/ifelse0/WhileSpec.scala3
-rw-r--r--src/test/scala/scala/async/run/ifelse1/IfElse1.scala3
-rw-r--r--src/test/scala/scala/async/run/ifelse2/ifelse2.scala3
-rw-r--r--src/test/scala/scala/async/run/ifelse3/IfElse3.scala3
-rw-r--r--src/test/scala/scala/async/run/match0/Match0.scala3
-rw-r--r--src/test/scala/scala/async/run/nesteddef/NestedDef.scala3
-rw-r--r--src/test/scala/scala/async/run/noawait/NoAwaitSpec.scala3
-rw-r--r--src/test/scala/scala/async/run/toughtype/ToughType.scala12
-rw-r--r--src/test/scala/scala/async/run/uncheckedBounds/UncheckedBoundsSpec.scala57
29 files changed, 115 insertions, 83 deletions
diff --git a/build.sbt b/build.sbt
index d6dc3bb..a013bb2 100644
--- a/build.sbt
+++ b/build.sbt
@@ -1,7 +1,10 @@
-scalaVersion := "2.10.2"
+scalaVersion := "2.10.3-RC1"
organization := "org.typesafe.async" // TODO new org name under scala-lang.
+// Uncomment to test with a locally built copy of Scala.
+// scalaHome := Some(file("/code/scala2/build/pack"))
+
name := "scala-async"
version := "1.0.0-SNAPSHOT"
@@ -15,7 +18,7 @@ libraryDependencies <++= (scalaVersion) {
libraryDependencies += "junit" % "junit-dep" % "4.10" % "test"
-libraryDependencies += "com.novocode" % "junit-interface" % "0.10-M2" % "test"
+libraryDependencies += "com.novocode" % "junit-interface" % "0.10" % "test"
testOptions += Tests.Argument(TestFrameworks.JUnit, "-q", "-v", "-s")
@@ -23,10 +26,22 @@ parallelExecution in Global := false
autoCompilerPlugins := true
-libraryDependencies <<= (scalaVersion, libraryDependencies) {
- (ver, deps) =>
- deps :+ compilerPlugin("org.scala-lang.plugins" % "continuations" % ver)
-}
+scalacOptions ++= (scalaHome.value match {
+ case Some(sh) =>
+ // Use continuations plugin from the local scala instance
+ val continuationsJar = sh / "misc" / "scala-devel" / "plugins" / "continuations.jar"
+ ("-Xplugin:" + continuationsJar.getAbsolutePath) :: Nil
+ case None =>
+ Nil
+})
+
+libraryDependencies ++= (scalaHome.value match {
+ case Some(sh) =>
+ Nil
+ case None =>
+ // Use continuations plugin from the published artifact.
+ compilerPlugin("org.scala-lang.plugins" % "continuations" % scalaVersion.value) :: Nil
+})
scalacOptions += "-P:continuations:enable"
diff --git a/project/build.properties b/project/build.properties
index 5e96e96..87d87d8 100644
--- a/project/build.properties
+++ b/project/build.properties
@@ -1 +1 @@
-sbt.version=0.12.4
+sbt.version=0.13.0-RC5
diff --git a/src/main/scala/scala/async/internal/AnfTransform.scala b/src/main/scala/scala/async/internal/AnfTransform.scala
index 1452c4c..d513499 100644
--- a/src/main/scala/scala/async/internal/AnfTransform.scala
+++ b/src/main/scala/scala/async/internal/AnfTransform.scala
@@ -119,8 +119,8 @@ private[async] trait AnfTransform {
}
private def defineVar(prefix: String, tp: Type, pos: Position): ValDef = {
- val sym = currOwner.newTermSymbol(name.fresh(prefix), pos, MUTABLE | SYNTHETIC).setInfo(tp)
- ValDef(sym, gen.mkZero(tp)).setType(NoType).setPos(pos)
+ val sym = currOwner.newTermSymbol(name.fresh(prefix), pos, MUTABLE | SYNTHETIC).setInfo(uncheckedBounds(tp))
+ ValDef(sym, gen.mkZero(uncheckedBounds(tp))).setType(NoType).setPos(pos)
}
}
@@ -145,7 +145,7 @@ private[async] trait AnfTransform {
}
private def defineVal(prefix: String, lhs: Tree, pos: Position): ValDef = {
- val sym = currOwner.newTermSymbol(name.fresh(prefix), pos, SYNTHETIC).setInfo(lhs.tpe)
+ val sym = currOwner.newTermSymbol(name.fresh(prefix), pos, SYNTHETIC).setInfo(uncheckedBounds(lhs.tpe))
changeOwner(lhs, currentOwner, sym)
ValDef(sym, changeOwner(lhs, currentOwner, sym)).setType(NoType).setPos(pos)
}
diff --git a/src/main/scala/scala/async/internal/AsyncId.scala b/src/main/scala/scala/async/internal/AsyncId.scala
index 4334088..b9d82e2 100644
--- a/src/main/scala/scala/async/internal/AsyncId.scala
+++ b/src/main/scala/scala/async/internal/AsyncId.scala
@@ -41,7 +41,7 @@ object IdentityFutureSystem extends FutureSystem {
def execContextType: Type = weakTypeOf[Unit]
def createProm[A: WeakTypeTag]: Expr[Prom[A]] = reify {
- new Prom()
+ new Prom[A]()
}
def promiseToFuture[A: WeakTypeTag](prom: Expr[Prom[A]]) = reify {
diff --git a/src/main/scala/scala/async/internal/AsyncTransform.scala b/src/main/scala/scala/async/internal/AsyncTransform.scala
index c755c87..78a0876 100644
--- a/src/main/scala/scala/async/internal/AsyncTransform.scala
+++ b/src/main/scala/scala/async/internal/AsyncTransform.scala
@@ -6,7 +6,12 @@ trait AsyncTransform {
import global._
def asyncTransform[T](body: Tree, execContext: Tree, cpsFallbackEnabled: Boolean)
- (implicit resultType: WeakTypeTag[T]): Tree = {
+ (resultType: WeakTypeTag[T]): Tree = {
+
+ // We annotate the type of the whole expression as `T @uncheckedBounds` so as not to introduce
+ // warnings about non-conformant LUBs. See SI-7694
+ // This implicit propatages the annotated type in the type tag.
+ implicit val uncheckedBoundsResultTag: WeakTypeTag[T] = WeakTypeTag[T](rootMirror, FixedMirrorTypeCreator(rootMirror, uncheckedBounds(resultType.tpe)))
reportUnsupportedAwaits(body, report = !cpsFallbackEnabled)
@@ -22,12 +27,12 @@ trait AsyncTransform {
DefDef(NoMods, name.apply, Nil, applyVParamss, TypeTree(definitions.UnitTpe), Literal(Constant(())))
}
- val stateMachineType = applied("scala.async.StateMachine", List(futureSystemOps.promType[T], futureSystemOps.execContextType))
+ val stateMachineType = applied("scala.async.StateMachine", List(futureSystemOps.promType[T](uncheckedBoundsResultTag), futureSystemOps.execContextType))
val stateMachine: ClassDef = {
val body: List[Tree] = {
val stateVar = ValDef(Modifiers(Flag.MUTABLE | Flag.PRIVATE | Flag.LOCAL), name.state, TypeTree(definitions.IntTpe), Literal(Constant(0)))
- val result = ValDef(NoMods, name.result, TypeTree(futureSystemOps.promType[T]), futureSystemOps.createProm[T].tree)
+ val result = ValDef(NoMods, name.result, TypeTree(futureSystemOps.promType[T](uncheckedBoundsResultTag)), futureSystemOps.createProm[T](uncheckedBoundsResultTag).tree)
val execContextValDef = ValDef(NoMods, name.execContext, TypeTree(), execContext)
val apply0DefDef: DefDef = {
diff --git a/src/main/scala/scala/async/internal/ExprBuilder.scala b/src/main/scala/scala/async/internal/ExprBuilder.scala
index 3627eeb..3bde51a 100644
--- a/src/main/scala/scala/async/internal/ExprBuilder.scala
+++ b/src/main/scala/scala/async/internal/ExprBuilder.scala
@@ -283,7 +283,7 @@ trait ExprBuilder {
def onCompleteHandler[T: WeakTypeTag]: Tree
- def resumeFunTree[T]: DefDef
+ def resumeFunTree[T: WeakTypeTag]: DefDef
}
case class SymLookup(stateMachineClass: Symbol, applyTrParam: Symbol) {
@@ -303,12 +303,12 @@ trait ExprBuilder {
new AsyncBlock {
def asyncStates = blockBuilder.asyncStates.toList
- def mkCombinedHandlerCases[T]: List[CaseDef] = {
+ def mkCombinedHandlerCases[T: WeakTypeTag]: List[CaseDef] = {
val caseForLastState: CaseDef = {
val lastState = asyncStates.last
val lastStateBody = Expr[T](lastState.body)
val rhs = futureSystemOps.completeProm(
- Expr[futureSystem.Prom[T]](symLookup.memberRef(name.result)), reify(scala.util.Success(lastStateBody.splice)))
+ Expr[futureSystem.Prom[T]](symLookup.memberRef(name.result)), reify(scala.util.Success[T](lastStateBody.splice)))
mkHandlerCase(lastState.state, rhs.tree)
}
asyncStates.toList match {
@@ -337,7 +337,7 @@ trait ExprBuilder {
* }
* }
*/
- def resumeFunTree[T]: DefDef =
+ def resumeFunTree[T: WeakTypeTag]: DefDef =
DefDef(Modifiers(), name.resume, Nil, List(Nil), Ident(definitions.UnitClass),
Try(
Match(symLookup.memberRef(name.state), mkCombinedHandlerCases[T]),
diff --git a/src/main/scala/scala/async/internal/TransformUtils.scala b/src/main/scala/scala/async/internal/TransformUtils.scala
index 70237bc..663ca45 100644
--- a/src/main/scala/scala/async/internal/TransformUtils.scala
+++ b/src/main/scala/scala/async/internal/TransformUtils.scala
@@ -244,8 +244,19 @@ private[async] trait TransformUtils {
// Attributed version of `TreeGen#mkCastPreservingAnnotations`
def mkAttributedCastPreservingAnnotations(tree: Tree, tp: Type): Tree = {
atPos(tree.pos) {
- val casted = gen.mkAttributedCast(tree, tp.withoutAnnotations.dealias)
+ val casted = gen.mkAttributedCast(tree, uncheckedBounds(tp.withoutAnnotations).dealias)
Typed(casted, TypeTree(tp)).setType(tp)
}
}
+
+ // =====================================
+ // Copy/Pasted from Scala 2.10.3. See SI-7694.
+ private lazy val UncheckedBoundsClass = {
+ global.rootMirror.getClassIfDefined("scala.reflect.internal.annotations.uncheckedBounds")
+ }
+ final def uncheckedBounds(tp: Type): Type = {
+ if (tp.typeArgs.isEmpty || UncheckedBoundsClass == NoSymbol) tp
+ else tp.withAnnotation(AnnotationInfo marker UncheckedBoundsClass.tpe)
+ }
+ // =====================================
}
diff --git a/src/test/scala/scala/async/TreeInterrogation.scala b/src/test/scala/scala/async/TreeInterrogation.scala
index a3d2c67..524e1a2 100644
--- a/src/test/scala/scala/async/TreeInterrogation.scala
+++ b/src/test/scala/scala/async/TreeInterrogation.scala
@@ -4,14 +4,11 @@
package scala.async
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import org.junit.Test
import scala.async.internal.AsyncId
import AsyncId._
import tools.reflect.ToolBox
-@RunWith(classOf[JUnit4])
class TreeInterrogation {
@Test
def `a minimal set of vals are lifted to vars`() {
diff --git a/src/test/scala/scala/async/neg/LocalClasses0Spec.scala b/src/test/scala/scala/async/neg/LocalClasses0Spec.scala
index 6ebc9ca..ae346a2 100644
--- a/src/test/scala/scala/async/neg/LocalClasses0Spec.scala
+++ b/src/test/scala/scala/async/neg/LocalClasses0Spec.scala
@@ -5,12 +5,9 @@
package scala.async
package neg
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import org.junit.Test
import scala.async.internal.AsyncId
-@RunWith(classOf[JUnit4])
class LocalClasses0Spec {
@Test
def localClassCrashIssue16() {
diff --git a/src/test/scala/scala/async/neg/NakedAwait.scala b/src/test/scala/scala/async/neg/NakedAwait.scala
index ba388c5..deac069 100644
--- a/src/test/scala/scala/async/neg/NakedAwait.scala
+++ b/src/test/scala/scala/async/neg/NakedAwait.scala
@@ -5,11 +5,8 @@
package scala.async
package neg
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import org.junit.Test
-@RunWith(classOf[JUnit4])
class NakedAwait {
@Test
def `await only allowed in async neg`() {
diff --git a/src/test/scala/scala/async/neg/SampleNegSpec.scala b/src/test/scala/scala/async/neg/SampleNegSpec.scala
index 76f9c3e..e57dae9 100644
--- a/src/test/scala/scala/async/neg/SampleNegSpec.scala
+++ b/src/test/scala/scala/async/neg/SampleNegSpec.scala
@@ -5,11 +5,8 @@
package scala.async
package neg
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import org.junit.Test
-@RunWith(classOf[JUnit4])
class SampleNegSpec {
@Test
def `missing symbol`() {
diff --git a/src/test/scala/scala/async/run/anf/AnfTransformSpec.scala b/src/test/scala/scala/async/run/anf/AnfTransformSpec.scala
index c8cec28..728f33b 100644
--- a/src/test/scala/scala/async/run/anf/AnfTransformSpec.scala
+++ b/src/test/scala/scala/async/run/anf/AnfTransformSpec.scala
@@ -11,8 +11,6 @@ import scala.concurrent.{Future, ExecutionContext, future, Await}
import scala.concurrent.duration._
import scala.async.Async.{async, await}
import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import scala.async.internal.AsyncId
@@ -70,7 +68,6 @@ object State {
@volatile var result: Int = 0
}
-@RunWith(classOf[JUnit4])
class AnfTransformSpec {
@Test
diff --git a/src/test/scala/scala/async/run/await0/Await0Spec.scala b/src/test/scala/scala/async/run/await0/Await0Spec.scala
index 111602a..2adaa09 100644
--- a/src/test/scala/scala/async/run/await0/Await0Spec.scala
+++ b/src/test/scala/scala/async/run/await0/Await0Spec.scala
@@ -15,8 +15,6 @@ import language.{reflectiveCalls, postfixOps}
import scala.concurrent.{Future, ExecutionContext, future, Await}
import scala.concurrent.duration._
import scala.async.Async.{async, await}
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import org.junit.Test
class Await0Class {
@@ -63,7 +61,6 @@ class Await0Class {
}
}
-@RunWith(classOf[JUnit4])
class Await0Spec {
@Test
diff --git a/src/test/scala/scala/async/run/block0/AsyncSpec.scala b/src/test/scala/scala/async/run/block0/AsyncSpec.scala
index 5f38086..677cce8 100644
--- a/src/test/scala/scala/async/run/block0/AsyncSpec.scala
+++ b/src/test/scala/scala/async/run/block0/AsyncSpec.scala
@@ -11,8 +11,6 @@ import scala.concurrent.{Future, ExecutionContext, future, Await}
import scala.concurrent.duration._
import scala.async.Async.{async, await}
import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
class Test1Class {
@@ -39,7 +37,6 @@ class Test1Class {
}
-@RunWith(classOf[JUnit4])
class AsyncSpec {
@Test
diff --git a/src/test/scala/scala/async/run/block1/block1.scala b/src/test/scala/scala/async/run/block1/block1.scala
index bf9b56f..f42b073 100644
--- a/src/test/scala/scala/async/run/block1/block1.scala
+++ b/src/test/scala/scala/async/run/block1/block1.scala
@@ -11,8 +11,6 @@ import scala.concurrent.{Future, ExecutionContext, future, Await}
import scala.concurrent.duration._
import scala.async.Async.{async, await}
import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
class Test1Class {
@@ -32,7 +30,6 @@ class Test1Class {
}
}
-@RunWith(classOf[JUnit4])
class Block1Spec {
@Test def `support a simple await`() {
diff --git a/src/test/scala/scala/async/run/cps/CPSSpec.scala b/src/test/scala/scala/async/run/cps/CPSSpec.scala
index b56c6ad..9476b22 100644
--- a/src/test/scala/scala/async/run/cps/CPSSpec.scala
+++ b/src/test/scala/scala/async/run/cps/CPSSpec.scala
@@ -11,11 +11,8 @@ import scala.concurrent.duration._
import scala.async.continuations.CPSBasedAsync._
import scala.util.continuations._
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import org.junit.Test
-@RunWith(classOf[JUnit4])
class CPSSpec {
import ExecutionContext.Implicits.global
diff --git a/src/test/scala/scala/async/run/exceptions/ExceptionsSpec.scala b/src/test/scala/scala/async/run/exceptions/ExceptionsSpec.scala
index 733ea01..b417dd6 100644
--- a/src/test/scala/scala/async/run/exceptions/ExceptionsSpec.scala
+++ b/src/test/scala/scala/async/run/exceptions/ExceptionsSpec.scala
@@ -14,10 +14,7 @@ import scala.concurrent.duration._
import scala.reflect.ClassTag
import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
-@RunWith(classOf[JUnit4])
class ExceptionsSpec {
@Test
diff --git a/src/test/scala/scala/async/run/futures/FutureSpec.scala b/src/test/scala/scala/async/run/futures/FutureSpec.scala
index 01c8620..491b43f 100644
--- a/src/test/scala/scala/async/run/futures/FutureSpec.scala
+++ b/src/test/scala/scala/async/run/futures/FutureSpec.scala
@@ -18,10 +18,7 @@ import scala.util.{Try,Success,Failure}
import scala.async.Async.{async, await}
import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
-@RunWith(classOf[JUnit4])
class FutureSpec {
/* some utils */
diff --git a/src/test/scala/scala/async/run/hygiene/Hygiene.scala b/src/test/scala/scala/async/run/hygiene/Hygiene.scala
index 8081ee7..f11d21e 100644
--- a/src/test/scala/scala/async/run/hygiene/Hygiene.scala
+++ b/src/test/scala/scala/async/run/hygiene/Hygiene.scala
@@ -7,11 +7,8 @@ package run
package hygiene
import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import scala.async.internal.AsyncId
-@RunWith(classOf[JUnit4])
class HygieneSpec {
import AsyncId.{async, await}
diff --git a/src/test/scala/scala/async/run/ifelse0/IfElse0.scala b/src/test/scala/scala/async/run/ifelse0/IfElse0.scala
index fc438a1..4a86d82 100644
--- a/src/test/scala/scala/async/run/ifelse0/IfElse0.scala
+++ b/src/test/scala/scala/async/run/ifelse0/IfElse0.scala
@@ -10,8 +10,6 @@ import language.{reflectiveCalls, postfixOps}
import scala.concurrent.{Future, ExecutionContext, future, Await}
import scala.concurrent.duration._
import scala.async.Async.{async, await}
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import org.junit.Test
import scala.async.internal.AsyncId
@@ -39,7 +37,6 @@ class TestIfElseClass {
}
-@RunWith(classOf[JUnit4])
class IfElseSpec {
@Test def `support await in a simple if-else expression`() {
diff --git a/src/test/scala/scala/async/run/ifelse0/WhileSpec.scala b/src/test/scala/scala/async/run/ifelse0/WhileSpec.scala
index b8d88fb..666c373 100644
--- a/src/test/scala/scala/async/run/ifelse0/WhileSpec.scala
+++ b/src/test/scala/scala/async/run/ifelse0/WhileSpec.scala
@@ -6,12 +6,9 @@ package scala.async
package run
package ifelse0
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import org.junit.Test
import scala.async.internal.AsyncId
-@RunWith(classOf[JUnit4])
class WhileSpec {
@Test
diff --git a/src/test/scala/scala/async/run/ifelse1/IfElse1.scala b/src/test/scala/scala/async/run/ifelse1/IfElse1.scala
index b567ee6..41b81a4 100644
--- a/src/test/scala/scala/async/run/ifelse1/IfElse1.scala
+++ b/src/test/scala/scala/async/run/ifelse1/IfElse1.scala
@@ -10,8 +10,6 @@ import language.{reflectiveCalls, postfixOps}
import scala.concurrent.{Future, ExecutionContext, future, Await}
import scala.concurrent.duration._
import scala.async.Async.{async, await}
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import org.junit.Test
@@ -91,7 +89,6 @@ class TestIfElse1Class {
}
}
-@RunWith(classOf[JUnit4])
class IfElse1Spec {
@Test
diff --git a/src/test/scala/scala/async/run/ifelse2/ifelse2.scala b/src/test/scala/scala/async/run/ifelse2/ifelse2.scala
index 92a76e4..3fc4d3b 100644
--- a/src/test/scala/scala/async/run/ifelse2/ifelse2.scala
+++ b/src/test/scala/scala/async/run/ifelse2/ifelse2.scala
@@ -10,8 +10,6 @@ import language.{reflectiveCalls, postfixOps}
import scala.concurrent.{Future, ExecutionContext, future, Await}
import scala.concurrent.duration._
import scala.async.Async.{async, await}
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import org.junit.Test
@@ -37,7 +35,6 @@ class TestIfElse2Class {
}
}
-@RunWith(classOf[JUnit4])
class IfElse2Spec {
@Test
diff --git a/src/test/scala/scala/async/run/ifelse3/IfElse3.scala b/src/test/scala/scala/async/run/ifelse3/IfElse3.scala
index 8a2ab13..8e6e1bb 100644
--- a/src/test/scala/scala/async/run/ifelse3/IfElse3.scala
+++ b/src/test/scala/scala/async/run/ifelse3/IfElse3.scala
@@ -10,8 +10,6 @@ import language.{reflectiveCalls, postfixOps}
import scala.concurrent.{Future, ExecutionContext, future, Await}
import scala.concurrent.duration._
import scala.async.Async.{async, await}
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import org.junit.Test
@@ -40,7 +38,6 @@ class TestIfElse3Class {
}
-@RunWith(classOf[JUnit4])
class IfElse3Spec {
@Test
diff --git a/src/test/scala/scala/async/run/match0/Match0.scala b/src/test/scala/scala/async/run/match0/Match0.scala
index 7c392ab..418275e 100644
--- a/src/test/scala/scala/async/run/match0/Match0.scala
+++ b/src/test/scala/scala/async/run/match0/Match0.scala
@@ -10,8 +10,6 @@ import language.{reflectiveCalls, postfixOps}
import scala.concurrent.{Future, ExecutionContext, future, Await}
import scala.concurrent.duration._
import scala.async.Async.{async, await}
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import org.junit.Test
import scala.async.internal.AsyncId
@@ -54,7 +52,6 @@ class TestMatchClass {
}
-@RunWith(classOf[JUnit4])
class MatchSpec {
@Test def `support await in a simple match expression`() {
diff --git a/src/test/scala/scala/async/run/nesteddef/NestedDef.scala b/src/test/scala/scala/async/run/nesteddef/NestedDef.scala
index 409f70a..69e741d 100644
--- a/src/test/scala/scala/async/run/nesteddef/NestedDef.scala
+++ b/src/test/scala/scala/async/run/nesteddef/NestedDef.scala
@@ -2,12 +2,9 @@ package scala.async
package run
package nesteddef
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import org.junit.Test
import scala.async.internal.AsyncId
-@RunWith(classOf[JUnit4])
class NestedDef {
@Test
diff --git a/src/test/scala/scala/async/run/noawait/NoAwaitSpec.scala b/src/test/scala/scala/async/run/noawait/NoAwaitSpec.scala
index ba9c9be..0adb506 100644
--- a/src/test/scala/scala/async/run/noawait/NoAwaitSpec.scala
+++ b/src/test/scala/scala/async/run/noawait/NoAwaitSpec.scala
@@ -9,10 +9,7 @@ package noawait
import scala.async.internal.AsyncId
import AsyncId._
import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
-@RunWith(classOf[JUnit4])
class NoAwaitSpec {
@Test
def `async block without await`() {
diff --git a/src/test/scala/scala/async/run/toughtype/ToughType.scala b/src/test/scala/scala/async/run/toughtype/ToughType.scala
index ec2278f..b342a00 100644
--- a/src/test/scala/scala/async/run/toughtype/ToughType.scala
+++ b/src/test/scala/scala/async/run/toughtype/ToughType.scala
@@ -10,9 +10,7 @@ import language.{reflectiveCalls, postfixOps}
import scala.concurrent._
import scala.concurrent.duration._
import scala.async.Async._
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
+import org.junit.{Assert, Test}
import scala.async.internal.AsyncId
@@ -29,7 +27,6 @@ object ToughTypeObject {
}
}
-@RunWith(classOf[JUnit4])
class ToughTypeSpec {
@Test def `propogates tough types`() {
@@ -139,3 +136,10 @@ class ToughTypeSpec {
foo
}
}
+
+trait A
+trait B
+
+trait L[A2, B2 <: A2] {
+ def bar(a: Any, b: Any) = 0
+}
diff --git a/src/test/scala/scala/async/run/uncheckedBounds/UncheckedBoundsSpec.scala b/src/test/scala/scala/async/run/uncheckedBounds/UncheckedBoundsSpec.scala
new file mode 100644
index 0000000..5eb1f32
--- /dev/null
+++ b/src/test/scala/scala/async/run/uncheckedBounds/UncheckedBoundsSpec.scala
@@ -0,0 +1,57 @@
+package scala.async
+package run
+package uncheckedBounds
+
+import org.junit.{Test, Assert}
+import scala.async.TreeInterrogation
+
+class UncheckedBoundsSpec {
+ @Test def insufficientLub_SI_7694() {
+ suppressingFailureBefore2_10_3 {
+ eval( s"""
+ object Test {
+ import _root_.scala.async.run.toughtype._
+ import _root_.scala.async.internal.AsyncId.{async, await}
+ async {
+ (if (true) await(null: L[A, A]) else await(null: L[B, B]))
+ }
+ }
+ """, compileOptions = s"-cp ${toolboxClasspath} ")
+ }
+ }
+
+ @Test def insufficientLub_SI_7694_ScalaConcurrent() {
+ suppressingFailureBefore2_10_3 {
+ eval( s"""
+ object Test {
+ import _root_.scala.async.run.toughtype._
+ import _root_.scala.async.Async.{async, await}
+ import scala.concurrent._
+ import scala.concurrent.ExecutionContext.Implicits.global
+ async {
+ (if (true) await(null: Future[L[A, A]]) else await(null: Future[L[B, B]]))
+ }
+ }
+ """, compileOptions = s"-cp ${toolboxClasspath} ")
+ }
+ }
+
+ private def suppressingFailureBefore2_10_3(body: => Any) {
+ try {
+ body
+ } catch {
+ case x: Throwable =>
+ // @uncheckedBounds was only introduced in 2.10.3/ 2.11.0-M5, so avoid reporting this test failure in those cases.
+ scala.util.Properties.versionNumberString match {
+ case "2.10.0" | "2.10.1" | "2.10.2" | "2.11.0-M4" => // ignore, the @uncheckedBounds doesn't exist yet
+ case _ =>
+ val annotationExists =
+ reflect.runtime.currentMirror.staticClass("scala.reflect.internal.annotations.uncheckedBounds") == reflect.runtime.universe.NoSymbol
+ if (annotationExists)
+ Assert.fail("@uncheckedBounds not found in scala-reflect.jar")
+ else
+ Assert.fail(s"@uncheckedBounds exists, but it didn't prevent this failure: $x")
+ }
+ }
+ }
+}