diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2013-07-07 07:37:53 +1000 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2013-07-07 07:37:53 +1000 |
commit | c60c38ca6098402f7a9cc6d6746b664bb2b1306c (patch) | |
tree | bc31d4de6cdda7bfe4358984a40095c2e7464eac | |
parent | 82232ec47effb4a6b67b3a0792e1c7600e2d31b7 (diff) | |
download | scala-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.scala | 11 | ||||
-rw-r--r-- | src/main/scala/scala/async/TransformUtils.scala | 10 | ||||
-rw-r--r-- | src/test/scala/scala/async/TreeInterrogation.scala | 3 | ||||
-rw-r--r-- | src/test/scala/scala/async/run/match0/Match0.scala | 13 | ||||
-rw-r--r-- | src/test/scala/scala/async/run/toughtype/ToughType.scala | 32 |
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 + } } |