diff options
author | Paul Phillips <paulp@improving.org> | 2012-10-12 22:24:32 -0700 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2012-10-13 07:28:30 -0700 |
commit | 02909f2be30db5c0f79f961cad17e2dc2f026ff4 (patch) | |
tree | 7a47e916ec196d4c8e34832eebacc21b76c4b997 | |
parent | 8a984fa0e351de532497450c9c80ddd2f975d32e (diff) | |
download | scala-02909f2be30db5c0f79f961cad17e2dc2f026ff4.tar.gz scala-02909f2be30db5c0f79f961cad17e2dc2f026ff4.tar.bz2 scala-02909f2be30db5c0f79f961cad17e2dc2f026ff4.zip |
Warn about more misplaced expressions.
An identifier being used in statement position is not likely
what was meant when it is a non-lazy getter.
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 13 | ||||
-rw-r--r-- | src/reflect/scala/reflect/internal/TreeInfo.scala | 28 | ||||
-rw-r--r-- | test/files/neg/unit-returns-value.check | 8 | ||||
-rw-r--r-- | test/files/neg/unit-returns-value.scala | 23 |
4 files changed, 58 insertions, 14 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index a262438ae0..546baba996 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -2713,17 +2713,6 @@ trait Typers extends Modes with Adaptations with Tags { case Some(imp1: Import) => imp1 case _ => log("unhandled import: "+imp+" in "+unit); imp } - private def isWarnablePureExpression(tree: Tree) = tree match { - case EmptyTree | Literal(Constant(())) => false - case _ => - !tree.isErrorTyped && (treeInfo isExprSafeToInline tree) && { - val sym = tree.symbol - (sym == null) || !(sym.isModule || sym.isLazy) || { - debuglog("'Pure' but side-effecting expression in statement position: " + tree) - false - } - } - } def typedStats(stats: List[Tree], exprOwner: Symbol): List[Tree] = { val inBlock = exprOwner == context.owner @@ -2760,7 +2749,7 @@ trait Typers extends Modes with Adaptations with Tags { ConstructorsOrderError(stat) } - if (isWarnablePureExpression(result)) context.warning(stat.pos, + if (treeInfo.isPureExprForWarningPurposes(result)) context.warning(stat.pos, "a pure expression does nothing in statement position; " + "you may be omitting necessary parentheses" ) diff --git a/src/reflect/scala/reflect/internal/TreeInfo.scala b/src/reflect/scala/reflect/internal/TreeInfo.scala index d4a22886dd..66326c90e9 100644 --- a/src/reflect/scala/reflect/internal/TreeInfo.scala +++ b/src/reflect/scala/reflect/internal/TreeInfo.scala @@ -104,6 +104,34 @@ abstract class TreeInfo { false } + /** As if the name of the method didn't give it away, + * this logic is designed around issuing helpful + * warnings and minimizing spurious ones. That means + * don't reuse it for important matters like inlining + * decisions. + */ + def isPureExprForWarningPurposes(tree: Tree) = tree match { + case EmptyTree | Literal(Constant(())) => false + case _ => + def isWarnableRefTree = tree match { + case t: RefTree => isExprSafeToInline(t.qualifier) && t.symbol != null && t.symbol.isAccessor + case _ => false + } + def isWarnableSymbol = { + val sym = tree.symbol + (sym == null) || !(sym.isModule || sym.isLazy) || { + debuglog("'Pure' but side-effecting expression in statement position: " + tree) + false + } + } + + ( !tree.isErrorTyped + && (isExprSafeToInline(tree) || isWarnableRefTree) + && isWarnableSymbol + ) + } + + @deprecated("Use isExprSafeToInline instead", "2.10.0") def isPureExpr(tree: Tree) = isExprSafeToInline(tree) diff --git a/test/files/neg/unit-returns-value.check b/test/files/neg/unit-returns-value.check index 363946f94d..f30a506ebe 100644 --- a/test/files/neg/unit-returns-value.check +++ b/test/files/neg/unit-returns-value.check @@ -4,6 +4,12 @@ unit-returns-value.scala:4: warning: a pure expression does nothing in statement unit-returns-value.scala:4: warning: enclosing method f has result type Unit: return value discarded if (b) return 5 ^ +unit-returns-value.scala:22: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses + i1 // warn + ^ +unit-returns-value.scala:23: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses + i2 // warn + ^ error: No warnings can be incurred under -Xfatal-warnings. -two warnings found +four warnings found one error found diff --git a/test/files/neg/unit-returns-value.scala b/test/files/neg/unit-returns-value.scala index ecc981f217..fc5a37069f 100644 --- a/test/files/neg/unit-returns-value.scala +++ b/test/files/neg/unit-returns-value.scala @@ -3,9 +3,30 @@ object Test { var b = false if (b) return 5 } - + // no warning def g { return println("hello") } } + +class UnusedValues { + var i1 = 2 + val i2 = 2 + lazy val i3 = 2 + object i4 { } + def i5 = 2 + final def i6 = 2 + + def x = { + i1 // warn + i2 // warn + i3 // no warn + i4 // no warn + i5 // no warn + i6 // could warn someday, if i6 returned 2.type instead of Int + + 5 + } +} + |