Skip to content

Commit d98bcdc

Browse files
committed
Merge branch 'ticket/86-mkZero' into merge/2.10.x-to-master-20140930
Conflicts: src/main/scala/scala/async/internal/AnfTransform.scala src/main/scala/scala/async/internal/AsyncTransform.scala src/test/scala/scala/async/run/toughtype/ToughType.scala
2 parents 0f8ea5c + b420446 commit d98bcdc

File tree

4 files changed

+73
-9
lines changed

4 files changed

+73
-9
lines changed

src/main/scala/scala/async/internal/AnfTransform.scala

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ private[async] trait AnfTransform {
5151
expr match {
5252
case Apply(fun, args) if isAwait(fun) =>
5353
val valDef = defineVal(name.await, expr, tree.pos)
54-
stats :+ valDef :+ gen.mkAttributedStableRef(valDef.symbol).setType(tree.tpe).setPos(tree.pos)
54+
stats :+ valDef :+ atPos(tree.pos)(gen.mkAttributedStableRef(valDef.symbol)).setType(tree.tpe)
5555

5656
case If(cond, thenp, elsep) =>
5757
// if type of if-else is Unit don't introduce assignment,
@@ -68,7 +68,7 @@ private[async] trait AnfTransform {
6868
}
6969
})
7070
val ifWithAssign = treeCopy.If(tree, cond, branchWithAssign(thenp), branchWithAssign(elsep)).setType(definitions.UnitTpe)
71-
stats :+ varDef :+ ifWithAssign :+ gen.mkAttributedStableRef(varDef.symbol).setType(tree.tpe).setPos(tree.pos)
71+
stats :+ varDef :+ ifWithAssign :+ atPos(tree.pos)(gen.mkAttributedStableRef(varDef.symbol)).setType(tree.tpe)
7272
}
7373
case LabelDef(name, params, rhs) =>
7474
statsExprUnit
@@ -93,7 +93,7 @@ private[async] trait AnfTransform {
9393
}
9494
val matchWithAssign = treeCopy.Match(tree, scrut, casesWithAssign).setType(definitions.UnitTpe)
9595
require(matchWithAssign.tpe != null, matchWithAssign)
96-
stats :+ varDef :+ matchWithAssign :+ gen.mkAttributedStableRef(varDef.symbol).setPos(tree.pos).setType(tree.tpe)
96+
stats :+ varDef :+ matchWithAssign :+ atPos(tree.pos)(gen.mkAttributedStableRef(varDef.symbol)).setType(tree.tpe)
9797
}
9898
case _ =>
9999
stats :+ expr
@@ -102,7 +102,7 @@ private[async] trait AnfTransform {
102102

103103
private def defineVar(prefix: String, tp: Type, pos: Position): ValDef = {
104104
val sym = api.currentOwner.newTermSymbol(name.fresh(prefix), pos, MUTABLE | SYNTHETIC).setInfo(uncheckedBounds(tp))
105-
valDef(sym, gen.mkZero(uncheckedBounds(tp))).setType(NoType).setPos(pos)
105+
valDef(sym, mkZero(uncheckedBounds(tp))).setType(NoType).setPos(pos)
106106
}
107107
}
108108

