summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2013-06-13 14:32:49 -0400
committerJason Zaugg <jzaugg@gmail.com>2013-06-23 23:09:22 +0200
commit58abe39c9d8d75bc2c5ca27e1b8c0c33de9e6824 (patch)
treebb763cf6126f2c1ee5997e87ba55e4a6353aef3a
parentf790662a3eab1e8efce5d4096d0efbae96cf45b4 (diff)
downloadscala-58abe39c9d8d75bc2c5ca27e1b8c0c33de9e6824.tar.gz
scala-58abe39c9d8d75bc2c5ca27e1b8c0c33de9e6824.tar.bz2
scala-58abe39c9d8d75bc2c5ca27e1b8c0c33de9e6824.zip
SI-7433 Fix spurious warning about catching control throwable
In the same vein as SI-6994, we have to be careful not to warn about synthetic code. In that case, the spurious warnings came because we warned in the typechecker, which was also called in erasure. In this case, we are issuing the warning in Uncurry, so we must be mindful of the pattern matchers translations of non-trivial catch patterns, which look like: case (ex8 @ _) => { <synthetic> val x5: Throwable = ex8; case11(){ if ({ case14(){ if (x5.$isInstanceOf[NullPointerException]()) matchEnd13(true) else case15() }; case15(){ if (x5.$isInstanceOf[RuntimeException]()) matchEnd13(true) else case16() }; case16(){ matchEnd13(false) }; matchEnd13(x: Boolean){ x } }) This commit detects that `ex8` is synthetic and disables the warning.
-rw-r--r--src/compiler/scala/tools/nsc/transform/UnCurry.scala8
-rw-r--r--src/reflect/scala/reflect/internal/TreeInfo.scala6
-rw-r--r--test/files/pos/t7433.flags1
-rw-r--r--test/files/pos/t7433.scala10
4 files changed, 24 insertions, 1 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
index 64f4e579e1..e2ce2743f7 100644
--- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala
+++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
@@ -187,8 +187,14 @@ abstract class UnCurry extends InfoTransform
val keyDef = ValDef(key, New(ObjectTpe))
val tryCatch = Try(body, pat -> rhs)
- for (Try(t, catches, _) <- body ; cdef <- catches ; if treeInfo catchesThrowable cdef)
+ import treeInfo.{catchesThrowable, isSyntheticCase}
+ for {
+ Try(t, catches, _) <- body
+ cdef <- catches
+ if catchesThrowable(cdef) && !isSyntheticCase(cdef)
+ } {
unit.warning(body.pos, "catch block may intercept non-local return from " + meth)
+ }
Block(List(keyDef), tryCatch)
}
diff --git a/src/reflect/scala/reflect/internal/TreeInfo.scala b/src/reflect/scala/reflect/internal/TreeInfo.scala
index 3a8d3fd460..30ec555bc5 100644
--- a/src/reflect/scala/reflect/internal/TreeInfo.scala
+++ b/src/reflect/scala/reflect/internal/TreeInfo.scala
@@ -553,6 +553,12 @@ abstract class TreeInfo {
})
)
+ /** Is this CaseDef synthetically generated, e.g. by `MatchTranslation.translateTry`? */
+ def isSyntheticCase(cdef: CaseDef) = cdef.pat.exists {
+ case dt: DefTree => dt.symbol.isSynthetic
+ case _ => false
+ }
+
/** Is this pattern node a catch-all or type-test pattern? */
def isCatchCase(cdef: CaseDef) = cdef match {
case CaseDef(Typed(Ident(nme.WILDCARD), tpt), EmptyTree, _) =>
diff --git a/test/files/pos/t7433.flags b/test/files/pos/t7433.flags
new file mode 100644
index 0000000000..e8fb65d50c
--- /dev/null
+++ b/test/files/pos/t7433.flags
@@ -0,0 +1 @@
+-Xfatal-warnings \ No newline at end of file
diff --git a/test/files/pos/t7433.scala b/test/files/pos/t7433.scala
new file mode 100644
index 0000000000..f2109f4afa
--- /dev/null
+++ b/test/files/pos/t7433.scala
@@ -0,0 +1,10 @@
+object Test {
+ def foo() {
+ try {
+ for (i <- 1 until 5) return
+ } catch {
+ case _: NullPointerException | _: RuntimeException =>
+ // was: "catch block may intercept non-local return from method check"
+ }
+ }
+}