aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2013-07-07 07:37:53 +1000
committerJason Zaugg <jzaugg@gmail.com>2013-07-07 07:37:53 +1000
commitc60c38ca6098402f7a9cc6d6746b664bb2b1306c (patch)
treebc31d4de6cdda7bfe4358984a40095c2e7464eac
parent82232ec47effb4a6b67b3a0792e1c7600e2d31b7 (diff)
downloadscala-async-c60c38ca6098402f7a9cc6d6746b664bb2b1306c.tar.gz
scala-async-c60c38ca6098402f7a9cc6d6746b664bb2b1306c.tar.bz2
scala-async-c60c38ca6098402f7a9cc6d6746b664bb2b1306c.zip
Fix another interation with existentials and a name clash.
-rw-r--r--src/main/scala/scala/async/AnfTransform.scala11
-rw-r--r--src/main/scala/scala/async/TransformUtils.scala10
-rw-r--r--src/test/scala/scala/async/TreeInterrogation.scala3
-rw-r--r--src/test/scala/scala/async/run/match0/Match0.scala13
-rw-r--r--src/test/scala/scala/async/run/toughtype/ToughType.scala32
5 files changed, 61 insertions, 8 deletions
diff --git a/src/main/scala/scala/async/AnfTransform.scala b/src/main/scala/scala/async/AnfTransform.scala
index 275bc49..14263da 100644
--- a/src/main/scala/scala/async/AnfTransform.scala
+++ b/src/main/scala/scala/async/AnfTransform.scala
@@ -79,12 +79,13 @@ private[async] trait AnfTransform {
stats :+ expr :+ localTyper.typedPos(expr.pos)(Literal(Constant(())))
} else {
val varDef = defineVar(name.ifRes, expr.tpe, tree.pos)
- def branchWithAssign(orig: Tree) = localTyper.typedPos(orig.pos)(
+ def branchWithAssign(orig: Tree) = localTyper.typedPos(orig.pos) {
+ def cast(t: Tree) = mkAttributedCastPreservingAnnotations(t, varDef.symbol.tpe)
orig match {
- case Block(thenStats, thenExpr) => Block(thenStats, Assign(Ident(varDef.symbol), thenExpr))
- case _ => Assign(Ident(varDef.symbol), orig)
+ case Block(thenStats, thenExpr) => Block(thenStats, Assign(Ident(varDef.symbol), cast(thenExpr)))
+ case _ => Assign(Ident(varDef.symbol), cast(orig))
}
- ).setType(orig.tpe)
+ }.setType(orig.tpe)
val ifWithAssign = treeCopy.If(tree, cond, branchWithAssign(thenp), branchWithAssign(elsep))
stats :+ varDef :+ ifWithAssign :+ gen.mkAttributedStableRef(varDef.symbol)
}
@@ -98,7 +99,7 @@ private[async] trait AnfTransform {
else {
val varDef = defineVar(name.matchRes, expr.tpe, tree.pos)
def typedAssign(lhs: Tree) =
- localTyper.typedPos(lhs.pos)(Assign(Ident(varDef.symbol), lhs))
+ localTyper.typedPos(lhs.pos)(Assign(Ident(varDef.symbol), mkAttributedCastPreservingAnnotations(lhs, varDef.symbol.tpe)))
val casesWithAssign = cases map {
case cd@CaseDef(pat, guard, body) =>
val newBody = body match {
diff --git a/src/main/scala/scala/async/TransformUtils.scala b/src/main/scala/scala/async/TransformUtils.scala
index 33dd21d..d69d03a 100644
--- a/src/main/scala/scala/async/TransformUtils.scala
+++ b/src/main/scala/scala/async/TransformUtils.scala
@@ -33,7 +33,7 @@ private[async] trait TransformUtils {
def fresh(name: TermName): TermName = newTermName(fresh(name.toString))
- def fresh(name: String): String = if (name.toString.contains("$")) name else currentUnit.freshTermName("" + name + "$").toString
+ def fresh(name: String): String = currentUnit.freshTermName("" + name + "$").toString
}
def isAwait(fun: Tree) =
@@ -240,4 +240,12 @@ private[async] trait TransformUtils {
def toMultiMap[A, B](as: Iterable[(A, B)]): Map[A, List[B]] =
as.toList.groupBy(_._1).mapValues(_.map(_._2).toList).toMap
+
+ // Attributed version of `TreeGen#mkCastPreservingAnnotations`
+ def mkAttributedCastPreservingAnnotations(tree: Tree, tp: Type): Tree = {
+ atPos(tree.pos) {
+ val casted = gen.mkAttributedCast(tree, tp.withoutAnnotations.dealias)
+ Typed(casted, TypeTree(tp)).setType(tp)
+ }
+ }
}
diff --git a/src/test/scala/scala/async/TreeInterrogation.scala b/src/test/scala/scala/async/TreeInterrogation.scala
index a06437d..86a7157 100644
--- a/src/test/scala/scala/async/TreeInterrogation.scala
+++ b/src/test/scala/scala/async/TreeInterrogation.scala
@@ -40,8 +40,7 @@ class TreeInterrogation {
val varDefs = tree1.collect {
case ValDef(mods, name, _, _) if mods.hasFlag(Flag.MUTABLE) => name
}
- varDefs.map(_.decoded.trim).toSet mustBe (Set("state", "await$1", "await$2"))
- varDefs.map(_.decoded.trim).toSet mustBe (Set("state", "await$1", "await$2"))
+ varDefs.map(_.decoded.trim).toSet mustBe (Set("state", "await$1$1", "await$2$1"))
val defDefs = tree1.collect {
case t: Template =>
diff --git a/src/test/scala/scala/async/run/match0/Match0.scala b/src/test/scala/scala/async/run/match0/Match0.scala
index 7624838..8b99214 100644
--- a/src/test/scala/scala/async/run/match0/Match0.scala
+++ b/src/test/scala/scala/async/run/match0/Match0.scala
@@ -111,4 +111,17 @@ class MatchSpec {
}
result mustBe (3)
}
+
+ @Test def duplicateBindName() {
+ import AsyncId.{async, await}
+ def m4(m: Any) = async {
+ m match {
+ case buf: String =>
+ await(0)
+ case buf: Double =>
+ await(2)
+ }
+ }
+ m4("") mustBe 0
+ }
}
diff --git a/src/test/scala/scala/async/run/toughtype/ToughType.scala b/src/test/scala/scala/async/run/toughtype/ToughType.scala
index 6fcd966..2737132 100644
--- a/src/test/scala/scala/async/run/toughtype/ToughType.scala
+++ b/src/test/scala/scala/async/run/toughtype/ToughType.scala
@@ -105,4 +105,36 @@ class ToughTypeSpec {
await(foo(new a.B))
}
}
+
+ @Test def existentialMatch() {
+ import scala.async.AsyncId.{async, await}
+ trait Container[+A]
+ case class ContainerImpl[A](value: A) extends Container[A]
+ def foo: Container[_] = async {
+ val a: Any = List(1)
+ a match {
+ case buf: Seq[_] =>
+ val foo = await(5)
+ val e0 = buf(0)
+ ContainerImpl(e0)
+ }
+ }
+ foo
+ }
+
+ @Test def existentialIfElse0() {
+ import scala.async.AsyncId.{async, await}
+ trait Container[+A]
+ case class ContainerImpl[A](value: A) extends Container[A]
+ def foo: Container[_] = async {
+ val a: Any = List(1)
+ if (true) {
+ val buf: Seq[_] = List(1)
+ val foo = await(5)
+ val e0 = buf(0)
+ ContainerImpl(e0)
+ } else ???
+ }
+ foo
+ }
}