From 673cc83f198322b3346be2bddea7ff05bd6f0f5b Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Sun, 10 Feb 2013 23:13:28 +0100 Subject: 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. --- .../scala/tools/nsc/typechecker/TypeDiagnostics.scala | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala') 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. -- cgit v1.2.3