Closed
Description
I have an implementation of FutureSystem nearly complete to connect scala-async with the Twitter util-core implementation of futures. It fails to compile with this error:
[error] /Users/tdyas/Code/twitter-util-async/src/test/scala/com/foursquare/common/async/TwitterFutureSystemTest.scala:16: class stateMachine$1 needs to be abstract, since method apply in trait Function1 of type (v1: scala.util.Try[Any])Unit is not defined
[error] (Note that T1 does not match com.twitter.util.Try[Any])
[error] val f3 = async {
The issue seems to be the hard-coded reference to scala.util.Try in src/main/scala/scala/async/internal/AsyncTransform.scala:
val template = Template(List(typeOf[(scala.util.Try[Any] => Unit)], typeOf[() => Unit]).map(TypeTree(_)), emptyValDef, body)
Basically, the apply
method is expecting com.twitter.util.Try but scala-async is hard-coding scala.util.Try
.
The AST produced by the code is:
asyncImpl: tree=Expr[AsyncBase.this.futureSystem.Fut[Int]]({
class stateMachine$1 extends scala.util.Try[Any] => Unit with () => Unit {
<synthetic> <stable> private[this] var await$2$1: Int = 0;
<synthetic> <stable> private[this] var await$1$1: Int = 0;
<stable> private[this] var v1$1: Int = 0;
def <init>(): stateMachine$1 = {
stateMachine$1.super.<init>();
()
};
private[this] var state: Int = 0;
private[this] val result: com.twitter.util.Promise[Int] = Promise.apply[Int]();
private[this] val execContext: scala.concurrent.ExecutionContextExecutor = scala.concurrent.ExecutionContext.Implicits.global;
def resume(): Unit = try {
stateMachine$1.this.state match {
case 0 => {
();
<synthetic> val awaitable$1: com.twitter.util.Future[Int] @scala.reflect.internal.annotations.uncheckedBounds = f1;
{
awaitable$1.respond(((x: com.twitter.util.Try[Int]) => {
this.apply(x);
()
}));
()
};
()
}
case 1 => {
stateMachine$1.this.v1$1 = stateMachine$1.this.await$1$1;
<synthetic> val awaitable$2: com.twitter.util.Future[Int] @scala.reflect.internal.annotations.uncheckedBounds = f2;
{
awaitable$2.respond(((x: com.twitter.util.Try[Int]) => {
this.apply(x);
()
}));
()
};
()
}
case 2 => {
stateMachine$1.this.result.update(Return.apply[Int]({
val v2: Int = stateMachine$1.this.await$2$1;
stateMachine$1.this.v1$1.+(v2)
}));
()
}
}
} catch {
case (throwable @ _) if NonFatal.apply(throwable) => {
stateMachine$1.this.result.update(Throw.apply[Int](throwable));
()
}
};
def apply(tr: com.twitter.util.Try[Any]): Unit = stateMachine$1.this.state match {
case 0 => {
if (tr.isThrow)
{
stateMachine$1.this.result.update(tr.asInstanceOf[com.twitter.util.Try[Int]]);
()
}
else
{
stateMachine$1.this.await$1$1 = tr.get().asInstanceOf[Int];
stateMachine$1.this.state = 1;
stateMachine$1.this.resume()
};
()
}
case 1 => {
if (tr.isThrow)
{
stateMachine$1.this.result.update(tr.asInstanceOf[com.twitter.util.Try[Int]]);
()
}
else
{
stateMachine$1.this.await$2$1 = tr.get().asInstanceOf[Int];
stateMachine$1.this.state = 2;
stateMachine$1.this.resume()
};
()
}
};
def apply: Unit = resume();
private[this] val extra: Unit = ()
};
val stateMachine$1 = new stateMachine$1();
{
val promise = Promise.apply[Unit]();
stateMachine$1.execContext.execute({
final class $anon extends Runnable {
def <init>() = {
super.<init>();
()
};
def run(): Unit = try {
promise.setValue(stateMachine$1.apply())
} catch {
case (ex @ (_: `package`.Exception)) => promise.setException(ex)
}
};
new $anon()
});
promise
};
stateMachine$1.result
})
I tried changing AsyncTransform.scala to refer to typeOf[futureSystem.Tryy[Any] => Unit]
instead but then running the scala-async tests gave errors like this:
[error] /Users/tdyas/Code/scala-async/src/test/scala/scala/async/run/ifelse3/IfElse3.scala:24: type mismatch;
[error] found : stateMachine$1
[error] required: scala.util.Try[Int] => ?
[error] def m(y: Int): Future[Int] = async {
[error] ^
Any ideas?
Metadata
Metadata
Assignees
Labels
No labels