summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2013-02-10 23:13:28 +0100
committerJason Zaugg <jzaugg@gmail.com>2013-02-10 23:21:49 +0100
commit673cc83f198322b3346be2bddea7ff05bd6f0f5b (patch)
tree13bdc50189bc44d0548a01e9ba07a001dd74b45d /src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
parent23b69c1e05474dc6b504d63c074629132264deaf (diff)
downloadscala-673cc83f198322b3346be2bddea7ff05bd6f0f5b.tar.gz
scala-673cc83f198322b3346be2bddea7ff05bd6f0f5b.tar.bz2
scala-673cc83f198322b3346be2bddea7ff05bd6f0f5b.zip
SI-6514 Avoid spurious dead code warnings
`deadCode.expr` stores the method symbol most recently encountered in `handleMonomorphicCall`, and uses this to avoid warnings for arguments to label jumps and `Object#synchronized` (which sneakily acts by-name without advertising the fact in its type.) But this scheme was insufficient if the argument itself contains another method call, such as `matchEnd(throw e(""))`. This commit changes the single slot to a stack, and also grants exemption to `LabelDef` trees. They were incorrectly flagged in the enclosed test case after I made the the first change.
Diffstat (limited to 'src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala17
1 files changed, 12 insertions, 5 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
index 4233bde770..8c21479f73 100644
--- a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
@@ -427,17 +427,24 @@ trait TypeDiagnostics {
contextWarning(pos, "imported `%s' is permanently hidden by definition of %s".format(hidden, defn.fullLocationString))
object checkDead {
- private var expr: Symbol = NoSymbol
+ private val exprStack: mutable.Stack[Symbol] = mutable.Stack(NoSymbol)
+ // The method being applied to `tree` when `apply` is called.
+ private def expr = exprStack.top
private def exprOK =
(expr != Object_synchronized) &&
!(expr.isLabel && treeInfo.isSynthCaseSymbol(expr)) // it's okay to jump to matchEnd (or another case) with an argument of type nothing
- private def treeOK(tree: Tree) = tree.tpe != null && tree.tpe.typeSymbol == NothingClass
+ private def treeOK(tree: Tree) = {
+ val isLabelDef = tree match { case _: LabelDef => true; case _ => false}
+ tree.tpe != null && tree.tpe.typeSymbol == NothingClass && !isLabelDef
+ }
- def updateExpr(fn: Tree) = {
- if (fn.symbol != null && fn.symbol.isMethod && !fn.symbol.isConstructor)
- checkDead.expr = fn.symbol
+ @inline def updateExpr[A](fn: Tree)(f: => A) = {
+ if (fn.symbol != null && fn.symbol.isMethod && !fn.symbol.isConstructor) {
+ exprStack push fn.symbol
+ try f finally exprStack.pop()
+ } else f
}
def apply(tree: Tree): Tree = {
// Error suppression will squash some of these warnings unless we circumvent it.