diff options
author | Adriaan Moors <adriaan.moors@epfl.ch> | 2012-02-09 12:12:19 +0100 |
---|---|---|
committer | Adriaan Moors <adriaan.moors@epfl.ch> | 2012-02-17 14:19:02 +0100 |
commit | 0643b79165e1ad524c5c99a9a7664fdf356d121a (patch) | |
tree | c85ab1bb1b8d30212877e705be462a24d86d39aa | |
parent | a57ac60dbb115b90ca1ccc9944199bf3e82d517d (diff) | |
download | scala-0643b79165e1ad524c5c99a9a7664fdf356d121a.tar.gz scala-0643b79165e1ad524c5c99a9a7664fdf356d121a.tar.bz2 scala-0643b79165e1ad524c5c99a9a7664fdf356d121a.zip |
[vpm] generate proper isDefinedAt for switches
don't consider the matcherror-throwing catch-all case (generated by virtpatmat) a default case
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/UnCurry.scala | 11 | ||||
-rw-r--r-- | test/files/run/virtpatmat_partial.check | 4 | ||||
-rw-r--r-- | test/files/run/virtpatmat_partial.scala | 23 |
3 files changed, 35 insertions, 3 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala index c26b19b04d..94e562b82f 100644 --- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala +++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala @@ -348,11 +348,18 @@ abstract class UnCurry extends InfoTransform substTree(idaBlock.duplicate) // duplicate on block as a whole to ensure valdefs are properly cloned and substed } + def dropMatchErrorCatchAll(cases: List[CaseDef]): List[CaseDef] = + if (!opt.virtPatmat) cases + else cases filter { + case CaseDef(pat, EmptyTree, Throw(Apply(Select(New(exTpt), nme.CONSTRUCTOR), _))) if (treeInfo.isWildcardArg(pat) && (exTpt.tpe.typeSymbol eq MatchErrorClass)) => false + case CaseDef(pat, guard, body) => true + } + DefDef(m, (fun.body: @unchecked) match { case Match(selector, cases) => - dupMatch(selector, cases) + dupMatch(selector, dropMatchErrorCatchAll(cases)) case Block((vd: ValDef) :: Nil, Match(selector, cases)) => // can't factor this out using an extractor due to bugs in the old pattern matcher - dupMatch(selector, cases, m => Block(List(vd), m)) + dupMatch(selector, dropMatchErrorCatchAll(cases), m => Block(List(vd), m)) // virtpatmat -- TODO: find a better way to keep this in synch with the code generated by patmatvirtualizer case Apply(Apply(TypeApply(Select(tgt, nme.runOrElse), targs), args_scrut), args_pm) if opt.virtPatmat => object noOne extends Transformer { diff --git a/test/files/run/virtpatmat_partial.check b/test/files/run/virtpatmat_partial.check index 093020ce05..1555eca82b 100644 --- a/test/files/run/virtpatmat_partial.check +++ b/test/files/run/virtpatmat_partial.check @@ -1,2 +1,4 @@ Map(a -> Some(1), b -> None) -Map(a -> 1)
\ No newline at end of file +79 +undefined +Map(a -> 1) diff --git a/test/files/run/virtpatmat_partial.scala b/test/files/run/virtpatmat_partial.scala index c408b31983..6597f2f5ae 100644 --- a/test/files/run/virtpatmat_partial.scala +++ b/test/files/run/virtpatmat_partial.scala @@ -4,6 +4,29 @@ object Test extends App { val res = a collect {case (p, Some(a)) => (p, a)} + final val GT = 79 + final val GTGT = 93 + final val GTGTGT = 94 + final val GTEQ = 81 + final val GTGTEQ = 113 + final val GTGTGTEQ = 114 + final val ASSIGN = 75 + + def acceptClosingAngle(in: Int) { + val closers: PartialFunction[Int, Int] = { + case GTGTGTEQ => GTGTEQ + case GTGTGT => GTGT + case GTGTEQ => GTEQ + case GTGT => GT + case GTEQ => ASSIGN + } + if (closers isDefinedAt in) println(closers(in)) + else println("undefined") + } + + acceptClosingAngle(GTGT) + acceptClosingAngle(ASSIGN) + // should uncurry to: // val res: Map[String,Int] = a.collect[(String, Int), Map[String,Int]]( // new PartialFunction[(String, Option[Int]),(String, Int)] { |