Skip to content

Commit 154a2d7

Browse files
committed
Merge pull request #80 from retronym/ticket/79
Fix regression around type skolems and if exprs.
2 parents 75ef24d + 1df8490 commit 154a2d7

File tree

3 files changed

+70
-4
lines changed

3 files changed

+70
-4
lines changed

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

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -156,9 +156,12 @@ trait AsyncTransform {
156156
case ValDef(_, _, _, rhs) if liftedSyms(tree.symbol) =>
157157
atOwner(currentOwner) {
158158
val fieldSym = tree.symbol
159-
val set = Assign(gen.mkAttributedStableRef(fieldSym.owner.thisType, fieldSym), transform(rhs))
160-
changeOwner(set, tree.symbol, currentOwner)
161-
localTyper.typedPos(tree.pos)(set)
159+
val lhs = atPos(tree.pos) {
160+
gen.mkAttributedStableRef(fieldSym.owner.thisType, fieldSym)
161+
}
162+
val assign = treeCopy.Assign(tree, lhs, transform(rhs)).setType(definitions.UnitTpe)
163+
changeOwner(assign, tree.symbol, currentOwner)
164+
assign
162165
}
163166
case _: DefTree if liftedSyms(tree.symbol) =>
164167
EmptyTree

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ private[async] trait TransformUtils {
100100
case ld: LabelDef => ld.symbol
101101
}.toSet
102102
t.exists {
103-
case rt: RefTree => !(labelDefs contains rt.symbol)
103+
case rt: RefTree => rt.symbol != null && rt.symbol.isLabel && !(labelDefs contains rt.symbol)
104104
case _ => false
105105
}
106106
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
* Copyright (C) 2012-2014 Typesafe Inc. <http://www.typesafe.com>
3+
*/
4+
5+
package scala.async
6+
package run
7+
package ifelse4
8+
9+
import language.{reflectiveCalls, postfixOps}
10+
import scala.concurrent.{Future, ExecutionContext, future, Await}
11+
import scala.concurrent.duration._
12+
import scala.async.Async.{async, await}
13+
import org.junit.Test
14+
15+
16+
class TestIfElse4Class {
17+
18+
import ExecutionContext.Implicits.global
19+
20+
class F[A]
21+
class S[A](val id: String)
22+
trait P
23+
24+
case class K(f: F[_])
25+
26+
def result[A](f: F[A]) = async {
27+
new S[A with P]("foo")
28+
}
29+
30+
def run(k: K) = async {
31+
val res = await(result(k.f))
32+
// these triggered a crash with mismatched existential skolems
33+
// found : S#10272[_$1#10308 with String#137] where type _$1#10308
34+
// required: S#10272[_$1#10311 with String#137] forSome { type _$1#10311 }
35+
36+
// This variation of the crash could be avoided by fixing the over-eager
37+
// generation of states in `If` nodes, which was caused by a bug in label
38+
// detection code.
39+
if(true) {
40+
identity(res)
41+
}
42+
43+
// This variation remained after the aforementioned fix, however.
44+
// It was fixed by manually typing the `Assign(liftedField, rhs)` AST,
45+
// which is how we avoid these problems through the rest of the ANF transform.
46+
if(true) {
47+
identity(res)
48+
await(result(k.f))
49+
}
50+
res
51+
}
52+
}
53+
54+
class IfElse4Spec {
55+
56+
@Test
57+
def `await result with complex type containing skolem`() {
58+
val o = new TestIfElse4Class
59+
val fut = o.run(new o.K(null))
60+
val res = Await.result(fut, 2 seconds)
61+
res.id mustBe ("foo")
62+
}
63+
}

0 commit comments

Comments
 (0)