summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/library/scala/concurrent/ConcurrentPackageObject.scala27
-rw-r--r--src/library/scala/concurrent/ExecutionContext.scala1
-rw-r--r--src/library/scala/concurrent/Future.scala81
-rw-r--r--src/library/scala/concurrent/Promise.scala17
-rw-r--r--src/library/scala/concurrent/impl/ExecutionContextImpl.scala1
-rw-r--r--src/library/scala/concurrent/impl/Future.scala9
-rw-r--r--src/library/scala/concurrent/impl/Promise.scala46
-rw-r--r--src/library/scala/util/Try.scala53
-rw-r--r--test/files/jvm/scala-concurrent-tck.scala80
9 files changed, 197 insertions, 118 deletions
diff --git a/src/library/scala/concurrent/ConcurrentPackageObject.scala b/src/library/scala/concurrent/ConcurrentPackageObject.scala
index f4744a8757..0f882540f2 100644
--- a/src/library/scala/concurrent/ConcurrentPackageObject.scala
+++ b/src/library/scala/concurrent/ConcurrentPackageObject.scala
@@ -8,11 +8,8 @@
package scala.concurrent
-
-
import java.util.concurrent.{ Executors, ExecutorService, ThreadFactory }
import scala.concurrent.forkjoin.{ ForkJoinPool, ForkJoinWorkerThread }
-import scala.util.{ Try, Success, Failure }
import scala.concurrent.util.Duration
import ConcurrentPackageObject._
@@ -40,16 +37,16 @@ abstract class ConcurrentPackageObject {
case _ => true
}
- private[concurrent] def resolve[T](source: Try[T]): Try[T] = source match {
- case Failure(t: scala.runtime.NonLocalReturnControl[_]) => Success(t.value.asInstanceOf[T])
- case Failure(t: scala.util.control.ControlThrowable) => Failure(new ExecutionException("Boxed ControlThrowable", t))
- case Failure(t: InterruptedException) => Failure(new ExecutionException("Boxed InterruptedException", t))
- case Failure(e: Error) => Failure(new ExecutionException("Boxed Error", e))
+ private[concurrent] def resolve[T](source: Either[Throwable, T]): Either[Throwable, T] = source match {
+ case Left(t: scala.runtime.NonLocalReturnControl[_]) => Right(t.value.asInstanceOf[T])
+ case Left(t: scala.util.control.ControlThrowable) => Left(new ExecutionException("Boxed ControlThrowable", t))
+ case Left(t: InterruptedException) => Left(new ExecutionException("Boxed InterruptedException", t))
+ case Left(e: Error) => Left(new ExecutionException("Boxed Error", e))
case _ => source
}
private[concurrent] def resolver[T] =
- resolverFunction.asInstanceOf[PartialFunction[Throwable, Try[T]]]
+ resolverFunction.asInstanceOf[PartialFunction[Throwable, Either[Throwable, T]]]
/* concurrency constructs */
@@ -104,11 +101,11 @@ private[concurrent] object ConcurrentPackageObject {
// compiling a subset of sources; it seems that the wildcard is not
// properly handled, and you get messages like "type _$1 defined twice".
// This is consistent with other package object breakdowns.
- private val resolverFunction: PartialFunction[Throwable, Try[_]] = {
- case t: scala.runtime.NonLocalReturnControl[_] => Success(t.value)
- case t: scala.util.control.ControlThrowable => Failure(new ExecutionException("Boxed ControlThrowable", t))
- case t: InterruptedException => Failure(new ExecutionException("Boxed InterruptedException", t))
- case e: Error => Failure(new ExecutionException("Boxed Error", e))
- case t => Failure(t)
+ private val resolverFunction: PartialFunction[Throwable, Either[Throwable, _]] = {
+ case t: scala.runtime.NonLocalReturnControl[_] => Right(t.value)
+ case t: scala.util.control.ControlThrowable => Left(new ExecutionException("Boxed ControlThrowable", t))
+ case t: InterruptedException => Left(new ExecutionException("Boxed InterruptedException", t))
+ case e: Error => Left(new ExecutionException("Boxed Error", e))
+ case t => Left(t)
}
}
diff --git a/src/library/scala/concurrent/ExecutionContext.scala b/src/library/scala/concurrent/ExecutionContext.scala
index f639f76dc9..16d9a1f980 100644
--- a/src/library/scala/concurrent/ExecutionContext.scala
+++ b/src/library/scala/concurrent/ExecutionContext.scala
@@ -13,7 +13,6 @@ package scala.concurrent
import java.util.concurrent.atomic.{ AtomicInteger }
import java.util.concurrent.{ Executors, Future => JFuture, Callable }
import scala.concurrent.util.Duration
-import scala.util.{ Try, Success, Failure }
import scala.concurrent.forkjoin.{ ForkJoinPool, RecursiveTask => FJTask, RecursiveAction, ForkJoinWorkerThread }
import scala.collection.generic.CanBuildFrom
import collection._
diff --git a/src/library/scala/concurrent/Future.scala b/src/library/scala/concurrent/Future.scala
index 8cecadc605..5f703ac23b 100644
--- a/src/library/scala/concurrent/Future.scala
+++ b/src/library/scala/concurrent/Future.scala
@@ -17,7 +17,6 @@ import java.util.{ LinkedList => JLinkedList }
import java.{ lang => jl }
import java.util.concurrent.atomic.{ AtomicReferenceFieldUpdater, AtomicInteger, AtomicBoolean }
-import scala.util.{ Try, Success, Failure }
import scala.concurrent.util.Duration
import scala.Option
@@ -97,8 +96,8 @@ self =>
* $multipleCallbacks
*/
def onSuccess[U](pf: PartialFunction[T, U]): this.type = onComplete {
- case Failure(t) => // do nothing
- case Success(v) => if (pf isDefinedAt v) pf(v) else { /*do nothing*/ }
+ case Left(t) => // do nothing
+ case Right(v) => if (pf isDefinedAt v) pf(v) else { /*do nothing*/ }
}
/** When this future is completed with a failure (i.e. with a throwable),
@@ -114,8 +113,8 @@ self =>
* $multipleCallbacks
*/
def onFailure[U](callback: PartialFunction[Throwable, U]): this.type = onComplete {
- case Failure(t) => if (isFutureThrowable(t) && callback.isDefinedAt(t)) callback(t) else { /*do nothing*/ }
- case Success(v) => // do nothing
+ case Left(t) => if (isFutureThrowable(t) && callback.isDefinedAt(t)) callback(t) else { /*do nothing*/ }
+ case Right(v) => // do nothing
}
/** When this future is completed, either through an exception, a timeout, or a value,
@@ -126,7 +125,7 @@ self =>
*
* $multipleCallbacks
*/
- def onComplete[U](func: Try[T] => U): this.type
+ def onComplete[U](func: Either[Throwable, T] => U): this.type
/* Miscellaneous */
@@ -151,7 +150,7 @@ self =>
* if it contains a valid result, or `Some(Failure(error))` if it contains
* an exception.
*/
- def value: Option[Try[T]]
+ def value: Option[Either[Throwable, T]]
/* Projections */
@@ -175,8 +174,8 @@ self =>
val p = newPromise[Throwable]
onComplete {
- case Failure(t) => p success t
- case Success(v) => p failure noSuchElem(v)
+ case Left(t) => p success t
+ case Right(v) => p failure noSuchElem(v)
}
p.future
@@ -190,8 +189,8 @@ self =>
* Will not be called if the future fails.
*/
def foreach[U](f: T => U): Unit = onComplete {
- case Success(r) => f(r)
- case Failure(_) => // do nothing
+ case Right(r) => f(r)
+ case Left(_) => // do nothing
}
/** Creates a new future by applying a function to the successful result of
@@ -204,8 +203,8 @@ self =>
val p = newPromise[S]
onComplete {
- case Failure(t) => p failure t
- case Success(v) =>
+ case Left(t) => p failure t
+ case Right(v) =>
try p success f(v)
catch {
case t => p complete resolver(t)
@@ -226,12 +225,12 @@ self =>
val p = newPromise[S]
onComplete {
- case Failure(t) => p failure t
- case Success(v) =>
+ case Left(t) => p failure t
+ case Right(v) =>
try {
f(v) onComplete {
- case Failure(t) => p failure t
- case Success(v) => p success v
+ case Left(t) => p failure t
+ case Right(v) => p success v
}
} catch {
case t: Throwable => p complete resolver(t)
@@ -261,8 +260,8 @@ self =>
val p = newPromise[T]
onComplete {
- case Failure(t) => p failure t
- case Success(v) =>
+ case Left(t) => p failure t
+ case Right(v) =>
try {
if (pred(v)) p success v
else p failure new NoSuchElementException("Future.filter predicate is not satisfied by: " + v)
@@ -310,8 +309,8 @@ self =>
val p = newPromise[S]
onComplete {
- case Failure(t) => p failure t
- case Success(v) =>
+ case Left(t) => p failure t
+ case Right(v) =>
try {
if (pf.isDefinedAt(v)) p success pf(v)
else p failure new NoSuchElementException("Future.collect partial function is not defined at: " + v)
@@ -339,7 +338,7 @@ self =>
val p = newPromise[U]
onComplete {
- case Failure(t) if pf isDefinedAt t =>
+ case Left(t) if pf isDefinedAt t =>
try { p success pf(t) }
catch { case t: Throwable => p complete resolver(t) }
case otherwise => p complete otherwise
@@ -365,7 +364,7 @@ self =>
val p = newPromise[U]
onComplete {
- case Failure(t) if pf isDefinedAt t =>
+ case Left(t) if pf isDefinedAt t =>
try {
p completeWith pf(t)
} catch {
@@ -389,8 +388,8 @@ self =>
val p = newPromise[(T, U)]
this onComplete {
- case Failure(t) => p failure t
- case Success(r) => that onSuccess {
+ case Left(t) => p failure t
+ case Right(r) => that onSuccess {
case r2 => p success ((r, r2))
}
}
@@ -420,11 +419,11 @@ self =>
val p = newPromise[U]
onComplete {
- case Failure(t) => that onComplete {
- case Failure(_) => p failure t
- case Success(v) => p success v
+ case Left(t) => that onComplete {
+ case Left(_) => p failure t
+ case Right(v) => p success v
}
- case Success(v) => p success v
+ case Right(v) => p success v
}
p.future
@@ -437,12 +436,12 @@ self =>
val p = newPromise[S]
onComplete {
- case l: Failure[_] => p complete l.asInstanceOf[Try[S]]
- case Success(t) =>
+ case l: Left[Throwable, _] => p complete l.asInstanceOf[Either[Throwable, S]]
+ case Right(t) =>
p complete (try {
- Success(impl.Future.boxedType(m.erasure).cast(t).asInstanceOf[S])
+ Right(impl.Future.boxedType(m.erasure).cast(t).asInstanceOf[S])
} catch {
- case e: ClassCastException => Failure(e)
+ case e: ClassCastException => Left(e)
})
}
@@ -472,7 +471,7 @@ self =>
* }
* }}}
*/
- def andThen[U](pf: PartialFunction[Try[T], U]): Future[T] = {
+ def andThen[U](pf: PartialFunction[Either[Throwable, T], U]): Future[T] = {
val p = newPromise[T]
onComplete {
@@ -500,9 +499,9 @@ self =>
def either[U >: T](that: Future[U]): Future[U] = {
val p = self.newPromise[U]
- val completePromise: PartialFunction[Try[U], _] = {
- case Failure(t) => p tryFailure t
- case Success(v) => p trySuccess v
+ val completePromise: PartialFunction[Either[Throwable, U], _] = {
+ case Left(t) => p tryFailure t
+ case Right(v) => p trySuccess v
}
self onComplete completePromise
@@ -541,7 +540,7 @@ object Future {
def firstCompletedOf[T](futures: Traversable[Future[T]])(implicit executor: ExecutionContext): Future[T] = {
val p = Promise[T]()
- val completeFirst: Try[T] => Unit = p tryComplete _
+ val completeFirst: Either[Throwable, T] => Unit = p tryComplete _
futures.foreach(_ onComplete completeFirst)
p.future
@@ -554,14 +553,14 @@ object Future {
else {
val result = Promise[Option[T]]()
val ref = new AtomicInteger(futures.size)
- val search: Try[T] => Unit = v => try {
+ val search: Either[Throwable, T] => Unit = v => try {
v match {
- case Success(r) => if (predicate(r)) result tryComplete Success(Some(r))
+ case Right(r) => if (predicate(r)) result tryComplete Right(Some(r))
case _ =>
}
} finally {
if (ref.decrementAndGet == 0)
- result tryComplete Success(None)
+ result tryComplete Right(None)
}
futures.foreach(_ onComplete search)
diff --git a/src/library/scala/concurrent/Promise.scala b/src/library/scala/concurrent/Promise.scala
index 61e21606e6..8f2bce5d1a 100644
--- a/src/library/scala/concurrent/Promise.scala
+++ b/src/library/scala/concurrent/Promise.scala
@@ -8,11 +8,6 @@
package scala.concurrent
-import scala.util.{ Try, Success, Failure }
-
-
-
-
/** Promise is an object which can be completed with a value or failed
* with an exception.
*
@@ -40,7 +35,7 @@ trait Promise[T] {
*
* $promiseCompletion
*/
- def complete(result:Try[T]): this.type = if (tryComplete(result)) this else throwCompleted
+ def complete(result: Either[Throwable, T]): this.type = if (tryComplete(result)) this else throwCompleted
/** Tries to complete the promise with either a value or the exception.
*
@@ -48,7 +43,7 @@ trait Promise[T] {
*
* @return If the promise has already been completed returns `false`, or `true` otherwise.
*/
- def tryComplete(result: Try[T]): Boolean
+ def tryComplete(result: Either[Throwable, T]): Boolean
/** Completes this promise with the specified future, once that future is completed.
*
@@ -75,7 +70,7 @@ trait Promise[T] {
*
* @return If the promise has already been completed returns `false`, or `true` otherwise.
*/
- def trySuccess(value: T): Boolean = tryComplete(Success(value))
+ def trySuccess(value: T): Boolean = tryComplete(Right(value))
/** Completes the promise with an exception.
*
@@ -93,7 +88,7 @@ trait Promise[T] {
*
* @return If the promise has already been completed returns `false`, or `true` otherwise.
*/
- def tryFailure(t: Throwable): Boolean = tryComplete(Failure(t))
+ def tryFailure(t: Throwable): Boolean = tryComplete(Left(t))
/** Wraps a `Throwable` in an `ExecutionException` if necessary. TODO replace with `resolver` from scala.concurrent
*
@@ -118,11 +113,11 @@ object Promise {
/** Creates an already completed Promise with the specified exception
*/
- def failed[T](exception: Throwable)(implicit executor: ExecutionContext): Promise[T] = new impl.Promise.KeptPromise[T](Failure(exception))
+ def failed[T](exception: Throwable)(implicit executor: ExecutionContext): Promise[T] = new impl.Promise.KeptPromise[T](Left(exception))
/** Creates an already completed Promise with the specified result
*/
- def successful[T](result: T)(implicit executor: ExecutionContext): Promise[T] = new impl.Promise.KeptPromise[T](Success(result))
+ def successful[T](result: T)(implicit executor: ExecutionContext): Promise[T] = new impl.Promise.KeptPromise[T](Right(result))
}
diff --git a/src/library/scala/concurrent/impl/ExecutionContextImpl.scala b/src/library/scala/concurrent/impl/ExecutionContextImpl.scala
index 2cfd6f22cd..9a94bfca4f 100644
--- a/src/library/scala/concurrent/impl/ExecutionContextImpl.scala
+++ b/src/library/scala/concurrent/impl/ExecutionContextImpl.scala
@@ -13,7 +13,6 @@ package scala.concurrent.impl
import java.util.concurrent.{Callable, ExecutorService, Executors, ThreadFactory}
import scala.concurrent.forkjoin._
import scala.concurrent.{ExecutionContext, resolver, Awaitable, body2awaitable}
-import scala.util.{ Try, Success, Failure }
import scala.concurrent.util.{ Duration }
diff --git a/src/library/scala/concurrent/impl/Future.scala b/src/library/scala/concurrent/impl/Future.scala
index 1111aa4753..615ab061a5 100644
--- a/src/library/scala/concurrent/impl/Future.scala
+++ b/src/library/scala/concurrent/impl/Future.scala
@@ -11,11 +11,8 @@ package scala.concurrent.impl
import scala.concurrent.{Awaitable, ExecutionContext}
-import scala.util.{ Try, Success, Failure }
import scala.collection.mutable.Stack
-
-
private[concurrent] trait Future[+T] extends scala.concurrent.Future[T] with Awaitable[T] {
implicit def executor: ExecutionContext
@@ -36,9 +33,9 @@ private[concurrent] trait Future[+T] extends scala.concurrent.Future[T] with Awa
* if it contains a valid result, or Some(Left(error)) if it contains
* an exception.
*/
- def value: Option[Try[T]]
+ def value: Option[Either[Throwable, T]]
- def onComplete[U](func: Try[T] => U): this.type
+ def onComplete[U](func: Either[Throwable, T] => U): this.type
}
@@ -67,7 +64,7 @@ object Future {
def run = {
promise complete {
try {
- Success(body)
+ Right(body)
} catch {
case e => scala.concurrent.resolver(e)
}
diff --git a/src/library/scala/concurrent/impl/Promise.scala b/src/library/scala/concurrent/impl/Promise.scala
index f05e306088..f7e073cb78 100644
--- a/src/library/scala/concurrent/impl/Promise.scala
+++ b/src/library/scala/concurrent/impl/Promise.scala
@@ -15,7 +15,6 @@ import java.util.concurrent.atomic.AtomicReferenceFieldUpdater
import scala.concurrent.{Awaitable, ExecutionContext, resolve, resolver, blocking, CanAwait, TimeoutException}
//import scala.util.continuations._
import scala.concurrent.util.Duration
-import scala.util.Try
import scala.util
import scala.annotation.tailrec
//import scala.concurrent.NonDeterministic
@@ -84,18 +83,18 @@ object Promise {
*
* [adriaan] it's unsound to make FState covariant (tryComplete won't type check)
*/
- sealed trait FState[T] { def value: Option[Try[T]] }
+ sealed trait FState[T] { def value: Option[Either[Throwable, T]] }
- case class Pending[T](listeners: List[Try[T] => Any] = Nil) extends FState[T] {
- def value: Option[Try[T]] = None
+ case class Pending[T](listeners: List[Either[Throwable, T] => Any] = Nil) extends FState[T] {
+ def value: Option[Either[Throwable, T]] = None
}
- case class Success[T](value: Option[util.Success[T]] = None) extends FState[T] {
- def result: T = value.get.get
+ case class Success[T](value: Option[Either[Throwable, T]] = None) extends FState[T] {
+ def result: T = value.get.right.get
}
- case class Failure[T](value: Option[util.Failure[T]] = None) extends FState[T] {
- def exception: Throwable = value.get.exception
+ case class Failure[T](value: Option[Either[Throwable, T]] = None) extends FState[T] {
+ def exception: Throwable = value.get.left.get
}
private val emptyPendingValue = Pending[Nothing](Nil)
@@ -136,11 +135,11 @@ object Promise {
def result(atMost: Duration)(implicit permit: CanAwait): T =
ready(atMost).value.get match {
- case util.Failure(e) => throw e
- case util.Success(r) => r
+ case Left(e) => throw e
+ case Right(r) => r
}
- def value: Option[Try[T]] = getState.value
+ def value: Option[Either[Throwable, T]] = getState.value
@inline
private[this] final def updater = AbstractPromise.updater.asInstanceOf[AtomicReferenceFieldUpdater[AbstractPromise, FState[T]]]
@@ -151,16 +150,16 @@ object Promise {
@inline
protected final def getState: FState[T] = updater.get(this)
- def tryComplete(value: Try[T]): Boolean = {
- val callbacks: List[Try[T] => Any] = {
+ def tryComplete(value: Either[Throwable, T]): Boolean = {
+ val callbacks: List[Either[Throwable, T] => Any] = {
try {
@tailrec
- def tryComplete(v: Try[T]): List[Try[T] => Any] = {
+ def tryComplete(v: Either[Throwable, T]): List[Either[Throwable, T] => Any] = {
getState match {
case cur @ Pending(listeners) =>
val newState =
- if (v.isFailure) Failure(Some(v.asInstanceOf[util.Failure[T]]))
- else Success(Some(v.asInstanceOf[util.Success[T]]))
+ if (v.isLeft) Failure(Some(v.asInstanceOf[Left[Throwable, T]]))
+ else Success(Some(v.asInstanceOf[Right[Throwable, T]]))
if (updateState(cur, newState)) listeners
else tryComplete(v)
@@ -184,7 +183,7 @@ object Promise {
}
}
- def onComplete[U](func: Try[T] => U): this.type = {
+ def onComplete[U](func: Either[Throwable, T] => U): this.type = {
@tailrec // Returns whether the future has already been completed or not
def tryAddCallback(): Boolean = {
val cur = getState
@@ -206,7 +205,7 @@ object Promise {
this
}
- private final def notifyCompleted(func: Try[T] => Any, result: Try[T]) {
+ private final def notifyCompleted(func: Either[Throwable, T] => Any, result: Either[Throwable, T]) {
try {
func(result)
} catch {
@@ -219,12 +218,13 @@ object Promise {
*
* Useful in Future-composition when a value to contribute is already available.
*/
- final class KeptPromise[T](suppliedValue: Try[T])(implicit val executor: ExecutionContext) extends Promise[T] {
+ final class KeptPromise[T](suppliedValue: Either[Throwable, T])(implicit val executor: ExecutionContext) extends Promise[T] {
+
val value = Some(resolve(suppliedValue))
- def tryComplete(value: Try[T]): Boolean = false
+ def tryComplete(value: Either[Throwable, T]): Boolean = false
- def onComplete[U](func: Try[T] => U): this.type = {
+ def onComplete[U](func: Either[Throwable, T] => U): this.type = {
val completedAs = value.get
Future.dispatchFuture(executor, {
() => func(completedAs)
@@ -235,8 +235,8 @@ object Promise {
def ready(atMost: Duration)(implicit permit: CanAwait): this.type = this
def result(atMost: Duration)(implicit permit: CanAwait): T = value.get match {
- case util.Failure(e) => throw e
- case util.Success(r) => r
+ case Left(e) => throw e
+ case Right(r) => r
}
}
diff --git a/src/library/scala/util/Try.scala b/src/library/scala/util/Try.scala
index c9bde81317..efa2fcabb8 100644
--- a/src/library/scala/util/Try.scala
+++ b/src/library/scala/util/Try.scala
@@ -101,9 +101,9 @@ sealed abstract class Try[+T] {
}
-final case class Failure[+T](val exception: Throwable) extends Try[T] {
- def isFailure = true
- def isSuccess = false
+final class Failure[+T](val exception: Throwable) extends Try[T] {
+ def isFailure: Boolean = true
+ def isSuccess: Boolean = false
def rescue[U >: T](rescueException: PartialFunction[Throwable, Try[U]]): Try[U] = {
try {
if (rescueException.isDefinedAt(exception)) rescueException(exception) else this
@@ -129,30 +129,49 @@ final case class Failure[+T](val exception: Throwable) extends Try[T] {
}
-final case class Success[+T](r: T) extends Try[T] {
- def isFailure = false
- def isSuccess = true
- def rescue[U >: T](rescueException: PartialFunction[Throwable, Try[U]]): Try[U] = Success(r)
- def get = r
+final class Success[+T](value: T) extends Try[T] {
+ def isFailure: Boolean = false
+ def isSuccess: Boolean = true
+ def rescue[U >: T](rescueException: PartialFunction[Throwable, Try[U]]): Try[U] = Success(value)
+ def get = value
def flatMap[U](f: T => Try[U]): Try[U] =
- try f(r)
+ try f(value)
catch {
case e => Failure(e)
}
- def flatten[U](implicit ev: T <:< Try[U]): Try[U] = r
- def foreach[U](f: T => U): Unit = f(r)
- def map[U](f: T => U): Try[U] = Try[U](f(r))
+ def flatten[U](implicit ev: T <:< Try[U]): Try[U] = value
+ def foreach[U](f: T => U): Unit = f(value)
+ def map[U](f: T => U): Try[U] = Try[U](f(value))
def collect[U](pf: PartialFunction[T, U]): Try[U] =
- if (pf isDefinedAt r) Success(pf(r))
- else Failure[U](new NoSuchElementException("Partial function not defined at " + r))
+ if (pf isDefinedAt value) Success(pf(value))
+ else Failure[U](new NoSuchElementException("Partial function not defined at " + value))
def filter(p: T => Boolean): Try[T] =
- if (p(r)) this
- else Failure(new NoSuchElementException("Predicate does not hold for " + r))
+ if (p(value)) this
+ else Failure(new NoSuchElementException("Predicate does not hold for " + value))
def recover[U >: T](rescueException: PartialFunction[Throwable, U]): Try[U] = this
- def exists(p: T => Boolean): Boolean = p(r)
+ def exists(p: T => Boolean): Boolean = p(value)
def failed: Try[Throwable] = Failure(new UnsupportedOperationException("Success.failed"))
}
+object Failure {
+ def apply[T](e: Throwable): Failure[T] = new Failure(e)
+ def unapply(scrutinizee: Any): Option[Throwable] = scrutinizee match {
+ case Right(_) => None
+ case Left(e) => Some(e.asInstanceOf[Throwable])
+ case s: Success[_] => None
+ case f: Failure[_] => Some(f.exception)
+ }
+}
+
+object Success {
+ def apply[T](value: T): Success[T] = new Success(value)
+ def unapply[T](scrutinizee: Any): Option[T] = scrutinizee match {
+ case Right(v) => Some(v.asInstanceOf[T])
+ case Left(_) => None
+ case s: Success[_] => Some(s.get.asInstanceOf[T])
+ case f: Failure[Throwable] => None
+ }
+}
object Try {
diff --git a/test/files/jvm/scala-concurrent-tck.scala b/test/files/jvm/scala-concurrent-tck.scala
index 75e2b92ff6..b3470d275d 100644
--- a/test/files/jvm/scala-concurrent-tck.scala
+++ b/test/files/jvm/scala-concurrent-tck.scala
@@ -1,6 +1,3 @@
-
-
-
import scala.concurrent.{
Future,
Promise,
@@ -398,6 +395,80 @@ trait Exceptions extends TestBase {
}
+trait TryEitherExtractor extends TestBase {
+
+ import scala.util.{Try, Success, Failure}
+
+ def testSuccessMatch(): Unit = once {
+ done =>
+ val thisIsASuccess = Success(42)
+ thisIsASuccess match {
+ case Success(v) =>
+ done()
+ assert(v == 42)
+ case Failure(e) =>
+ done()
+ assert(false)
+ case other =>
+ done()
+ assert(false)
+ }
+ }
+
+ def testRightMatch(): Unit = once {
+ done =>
+ val thisIsNotASuccess: Right[Throwable, Int] = Right(43)
+ thisIsNotASuccess match {
+ case Success(v) =>
+ done()
+ assert(v == 43)
+ case Failure(e) =>
+ done()
+ assert(false)
+ case other =>
+ done()
+ assert(false)
+ }
+ }
+
+ def testFailureMatch(): Unit = once {
+ done =>
+ val thisIsAFailure = Failure(new Exception("I'm an exception"))
+ thisIsAFailure match {
+ case Success(v) =>
+ done()
+ assert(false)
+ case Failure(e) =>
+ done()
+ assert(e.getMessage == "I'm an exception")
+ case other =>
+ done()
+ assert(false)
+ }
+ }
+
+ def testLeftMatch(): Unit = once {
+ done =>
+ val thisIsNotAFailure: Left[Throwable, Int] = Left(new Exception("I'm an exception"))
+ thisIsNotAFailure match {
+ case Success(v) =>
+ done()
+ assert(false)
+ case Failure(e) =>
+ done()
+ assert(e.getMessage == "I'm an exception")
+ case other =>
+ done()
+ assert(false)
+ }
+
+ }
+
+ testSuccessMatch()
+ testRightMatch()
+ testFailureMatch()
+ testLeftMatch()
+}
object Test
extends App
@@ -406,8 +477,11 @@ with FutureCombinators
with FutureProjections
with Promises
with Exceptions
+with TryEitherExtractor
{
System.exit(0)
}
+
+