summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala17
-rw-r--r--test/files/neg/t6902.check10
-rw-r--r--test/files/neg/t6902.flags1
-rw-r--r--test/files/neg/t6902.scala23
-rw-r--r--test/files/run/t6011c.scala13
5 files changed, 55 insertions, 9 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala b/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala
index fa8aff5cdd..9746b05c03 100644
--- a/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala
@@ -3225,6 +3225,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
// TODO: make more fine-grained, as we don't always need to jump
def canJump: Boolean
+ /** Should exhaustivity analysis be skipped? */
def unchecked: Boolean
@@ -3458,12 +3459,10 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
case Some(cds) => cds
}
- val allReachable = unchecked || {
- // a switch with duplicate cases yields a verify error,
- // and a switch with duplicate cases and guards cannot soundly be rewritten to an unguarded switch
- // (even though the verify error would disappear, the behaviour would change)
- unreachableCase(caseDefsWithGuards) map (cd => reportUnreachable(cd.body.pos)) isEmpty
- }
+ // a switch with duplicate cases yields a verify error,
+ // and a switch with duplicate cases and guards cannot soundly be rewritten to an unguarded switch
+ // (even though the verify error would disappear, the behaviour would change)
+ val allReachable = unreachableCase(caseDefsWithGuards) map (cd => reportUnreachable(cd.body.pos)) isEmpty
if (!allReachable) Nil
else if (noGuards(caseDefsWithGuards)) {
@@ -3710,10 +3709,10 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
with SymbolicMatchAnalysis
with DPLLSolver { self: TreeMakers =>
override def optimizeCases(prevBinder: Symbol, cases: List[List[TreeMaker]], pt: Type, unchecked: Boolean): (List[List[TreeMaker]], List[Tree]) = {
+ unreachableCase(prevBinder, cases, pt) foreach { caseIndex =>
+ reportUnreachable(cases(caseIndex).last.pos)
+ }
if (!unchecked) {
- unreachableCase(prevBinder, cases, pt) foreach { caseIndex =>
- reportUnreachable(cases(caseIndex).last.pos)
- }
val counterExamples = exhaustive(prevBinder, cases, pt)
if (counterExamples.nonEmpty)
reportMissingCases(prevBinder.pos, counterExamples)
diff --git a/test/files/neg/t6902.check b/test/files/neg/t6902.check
new file mode 100644
index 0000000000..8ad7fd37f9
--- /dev/null
+++ b/test/files/neg/t6902.check
@@ -0,0 +1,10 @@
+t6902.scala:4: error: unreachable code
+ case Some(b) => 3 // no warning was emitted
+ ^
+t6902.scala:9: error: unreachable code
+ case Some(b) => 3 // no warning was emitted
+ ^
+t6902.scala:21: error: unreachable code
+ case 1 => 3 // crash
+ ^
+three errors found
diff --git a/test/files/neg/t6902.flags b/test/files/neg/t6902.flags
new file mode 100644
index 0000000000..e8fb65d50c
--- /dev/null
+++ b/test/files/neg/t6902.flags
@@ -0,0 +1 @@
+-Xfatal-warnings \ No newline at end of file
diff --git a/test/files/neg/t6902.scala b/test/files/neg/t6902.scala
new file mode 100644
index 0000000000..ce5ff8b6fb
--- /dev/null
+++ b/test/files/neg/t6902.scala
@@ -0,0 +1,23 @@
+object Test {
+ Some(Some(1)) collect {
+ case Some(a) => 2
+ case Some(b) => 3 // no warning was emitted
+ }
+
+ (Some(1): @ unchecked) match {
+ case Some(a) => 2
+ case Some(b) => 3 // no warning was emitted
+ }
+
+ // A variation of SI-6011, which eluded the fix
+ // in 2.10.0.
+ //
+ // duplicate keys in SWITCH, can't pick arbitrarily one of them to evict, see SI-6011.
+ // at scala.reflect.internal.SymbolTable.abort(SymbolTable.scala:50)
+ // at scala.tools.nsc.Global.abort(Global.scala:249)
+ // at scala.tools.nsc.backend.jvm.GenASM$JPlainBuilder$jcode$.emitSWITCH(GenASM.scala:1850)
+ ((1: Byte): @unchecked @annotation.switch) match {
+ case 1 => 2
+ case 1 => 3 // crash
+ }
+}
diff --git a/test/files/run/t6011c.scala b/test/files/run/t6011c.scala
new file mode 100644
index 0000000000..0647e3f81a
--- /dev/null
+++ b/test/files/run/t6011c.scala
@@ -0,0 +1,13 @@
+object Test extends App {
+ // A variation of SI-6011, which eluded the fix
+ // in 2.10.0.
+ //
+ // duplicate keys in SWITCH, can't pick arbitrarily one of them to evict, see SI-6011.
+ // at scala.reflect.internal.SymbolTable.abort(SymbolTable.scala:50)
+ // at scala.tools.nsc.Global.abort(Global.scala:249)
+ // at scala.tools.nsc.backend.jvm.GenASM$JPlainBuilder$jcode$.emitSWITCH(GenASM.scala:1850)
+ ((1: Byte): @unchecked @annotation.switch) match {
+ case 1 => 2
+ case 1 => 3 // crash
+ }
+}