@@ -128,8 +128,7 @@ private[async] trait AnfTransform {
128128

129129
def defineVal(prefix: String, lhs: Tree, pos: Position): ValDef = {
130130
val sym = api.currentOwner.newTermSymbol(name.fresh(prefix), pos, SYNTHETIC).setInfo(uncheckedBounds(lhs.tpe))
131-
lhs.changeOwner(api.currentOwner, sym)
132-
valDef(sym, lhs.changeOwner(api.currentOwner, sym)).setType(NoType).setPos(pos)
131+
internal.valDef(sym, internal.changeOwner(lhs, api.currentOwner, sym)).setType(NoType).setPos(pos)
133132
}
134133

135134
object anf {

src/main/scala/scala/async/internal/AsyncTransform.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ trait AsyncTransform {
8181
List(
8282
asyncBase.nullOut(c.universe)(c.Expr[String](Literal(Constant(fieldSym.name.toString))), c.Expr[Any](Ident(fieldSym))).tree
8383
),
84-
Assign(gen.mkAttributedStableRef(thisType(fieldSym.owner), fieldSym), gen.mkZero(fieldSym.info))
84+
Assign(gen.mkAttributedStableRef(thisType(fieldSym.owner), fieldSym), mkZero(fieldSym.info))
8585
)
8686
}
8787
val asyncState = asyncBlock.asyncStates.find(_.state == state).get

src/main/scala/scala/async/internal/TransformUtils.scala

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,22 @@ private[async] trait TransformUtils {
327327
else NoPrefix
328328
}
329329

330+
private def derivedValueClassUnbox(cls: Symbol) =
331+
(cls.info.decls.find(sym => sym.isMethod && sym.asTerm.isParamAccessor) getOrElse NoSymbol)
332+
333+
def mkZero(tp: Type): Tree = {
334+
if (tp.typeSymbol.asClass.isDerivedValueClass) {
335+
val argZero = mkZero(derivedValueClassUnbox(tp.typeSymbol).infoIn(tp).resultType)
336+
val target: Tree = gen.mkAttributedSelect(
337+
c.typecheck(atMacroPos(
338+
New(TypeTree(tp.baseType(tp.typeSymbol))))), tp.typeSymbol.asClass.primaryConstructor)
339+
val zero = gen.mkMethodCall(target, argZero :: Nil)
340+
gen.mkCast(zero, tp)
341+
} else {
342+
gen.mkZero(tp)
343+
}
344+
}
345+
330346
// =====================================
331347
// Copy/Pasted from Scala 2.10.3. See SI-7694.
332348
private lazy val UncheckedBoundsClass = {

src/test/scala/scala/async/run/toughtype/ToughType.scala

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -239,10 +239,59 @@ class ToughTypeSpec {
239239
val result = Await.result(f, 5.seconds)
240240
result mustEqual (new IntWrapper("foo"))
241241
}
242-
}
243242

244-
class IntWrapper(val value: String) extends AnyVal
243+
@Test def ticket86NestedValueClass() {
244+
import ExecutionContext.Implicits.global
245+
246+
val f = async {
247+
val a = Future.successful(new IntWrapper("42"))
248+
await(await(a).plusStr)
249+
}
250+
val result = Await.result(f, 5.seconds)
251+
result mustEqual "42!"
252+
}
253+
254+
@Test def ticket86MatchedValueClass(): Unit = {
255+
import ExecutionContext.Implicits.global
256+
257+
def doAThing(param: IntWrapper) = Future(None)
258+
259+
val fut = async {
260+
Option(new IntWrapper("value!")) match {
261+
case Some(valueHolder) =>
262+
await(doAThing(valueHolder))
263+
case None =>
264+
None
265+
}
266+
}
267+
268+
val result = Await.result(fut, 5.seconds)
269+
result mustBe None
270+
}
271+
272+
@Test def ticket86MatchedParameterizedValueClass(): Unit = {
273+
import ExecutionContext.Implicits.global
245274

275+
def doAThing(param: ParamWrapper[String]) = Future(None)
276+
277+
val fut = async {
278+
Option(new ParamWrapper("value!")) match {
279+
case Some(valueHolder) =>
280+
await(doAThing(valueHolder))
281+
case None =>
282+
None
283+
}
284+
}
285+
286+
val result = Await.result(fut, 5.seconds)
287+
result mustBe None
288+
}
289+
}
290+
291+
class IntWrapper(val value: String) extends AnyVal {
292+
def plusStr = Future.successful(value + "!")
293+
}
294+
class ParamWrapper[T](val value: T) extends AnyVal
246295

247296
trait A
248297

0 commit comments

Comments
 (0)