diff options
author | James Iry <jamesiry@gmail.com> | 2013-02-11 11:14:45 -0800 |
---|---|---|
committer | James Iry <jamesiry@gmail.com> | 2013-02-11 11:14:45 -0800 |
commit | d2696dc8137ef8999c7ebac20403392589988dfd (patch) | |
tree | ae95cc50300afae7e6a5a4a944f6c099d60a997d | |
parent | 638d41b650cbaa6216fb15f0e9b6eca7eb499f06 (diff) | |
parent | 673cc83f198322b3346be2bddea7ff05bd6f0f5b (diff) | |
download | scala-d2696dc8137ef8999c7ebac20403392589988dfd.tar.gz scala-d2696dc8137ef8999c7ebac20403392589988dfd.tar.bz2 scala-d2696dc8137ef8999c7ebac20403392589988dfd.zip |
Merge pull request #2111 from retronym/2.10.x
SI-6514 Avoid spurious dead code warnings
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala | 17 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 6 | ||||
-rw-r--r-- | test/files/pos/t6514.scala | 11 |
3 files changed, 26 insertions, 8 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. diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 478312116a..f97582f45c 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -3305,8 +3305,6 @@ trait Typers extends Modes with Adaptations with Tags { // but behaves as if it were (=> T) => T) we need to know what is the actual // target of a call. Since this information is no longer available from // typedArg, it is recorded here. - checkDead.updateExpr(fun) - val args1 = // no expected type when jumping to a match label -- anything goes (this is ok since we're typing the translation of well-typed code) // ... except during erasure: we must take the expected type into account as it drives the insertion of casts! @@ -3361,7 +3359,9 @@ trait Typers extends Modes with Adaptations with Tags { else constfold(treeCopy.Apply(tree, fun, args1) setType ifPatternSkipFormals(restpe)) } - handleMonomorphicCall + checkDead.updateExpr(fun) { + handleMonomorphicCall + } } else if (needsInstantiation(tparams, formals, args)) { //println("needs inst "+fun+" "+tparams+"/"+(tparams map (_.info))) inferExprInstance(fun, tparams) diff --git a/test/files/pos/t6514.scala b/test/files/pos/t6514.scala new file mode 100644 index 0000000000..7c58605d39 --- /dev/null +++ b/test/files/pos/t6514.scala @@ -0,0 +1,11 @@ +object Test { + def e(msg: String) = new Exception(msg) + + // this code ain't dead. + def a(b: Boolean) = { + b match { + case true => throw e("true") + case false => throw e("false") + } + } +} |