summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2012-10-12 22:24:32 -0700
committerPaul Phillips <paulp@improving.org>2012-10-13 07:28:30 -0700
commit02909f2be30db5c0f79f961cad17e2dc2f026ff4 (patch)
tree7a47e916ec196d4c8e34832eebacc21b76c4b997
parent8a984fa0e351de532497450c9c80ddd2f975d32e (diff)
downloadscala-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.scala13
-rw-r--r--src/reflect/scala/reflect/internal/TreeInfo.scala28
-rw-r--r--test/files/neg/unit-returns-value.check8
-rw-r--r--test/files/neg/unit-returns-value.scala23
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
+ }
+}
+