diff options
author | Som Snytt <som.snytt@gmail.com> | 2014-08-20 10:25:28 -0700 |
---|---|---|
committer | Som Snytt <som.snytt@gmail.com> | 2014-09-05 01:07:44 -0700 |
commit | c9ec916f20c4f06a0aebe0a9929443c1c8b60c5c (patch) | |
tree | 9c592c054af335510d57fa2ff3fc0e733f8953a1 | |
parent | d4b5c7b95de88d3890be654e06da812c6eb607f5 (diff) | |
download | scala-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.scala | 11 | ||||
-rw-r--r-- | test/files/neg/warn-inferred-any.check | 5 | ||||
-rw-r--r-- | test/files/neg/warn-inferred-any.scala | 8 |
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") +} |