summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2009-10-22 01:01:04 +0000
committerPaul Phillips <paulp@improving.org>2009-10-22 01:01:04 +0000
commit3bd3ae75dae560a307c818515d79a0a4ebe67d41 (patch)
treeeb6e09c1eabf3feaf63c5490759798b3b6830515 /src
parentdc64c686606f8dde6be4d5ff185806331c693842 (diff)
downloadscala-3bd3ae75dae560a307c818515d79a0a4ebe67d41.tar.gz
scala-3bd3ae75dae560a307c818515d79a0a4ebe67d41.tar.bz2
scala-3bd3ae75dae560a307c818515d79a0a4ebe67d41.zip
Another warning for -Xstrict-warnings.
beloved try/catch blocks which swallow all comers. Realized that two warnings are already one too many to combine under a single option, and broke them out into individual options.
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/Settings.scala15
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreeInfo.scala13
-rw-r--r--src/compiler/scala/tools/nsc/transform/UnCurry.scala5
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala4
4 files changed, 30 insertions, 7 deletions
diff --git a/src/compiler/scala/tools/nsc/Settings.scala b/src/compiler/scala/tools/nsc/Settings.scala
index c85242f937..ed7b745bef 100644
--- a/src/compiler/scala/tools/nsc/Settings.scala
+++ b/src/compiler/scala/tools/nsc/Settings.scala
@@ -761,7 +761,6 @@ trait ScalacSettings {
val Xhelp = BooleanSetting ("-X", "Print a synopsis of advanced options")
val assemname = StringSetting ("-Xassem", "file", "Name of the output assembly (only relevant with -target:msil)", "").dependsOn(target, "msil")
val assemrefs = StringSetting ("-Xassem-path", "path", "List of assemblies referenced by the program (only relevant with -target:msil)", ".").dependsOn(target, "msil")
- val Xchecknull = BooleanSetting ("-Xcheck-null", "Emit warning on selection of nullable reference")
val checkInit = BooleanSetting ("-Xcheckinit", "Add runtime checks on field accessors. Uninitialized accesses result in an exception being thrown.")
val noassertions = BooleanSetting ("-Xdisable-assertions", "Generate no assertions and assumptions")
val elideLevel = IntSetting ("-Xelide-level", "Generate calls to @elidable-marked methods only method priority is greater than argument.",
@@ -790,7 +789,6 @@ trait ScalacSettings {
val Xshowobj = StringSetting ("-Xshow-object", "object", "Show object info", "")
val showPhases = BooleanSetting ("-Xshow-phases", "Print a synopsis of compiler phases")
val sourceReader = StringSetting ("-Xsource-reader", "classname", "Specify a custom method for reading source files", "scala.tools.nsc.io.SourceReader")
- val Xwarninit = BooleanSetting ("-Xwarninit", "Warn about possible changes in initialization semantics")
val newArrays = BooleanSetting ("-Ynewarrays", "Generate code for new array scheme")
/**
@@ -827,15 +825,24 @@ trait ScalacSettings {
ChoiceSetting ("-Ystruct-dispatch", "Selects dispatch method for structural refinement method calls",
List("no-cache", "mono-cache", "poly-cache", "invoke-dynamic"), "poly-cache") .
withHelpSyntax("-Ystruct-dispatch:<method>")
- val Xwarndeadcode = BooleanSetting ("-Ywarn-dead-code", "Emit warnings for dead code")
val specialize = BooleanSetting ("-Yspecialize", "Specialize generic code on types.")
val Yrangepos = BooleanSetting ("-Yrangepos", "Use range positions for syntax trees.")
val Yidedebug = BooleanSetting ("-Yide-debug", "Generate, validate and output trees using the interactive compiler.")
val Ytyperdebug = BooleanSetting ("-Ytyper-debug", "Trace all type assignements")
val Ypmatdebug = BooleanSetting ("-Ypmat-debug", "Trace all pattern matcher activity.")
- val Xwarnings = BooleanSetting ("-Xstrict-warnings", "Emit extra (usually spurious) warnings.")
val Ytailrec = BooleanSetting ("-Ytailrecommend", "Alert methods which would be tail-recursive if private or final.")
+ // Warnings
+ val Xwarninit = BooleanSetting ("-Xwarninit", "Warn about possible changes in initialization semantics")
+ val Xchecknull = BooleanSetting ("-Xcheck-null", "Emit warning on selection of nullable reference")
+ val Xwarndeadcode = BooleanSetting ("-Ywarn-dead-code", "Emit warnings for dead code")
+ val YwarnShadow = BooleanSetting ("-Ywarn-shadowing", "Emit warnings about possible variable shadowing.")
+ val YwarnCatches = BooleanSetting ("-Ywarn-catches", "Emit warnings about catch blocks which catch everything.")
+ val Xwarnings = BooleanSetting ("-Xstrict-warnings", "Emit warnings about lots of things.") .
+ withPostSetHook(() =>
+ List(YwarnShadow, YwarnCatches, Xwarndeadcode, Xwarninit) foreach (_.value = true)
+ )
+
/**
* -P "Plugin" settings
*/
diff --git a/src/compiler/scala/tools/nsc/ast/TreeInfo.scala b/src/compiler/scala/tools/nsc/ast/TreeInfo.scala
index 28fb914f11..6a8f653ac4 100644
--- a/src/compiler/scala/tools/nsc/ast/TreeInfo.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreeInfo.scala
@@ -20,6 +20,7 @@ abstract class TreeInfo {
val trees: SymbolTable
import trees._
+ import definitions.ThrowableClass
def isTerm(tree: Tree): Boolean = tree.isTerm
def isType(tree: Tree): Boolean = tree.isType
@@ -238,6 +239,16 @@ abstract class TreeInfo {
case _ => false
}
+ /** Does this CaseDef catch Throwable? */
+ def catchesThrowable(cdef: CaseDef) = catchesAllOf(cdef, ThrowableClass.tpe)
+
+ /** Does this CaseDef catch everything of a certain Type? */
+ def catchesAllOf(cdef: CaseDef, threshold: Type) =
+ isDefaultCase(cdef) || (cdef.guard.isEmpty && (unbind(cdef.pat) match {
+ case Typed(Ident(nme.WILDCARD), tpt) => (tpt.tpe != null) && (threshold <:< tpt.tpe)
+ case _ => false
+ }))
+
/** Is this pattern node a catch-all or type-test pattern? */
def isCatchCase(cdef: CaseDef) = cdef match {
case CaseDef(Typed(Ident(nme.WILDCARD), tpt), EmptyTree, _) =>
@@ -251,7 +262,7 @@ abstract class TreeInfo {
private def isSimpleThrowable(tp: Type): Boolean = tp match {
case TypeRef(pre, sym, args) =>
(pre == NoPrefix || pre.widen.typeSymbol.isStatic) &&
- (sym isNonBottomSubClass definitions.ThrowableClass) && /* bq */ !sym.isTrait
+ (sym isNonBottomSubClass ThrowableClass) && /* bq */ !sym.isTrait
case _ =>
false
}
diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
index 24c5493858..96e40f1fe5 100644
--- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala
+++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
@@ -636,6 +636,11 @@ abstract class UnCurry extends InfoTransform with TypingTransformers {
}
treeCopy.DefDef(tree, mods, name, tparams, List(List.flatten(vparamss)), tpt, rhs1)
case Try(body, catches, finalizer) =>
+ // If warnings are enabled, alert about promiscuously catching cases.
+ if (settings.YwarnCatches.value)
+ for (cd <- catches find treeInfo.catchesThrowable)
+ unit.warning(cd.pos, "catch clause swallows everything: not advised.")
+
if (catches forall treeInfo.isCatchCase) tree
else {
val exname = unit.fresh.newName(tree.pos, "ex$")
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index b81c087901..269e9ca938 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -1651,7 +1651,7 @@ trait Typers { self: Analyzer =>
// catches method parameters shadowing identifiers declared in the same file, so more
// work is needed. Most of the code here is to filter out false positives.
def isAuxConstructor(sym: Symbol) = sym.isConstructor && !sym.isPrimaryConstructor
- if (settings.Xwarnings.value && !isAuxConstructor(ddef.symbol)) {
+ if (settings.YwarnShadow.value && !isAuxConstructor(ddef.symbol)) {
for (v <- ddef.vparamss.flatten ; if v.symbol != null && !(v.symbol hasFlag SYNTHETIC))
checkShadowings(v, (sym => !sym.isDeferred && !sym.isMethod))
}
@@ -1752,7 +1752,7 @@ trait Typers { self: Analyzer =>
while ((e ne null) && (e.sym ne stat.symbol)) e = e.tail
if (e eq null) context.scope.enter(stat.symbol)
}
- if (settings.Xwarnings.value) checkShadowings(stat)
+ if (settings.YwarnShadow.value) checkShadowings(stat)
enterLabelDef(stat)
}
val stats1 = typedStats(block.stats, context.owner)