summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSom Snytt <som.snytt@gmail.com>2014-08-20 10:25:28 -0700
committerSom Snytt <som.snytt@gmail.com>2014-09-05 01:07:44 -0700
commitc9ec916f20c4f06a0aebe0a9929443c1c8b60c5c (patch)
tree9c592c054af335510d57fa2ff3fc0e733f8953a1
parentd4b5c7b95de88d3890be654e06da812c6eb607f5 (diff)
downloadscala-c9ec916f20c4f06a0aebe0a9929443c1c8b60c5c.tar.gz
scala-c9ec916f20c4f06a0aebe0a9929443c1c8b60c5c.tar.bz2
scala-c9ec916f20c4f06a0aebe0a9929443c1c8b60c5c.zip
SI-8806 Add lower bound check to Any lint
We already exclude the lint check for infer-any if Any is somewhere explicit. This commit adds lower bounds of type params to the somewheres. Motivated by: ``` scala> f"${42}" <console>:8: warning: a type was inferred to be `Any`; this may indicate a programming error. f"${42}" ^ res0: String = 42 ```
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Infer.scala11
-rw-r--r--test/files/neg/warn-inferred-any.check5
-rw-r--r--test/files/neg/warn-inferred-any.scala8
3 files changed, 21 insertions, 3 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
index a3f1da60ce..c793632de4 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
@@ -546,7 +546,14 @@ trait Infer extends Checkable {
val targs = solvedTypes(tvars, tparams, tparams map varianceInTypes(formals), upper = false, lubDepth(formals) max lubDepth(argtpes))
// Can warn about inferring Any/AnyVal as long as they don't appear
// explicitly anywhere amongst the formal, argument, result, or expected type.
- def canWarnAboutAny = !(pt :: restpe :: formals ::: argtpes exists (t => (t contains AnyClass) || (t contains AnyValClass)))
+ // ...or lower bound of a type param, since they're asking for it.
+ def canWarnAboutAny = {
+ val loBounds = tparams map (_.info.bounds.lo)
+ val hasAny = pt :: restpe :: formals ::: argtpes ::: loBounds exists (t =>
+ (t contains AnyClass) || (t contains AnyValClass)
+ )
+ !hasAny
+ }
def argumentPosition(idx: Int): Position = context.tree match {
case x: ValOrDefDef => x.rhs match {
case Apply(fn, args) if idx < args.size => args(idx).pos
@@ -554,7 +561,7 @@ trait Infer extends Checkable {
}
case _ => context.tree.pos
}
- if (settings.warnInferAny.value && context.reportErrors && canWarnAboutAny) {
+ if (settings.warnInferAny && context.reportErrors && canWarnAboutAny) {
foreachWithIndex(targs) ((targ, idx) =>
targ.typeSymbol match {
case sym @ (AnyClass | AnyValClass) =>
diff --git a/test/files/neg/warn-inferred-any.check b/test/files/neg/warn-inferred-any.check
index 4628033e55..8ad81d1529 100644
--- a/test/files/neg/warn-inferred-any.check
+++ b/test/files/neg/warn-inferred-any.check
@@ -7,6 +7,9 @@ warn-inferred-any.scala:16: warning: a type was inferred to be `AnyVal`; this ma
warn-inferred-any.scala:17: warning: a type was inferred to be `AnyVal`; this may indicate a programming error.
{ 1l to 5l contains 5d }
^
+warn-inferred-any.scala:25: warning: a type was inferred to be `Any`; this may indicate a programming error.
+ def za = f(1, "one")
+ ^
error: No warnings can be incurred under -Xfatal-warnings.
-three warnings found
+four warnings found
one error found
diff --git a/test/files/neg/warn-inferred-any.scala b/test/files/neg/warn-inferred-any.scala
index b853e6e5a8..693c33e7be 100644
--- a/test/files/neg/warn-inferred-any.scala
+++ b/test/files/neg/warn-inferred-any.scala
@@ -17,3 +17,11 @@ trait Ys[+A] {
{ 1l to 5l contains 5d }
{ 1l to 5l contains 5l }
}
+
+trait Zs {
+ def f[A](a: A*) = 42
+ def g[A >: Any](a: A*) = 42 // don't warn
+
+ def za = f(1, "one")
+ def zu = g(1, "one")
+}