Skip to content

Commit b60346c

Browse files
committed
Scala 2.10.1 compat: account for change in PartialFunction synthesis.
Since SI-6187, the default case of a partial function is now included in the tree. Before, it was a tree attachment, conditionally inserted in the pattern matcher. I had hoped that that change would allow us to do away with `RestorePatternMatchingFunctions` altogether, but it seems that we aren't so lucky. Instead, I've adapted that transformer to account for the new scheme.
1 parent d332b46 commit b60346c

File tree

2 files changed

+28
-22
lines changed

2 files changed

+28
-22
lines changed

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

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,18 +274,26 @@ private[async] final case class TransformUtils[C <: Context](c: C) {
274274
private object RestorePatternMatchingFunctions extends Transformer {
275275

276276
import language.existentials
277+
val DefaultCaseName: TermName = "defaultCase$"
277278

278279
override def transform(tree: Tree): Tree = {
279280
val SYNTHETIC = (1 << 21).toLong.asInstanceOf[FlagSet]
280281
def isSynthetic(cd: ClassDef) = cd.mods hasFlag SYNTHETIC
281282

283+
/** Is this pattern node a synthetic catch-all case, added during PartialFuction synthesis before we know
284+
* whether the user provided cases are exhaustive. */
285+
def isSyntheticDefaultCase(cdef: CaseDef) = cdef match {
286+
case CaseDef(Bind(DefaultCaseName, _), EmptyTree, _) => true
287+
case _ => false
288+
}
282289
tree match {
283290
case Block(
284291
(cd@ClassDef(_, _, _, Template(_, _, body))) :: Nil,
285292
Apply(Select(New(a), nme.CONSTRUCTOR), Nil)) if isSynthetic(cd) =>
286293
val restored = (body collectFirst {
287294
case DefDef(_, /*name.apply | */ name.applyOrElse, _, _, _, Match(_, cases)) =>
288-
val transformedCases = super.transformStats(cases, currentOwner).asInstanceOf[List[CaseDef]]
295+
val nonSyntheticCases = cases.takeWhile(cdef => !isSyntheticDefaultCase(cdef))
296+
val transformedCases = super.transformStats(nonSyntheticCases, currentOwner).asInstanceOf[List[CaseDef]]
289297
Match(EmptyTree, transformedCases)
290298
}).getOrElse(c.abort(tree.pos, s"Internal Error: Unable to find original pattern matching cases in: $body"))
291299
restored

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

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -37,28 +37,26 @@ class ToughTypeSpec {
3737
res._1 mustBe (Nil)
3838
}
3939

40-
// TODO 2.10.1
41-
// @Test def patternMatchingPartialFunction() {
42-
// import AsyncId.{await, async}
43-
// async {
44-
// await(1)
45-
// val a = await(1)
46-
// val f = { case x => x + a }: PartialFunction[Int, Int]
47-
// await(f(2))
48-
// } mustBe 3
49-
// }
40+
@Test def patternMatchingPartialFunction() {
41+
import AsyncId.{await, async}
42+
async {
43+
await(1)
44+
val a = await(1)
45+
val f = { case x => x + a }: PartialFunction[Int, Int]
46+
await(f(2))
47+
} mustBe 3
48+
}
5049

51-
// TODO 2.10.1
52-
// @Test def patternMatchingPartialFunctionNested() {
53-
// import AsyncId.{await, async}
54-
// async {
55-
// await(1)
56-
// val neg1 = -1
57-
// val a = await(1)
58-
// val f = { case x => ({case x => neg1 * x}: PartialFunction[Int, Int])(x + a) }: PartialFunction[Int, Int]
59-
// await(f(2))
60-
// } mustBe -3
61-
// }
50+
@Test def patternMatchingPartialFunctionNested() {
51+
import AsyncId.{await, async}
52+
async {
53+
await(1)
54+
val neg1 = -1
55+
val a = await(1)
56+
val f = { case x => ({case x => neg1 * x}: PartialFunction[Int, Int])(x + a) }: PartialFunction[Int, Int]
57+
await(f(2))
58+
} mustBe -3
59+
}
6260

6361
@Test def patternMatchingFunction() {
6462
import AsyncId.{await, async}

0 commit comments

Comments
 (0)