summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@typesafe.com>2013-03-01 16:54:44 -0800
committerAdriaan Moors <adriaan.moors@typesafe.com>2013-03-01 16:54:44 -0800
commit440bf0a8c2545006de1ec70179100742fd73d981 (patch)
tree1eb66e38d1404604a07dc2b543ba559533fd133b
parentc4eede47d7de2af0f31b344bef5c5d7ee6739d27 (diff)
parent0303e64efa8ee223c0767d7be8d2875a62b88aea (diff)
downloadscala-440bf0a8c2545006de1ec70179100742fd73d981.tar.gz
scala-440bf0a8c2545006de1ec70179100742fd73d981.tar.bz2
scala-440bf0a8c2545006de1ec70179100742fd73d981.zip
Merge pull request #2168 from retronym/ticket/7183
SI-7183 Disable unreachability for withFilter matches.
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala42
-rw-r--r--test/files/pos/t7183.flags1
-rw-r--r--test/files/pos/t7183.scala13
3 files changed, 42 insertions, 14 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala b/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala
index f7579ad249..87fe3fb3f6 100644
--- a/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala
@@ -936,7 +936,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
// the making of the trees
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
trait TreeMakers extends TypedSubstitution { self: CodegenCore =>
- def optimizeCases(prevBinder: Symbol, cases: List[List[TreeMaker]], pt: Type, unchecked: Boolean): (List[List[TreeMaker]], List[Tree]) =
+ def optimizeCases(prevBinder: Symbol, cases: List[List[TreeMaker]], pt: Type, supression: Suppression): (List[List[TreeMaker]], List[Tree]) =
(cases, Nil)
def emitSwitch(scrut: Tree, scrutSym: Symbol, cases: List[List[TreeMaker]], pt: Type, matchFailGenOverride: Option[Tree => Tree], unchecked: Boolean): Option[Tree] =
@@ -1408,18 +1408,24 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
def matchFailGen = (matchFailGenOverride orElse Some(CODE.MATCHERROR(_: Tree)))
patmatDebug("combining cases: "+ (casesNoSubstOnly.map(_.mkString(" >> ")).mkString("{", "\n", "}")))
- val (unchecked, requireSwitch) =
- if (settings.XnoPatmatAnalysis.value) (true, false)
+ val (suppression, requireSwitch): (Suppression, Boolean) =
+ if (settings.XnoPatmatAnalysis.value) (Suppression.NoSuppresion, false)
else scrut match {
- case Typed(_, tpt) =>
- (tpt.tpe hasAnnotation UncheckedClass,
- // matches with two or fewer cases need not apply for switchiness (if-then-else will do)
- treeInfo.isSwitchAnnotation(tpt.tpe) && casesNoSubstOnly.lengthCompare(2) > 0)
+ case Typed(tree, tpt) =>
+ val suppressExhaustive = tpt.tpe hasAnnotation UncheckedClass
+ val supressUnreachable = tree match {
+ case Ident(name) if name startsWith nme.CHECK_IF_REFUTABLE_STRING => true // SI-7183 don't warn for withFilter's that turn out to be irrefutable.
+ case _ => false
+ }
+ val suppression = Suppression(suppressExhaustive, supressUnreachable)
+ // matches with two or fewer cases need not apply for switchiness (if-then-else will do)
+ val requireSwitch = treeInfo.isSwitchAnnotation(tpt.tpe) && casesNoSubstOnly.lengthCompare(2) > 0
+ (suppression, requireSwitch)
case _ =>
- (false, false)
+ (Suppression.NoSuppresion, false)
}
- emitSwitch(scrut, scrutSym, casesNoSubstOnly, pt, matchFailGenOverride, unchecked).getOrElse{
+ emitSwitch(scrut, scrutSym, casesNoSubstOnly, pt, matchFailGenOverride, suppression.exhaustive).getOrElse{
if (requireSwitch) typer.context.unit.warning(scrut.pos, "could not emit switch for @switch annotated match")
if (casesNoSubstOnly nonEmpty) {
@@ -1436,7 +1442,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
}) None
else matchFailGen
- val (cases, toHoist) = optimizeCases(scrutSym, casesNoSubstOnly, pt, unchecked)
+ val (cases, toHoist) = optimizeCases(scrutSym, casesNoSubstOnly, pt, suppression)
val matchRes = codegen.matcher(scrut, scrutSym, pt)(cases map combineExtractors, synthCatchAll)
@@ -3831,11 +3837,13 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
with OptimizedCodegen
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)
+ override def optimizeCases(prevBinder: Symbol, cases: List[List[TreeMaker]], pt: Type, suppression: Suppression): (List[List[TreeMaker]], List[Tree]) = {
+ if (!suppression.unreachable) {
+ unreachableCase(prevBinder, cases, pt) foreach { caseIndex =>
+ reportUnreachable(cases(caseIndex).last.pos)
+ }
}
- if (!unchecked) {
+ if (!suppression.exhaustive) {
val counterExamples = exhaustive(prevBinder, cases, pt)
if (counterExamples.nonEmpty)
reportMissingCases(prevBinder.pos, counterExamples)
@@ -3860,3 +3868,9 @@ object PatternMatchingStats {
val patmatAnaExhaust = Statistics.newSubTimer (" of which in exhaustivity", patmatNanos)
val patmatAnaReach = Statistics.newSubTimer (" of which in unreachability", patmatNanos)
}
+
+final case class Suppression(exhaustive: Boolean, unreachable: Boolean)
+
+object Suppression {
+ val NoSuppresion = Suppression(false, false)
+} \ No newline at end of file
diff --git a/test/files/pos/t7183.flags b/test/files/pos/t7183.flags
new file mode 100644
index 0000000000..e8fb65d50c
--- /dev/null
+++ b/test/files/pos/t7183.flags
@@ -0,0 +1 @@
+-Xfatal-warnings \ No newline at end of file
diff --git a/test/files/pos/t7183.scala b/test/files/pos/t7183.scala
new file mode 100644
index 0000000000..7647c1634b
--- /dev/null
+++ b/test/files/pos/t7183.scala
@@ -0,0 +1,13 @@
+class A
+object A {
+ def unapply(a: A): Some[A] = Some(a) // Change return type to Option[A] and the warning is gone
+}
+
+object Test {
+ for (A(a) <- List(new A)) yield a // spurious dead code warning.
+}
+
+// List(new A()).withFilter(((check$ifrefutable$2) => check$ifrefutable$2: @scala.unchecked match {
+// case A((a @ _)) => true
+// case _ => false // this is dead code, but it's compiler generated.
+// }))