From 6cdc2fe1a2d3d91e0b97171d4de8f968d730bc35 Mon Sep 17 00:00:00 2001 From: Szymon Rodziewicz Date: Mon, 2 Oct 2023 15:13:36 +0200 Subject: [PATCH] Add -Wall option --- .../tools/dotc/config/ScalaSettings.scala | 11 ++-- .../dotty/tools/dotc/config/Settings.scala | 19 +++++- tests/warn/i18559.check | 56 ++++++++++++++++ tests/warn/i18559.scala | 66 +++++++++++++++++++ 4 files changed, 146 insertions(+), 6 deletions(-) create mode 100644 tests/warn/i18559.check create mode 100644 tests/warn/i18559.scala diff --git a/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala b/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala index 85e6ebef751f..d07ca605b956 100644 --- a/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala +++ b/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala @@ -163,11 +163,12 @@ private sealed trait WarningSettings: self: SettingGroup => val Whelp: Setting[Boolean] = BooleanSetting("-W", "Print a synopsis of warning options.") + val Wall: Setting[Boolean] = BooleanSetting("-Wall", "Enable all warnings") val XfatalWarnings: Setting[Boolean] = BooleanSetting("-Werror", "Fail the compilation if there are any warnings.", aliases = List("-Xfatal-warnings")) - val WvalueDiscard: Setting[Boolean] = BooleanSetting("-Wvalue-discard", "Warn when non-Unit expression results are unused.") - val WNonUnitStatement = BooleanSetting("-Wnonunit-statement", "Warn when block statements are non-Unit expressions.") - val WimplausiblePatterns = BooleanSetting("-Wimplausible-patterns", "Warn if comparison with a pattern value looks like it might always fail.") - val WunstableInlineAccessors = BooleanSetting("-WunstableInlineAccessors", "Warn an inline methods has references to non-stable binary APIs.") + val WvalueDiscard: Setting[Boolean] = BooleanSetting("-Wvalue-discard", "Warn when non-Unit expression results are unused.").enableWith(Wall) + val WNonUnitStatement = BooleanSetting("-Wnonunit-statement", "Warn when block statements are non-Unit expressions.").enableWith(Wall) + val WimplausiblePatterns = BooleanSetting("-Wimplausible-patterns", "Warn if comparison with a pattern value looks like it might always fail.").enableWith(Wall) + val WunstableInlineAccessors = BooleanSetting("-WunstableInlineAccessors", "Warn an inline methods has references to non-stable binary APIs.").enableWith(Wall) val Wunused: Setting[List[ChoiceWithHelp[String]]] = MultiChoiceHelpSetting( name = "-Wunused", helpArg = "warning", @@ -199,7 +200,7 @@ private sealed trait WarningSettings: ) ), default = Nil - ) + ).enableWith(Wall, List(ChoiceWithHelp("all", ""))) object WunusedHas: def isChoiceSet(s: String)(using Context) = Wunused.value.pipe(us => us.contains(s)) def allOr(s: String)(using Context) = Wunused.value.pipe(us => us.contains("all") || us.contains(s)) diff --git a/compiler/src/dotty/tools/dotc/config/Settings.scala b/compiler/src/dotty/tools/dotc/config/Settings.scala index 79eb2b882f8f..38d9220ea8e0 100644 --- a/compiler/src/dotty/tools/dotc/config/Settings.scala +++ b/compiler/src/dotty/tools/dotc/config/Settings.scala @@ -64,10 +64,27 @@ object Settings: depends: List[(Setting[?], Any)] = Nil, ignoreInvalidArgs: Boolean = false, propertyClass: Option[Class[?]] = None)(private[Settings] val idx: Int) { + + private var enabledWith: Option[Setting[Boolean]] = None + private var enabledWithValue: T = _ private var changed: Boolean = false - def valueIn(state: SettingsState): T = state.value(idx).asInstanceOf[T] + def valueIn(state: SettingsState): T = + enabledWith.filter(_.valueIn(state)).map(_ => enabledWithValue) + .getOrElse(state.value(idx).asInstanceOf[T]) + + def enableWith(setting: Setting[Boolean])(using T =:= Boolean): Setting[T] = { + enabledWith = Some(setting) + enabledWithValue = true.asInstanceOf[T] + this + } + + def enableWith[A](setting: Setting[Boolean], value: T): Setting[T] = { + enabledWith = Some(setting) + enabledWithValue = value + this + } def updateIn(state: SettingsState, x: Any): SettingsState = x match case _: T => state.update(idx, x) diff --git a/tests/warn/i18559.check b/tests/warn/i18559.check new file mode 100644 index 000000000000..354385e78ebe --- /dev/null +++ b/tests/warn/i18559.check @@ -0,0 +1,56 @@ +-- [E176] Potential Issue Warning: tests/warn/i18559.scala:63:4 -------------------------------------------------------- +63 | improved // warn + | ^^^^^^^^ + | unused value of type (improved : => scala.concurrent.Future[Int]) +-- [E175] Potential Issue Warning: tests/warn/i18559.scala:51:35 ------------------------------------------------------- +51 | firstThing().map(_ => secondThing()) // warn + | ^^^^^^^^^^^^^ + | discarded non-Unit value of type Either[Failed, Unit] +-- [E175] Potential Issue Warning: tests/warn/i18559.scala:54:35 ------------------------------------------------------- +54 | firstThing().map(_ => secondThing()) // warn + | ^^^^^^^^^^^^^ + | discarded non-Unit value of type Either[Failed, Unit] +-- Warning: tests/warn/i18559.scala:4:6 -------------------------------------------------------------------------------- +4 | var e3 = 2 // warn + | ^^ + | unused local definition +-- Warning: tests/warn/i18559.scala:8:28 ------------------------------------------------------------------------------- +8 | import collection.mutable.Set // warn + | ^^^ + | unused import +-- Warning: tests/warn/i18559.scala:9:33 ------------------------------------------------------------------------------- +9 | import collection.mutable.{Map => MutMap} // warn + | ^^^^^^^^^^^^^ + | unused import +-- Warning: tests/warn/i18559.scala:10:28 ------------------------------------------------------------------------------ +10 | import collection.mutable._ // warn + | ^ + | unused import +-- Warning: tests/warn/i18559.scala:13:28 ------------------------------------------------------------------------------ +13 | import collection.mutable._ // warn + | ^ + | unused import +-- [E030] Match case Unreachable Warning: tests/warn/i18559.scala:31:10 ------------------------------------------------ +31 | case Sum(a@S(_),Z) => Z // warn + | ^^^^^^^^^^^^^ + | Unreachable case +-- [E030] Match case Unreachable Warning: tests/warn/i18559.scala:32:10 ------------------------------------------------ +32 | case Sum(a@S(_),Z) => a // warn unreachable + | ^^^^^^^^^^^^^ + | Unreachable case +-- [E030] Match case Unreachable Warning: tests/warn/i18559.scala:33:10 ------------------------------------------------ +33 | case Sum(a@S(b@S(_)), Z) => a // warn + | ^^^^^^^^^^^^^^^^^^^ + | Unreachable case +-- [E030] Match case Unreachable Warning: tests/warn/i18559.scala:34:10 ------------------------------------------------ +34 | case Sum(a@S(b@S(_)), Z) => a // warn + | ^^^^^^^^^^^^^^^^^^^ + | Unreachable case +-- [E030] Match case Unreachable Warning: tests/warn/i18559.scala:35:10 ------------------------------------------------ +35 | case Sum(a@S(b@(S(_))), Z) => Sum(a,b) // warn unreachable + | ^^^^^^^^^^^^^^^^^^^^^ + | Unreachable case +-- [E121] Pattern Match Warning: tests/warn/i18559.scala:37:7 ---------------------------------------------------------- +37 | case _ => Z // warn unreachable + | ^ + | Unreachable case except for null (if this is intentional, consider writing case null => instead). diff --git a/tests/warn/i18559.scala b/tests/warn/i18559.scala new file mode 100644 index 000000000000..8e9fb7408a04 --- /dev/null +++ b/tests/warn/i18559.scala @@ -0,0 +1,66 @@ +//> using options -Wall + +val b = // OK + var e3 = 2 // warn + 1 + +object FooUnused: + import collection.mutable.Set // warn + import collection.mutable.{Map => MutMap} // warn + import collection.mutable._ // warn + +object FooWildcardUnused: + import collection.mutable._ // warn + +object Foo: + import collection.mutable.Set // OK + import collection.mutable.{Map => MutMap} // OK + + val bar = Set() // OK + val baz = MutMap() // OK + +sealed trait Calc +sealed trait Const extends Calc +case class Sum(a: Calc, b: Calc) extends Calc +case class S(pred: Const) extends Const +case object Z extends Const + +val a = Sum(S(S(Z)),Z) match { + case Sum(a,Z) => Z // not warn: patvars not enabled by Wall + // case Sum(a @ _,Z) => Z // todo : this should pass in the future + case Sum(a@S(_),Z) => Z // warn + case Sum(a@S(_),Z) => a // warn unreachable + case Sum(a@S(b@S(_)), Z) => a // warn + case Sum(a@S(b@S(_)), Z) => a // warn + case Sum(a@S(b@(S(_))), Z) => Sum(a,b) // warn unreachable + case Sum(_,_) => Z // OK + case _ => Z // warn unreachable +} +import scala.util.{Either, Right, Left} +import scala.collection.mutable + +case class Failed(msg: String) + +def firstThing(): Either[Failed, Unit] = + Right(()) + +def secondThing(): Either[Failed, Unit] = + Left(Failed("whoops you should have flatMapped me")) + +def singleExpr(): Either[Failed, Unit] = + firstThing().map(_ => secondThing()) // warn + +def block(): Either[Failed, Unit] = { + firstThing().map(_ => secondThing()) // warn +} + +class C { + import concurrent._ + import ExecutionContext.Implicits._ + def c = { + def improved = Future(42) + def stale = Future(27) + improved // warn + stale + } +} \ No newline at end of file