summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@typesafe.com>2013-03-01 18:23:57 -0800
committerAdriaan Moors <adriaan.moors@typesafe.com>2013-03-03 23:29:19 -0800
commit2cf6c5d7e5cfbd60958eac0a545f5c2978a8e5cd (patch)
tree4c3c20875be88faf60f3b5ed93701d455004f7f2 /src
parent5b7cfe3c63c15488ed7d8a9bb3b8d7f2043874d8 (diff)
downloadscala-2cf6c5d7e5cfbd60958eac0a545f5c2978a8e5cd.tar.gz
scala-2cf6c5d7e5cfbd60958eac0a545f5c2978a8e5cd.tar.bz2
scala-2cf6c5d7e5cfbd60958eac0a545f5c2978a8e5cd.zip
[port] SI-7183 Disable unreachability for withFilter matches.
This is a forward port of #2168 (originally for 2.10.1, but the pattern matcher has since been refactored in 2.10.x.)
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala10
-rw-r--r--src/compiler/scala/tools/nsc/transform/patmat/MatchTreeMaking.scala33
-rw-r--r--src/compiler/scala/tools/nsc/transform/patmat/PatternMatching.scala2
3 files changed, 29 insertions, 16 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala
index 74b932e173..d9f93f27b6 100644
--- a/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala
+++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala
@@ -691,11 +691,13 @@ trait MatchAnalysis extends MatchApproximation {
VariableAssignment(scrutVar).toCounterExample()
}
- def analyzeCases(prevBinder: Symbol, cases: List[List[TreeMaker]], pt: Type, unchecked: Boolean): Unit = {
- unreachableCase(prevBinder, cases, pt) foreach { caseIndex =>
- reportUnreachable(cases(caseIndex).last.pos)
+ def analyzeCases(prevBinder: Symbol, cases: List[List[TreeMaker]], pt: Type, suppression: Suppression): Unit = {
+ 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)
diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchTreeMaking.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchTreeMaking.scala
index 51f21780b5..202f3444f8 100644
--- a/src/compiler/scala/tools/nsc/transform/patmat/MatchTreeMaking.scala
+++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchTreeMaking.scala
@@ -23,16 +23,21 @@ trait MatchTreeMaking extends MatchCodeGen with Debugging {
import global.{Tree, Type, Symbol, CaseDef, atPos, settings,
Select, Block, ThisType, SingleType, NoPrefix, NoType, needsOuterTest,
ConstantType, Literal, Constant, gen, This, EmptyTree, map2, NoSymbol, Traverser,
- Function, Typed, treeInfo, TypeRef, DefTree}
+ Function, Typed, treeInfo, TypeRef, DefTree, Ident, nme}
import global.definitions.{SomeClass, AnyRefClass, UncheckedClass, BooleanClass}
+ final case class Suppression(exhaustive: Boolean, unreachable: Boolean)
+ object Suppression {
+ val NoSuppression = Suppression(false, false)
+ }
+
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// the making of the trees
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
trait TreeMakers extends TypedSubstitution with CodegenCore {
def optimizeCases(prevBinder: Symbol, cases: List[List[TreeMaker]], pt: Type): (List[List[TreeMaker]], List[Tree])
- def analyzeCases(prevBinder: Symbol, cases: List[List[TreeMaker]], pt: Type, unchecked: Boolean): Unit
+ def analyzeCases(prevBinder: Symbol, cases: List[List[TreeMaker]], pt: Type, suppression: Suppression): Unit
def emitSwitch(scrut: Tree, scrutSym: Symbol, cases: List[List[TreeMaker]], pt: Type, matchFailGenOverride: Option[Tree => Tree], unchecked: Boolean): Option[Tree] =
None
@@ -522,18 +527,24 @@ trait MatchTreeMaking extends MatchCodeGen with Debugging {
def matchFailGen = (matchFailGenOverride orElse Some(CODE.MATCHERROR(_: Tree)))
debug.patmat("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.NoSuppression, 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.NoSuppression, 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) {
@@ -550,7 +561,7 @@ trait MatchTreeMaking extends MatchCodeGen with Debugging {
}) None
else matchFailGen
- analyzeCases(scrutSym, casesNoSubstOnly, pt, unchecked)
+ analyzeCases(scrutSym, casesNoSubstOnly, pt, suppression)
val (cases, toHoist) = optimizeCases(scrutSym, casesNoSubstOnly, pt)
diff --git a/src/compiler/scala/tools/nsc/transform/patmat/PatternMatching.scala b/src/compiler/scala/tools/nsc/transform/patmat/PatternMatching.scala
index f8d8044bdb..df4e699620 100644
--- a/src/compiler/scala/tools/nsc/transform/patmat/PatternMatching.scala
+++ b/src/compiler/scala/tools/nsc/transform/patmat/PatternMatching.scala
@@ -81,7 +81,7 @@ trait PatternMatching extends Transform with TypingTransformers
class PureMatchTranslator(val typer: analyzer.Typer, val matchStrategy: Tree) extends MatchTranslator with PureCodegen {
def optimizeCases(prevBinder: Symbol, cases: List[List[TreeMaker]], pt: Type) = (cases, Nil)
- def analyzeCases(prevBinder: Symbol, cases: List[List[TreeMaker]], pt: Type, unchecked: Boolean): Unit = {}
+ def analyzeCases(prevBinder: Symbol, cases: List[List[TreeMaker]], pt: Type, suppression: Suppression): Unit = {}
}
class OptimizingMatchTranslator(val typer: analyzer.Typer) extends MatchTranslator