From a3c7b7753f3955c58df5d0f4b29d7d25c4820e61 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 | 12 ++-- .../dotty/tools/dotc/config/Settings.scala | 19 +++++- tests/neg/i18559.scala | 67 +++++++++++++++++++ 3 files changed, 93 insertions(+), 5 deletions(-) create mode 100644 tests/neg/i18559.scala diff --git a/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala b/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala index 3dbfbfc6bab9..69bbbda5e8c4 100644 --- a/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala +++ b/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala @@ -159,10 +159,11 @@ private sealed trait WarningSettings: import Setting.ChoiceWithHelp 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 WvalueDiscard: Setting[Boolean] = BooleanSetting("-Wvalue-discard", "Warn when non-Unit expression results are unused.").overrideWith(Wall) + val WNonUnitStatement = BooleanSetting("-Wnonunit-statement", "Warn when block statements are non-Unit expressions.").overrideWith(Wall) + val WimplausiblePatterns = BooleanSetting("-Wimplausible-patterns", "Warn if comparison with a pattern value looks like it might always fail.").overrideWith(Wall) val Wunused: Setting[List[ChoiceWithHelp[String]]] = MultiChoiceHelpSetting( name = "-Wunused", helpArg = "warning", @@ -194,7 +195,10 @@ private sealed trait WarningSettings: ) ), default = Nil - ) + ).overrideWith(Wall, { + case true => List(ChoiceWithHelp("all", "")) + case false => Nil + }) 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 34e5582e8a91..75981e8c1edd 100644 --- a/compiler/src/dotty/tools/dotc/config/Settings.scala +++ b/compiler/src/dotty/tools/dotc/config/Settings.scala @@ -63,10 +63,27 @@ object Settings: aliases: List[String] = Nil, depends: List[(Setting[?], Any)] = Nil, propertyClass: Option[Class[?]] = None)(private[Settings] val idx: Int) { + + private var overridenBy: Option[Setting[_]] = None + private var overridenByMapper: Any => T = _ private var changed: Boolean = false - def valueIn(state: SettingsState): T = state.value(idx).asInstanceOf[T] + def valueIn(state: SettingsState): T = + overridenBy.map(_.valueIn(state)).map(overridenByMapper) + .getOrElse(state.value(idx).asInstanceOf[T]) + + def overrideWith(setting: Setting[T]): Setting[T] = { + overridenBy = Some(setting) + overridenByMapper = _.asInstanceOf[T] + this + } + + def overrideWith[A](setting: Setting[A], mapper: A => T): Setting[T] = { + overridenBy = Some(setting) + overridenByMapper = mapper.asInstanceOf[Any => T] + this + } def updateIn(state: SettingsState, x: Any): SettingsState = x match case _: T => state.update(idx, x) diff --git a/tests/neg/i18559.scala b/tests/neg/i18559.scala new file mode 100644 index 000000000000..da47fe65d14f --- /dev/null +++ b/tests/neg/i18559.scala @@ -0,0 +1,67 @@ +//> using options -Werror -Wall + +val b = // OK + var e3 = 2 // error + 1 + +object FooUnused: + import collection.mutable.Set // error + import collection.mutable.{Map => MutMap} // error + import collection.mutable._ // error + +object FooWildcardUnused: + import collection.mutable._ // error + +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 // error + // case Sum(a @ _,Z) => Z // todo : this should pass in the future + case Sum(a@S(_),Z) => Z // error + case Sum(a@S(_),Z) => a // OK + case Sum(a@S(b@S(_)), Z) => a // error + case Sum(a@S(b@S(_)), Z) => a // error + case Sum(a@S(b@(S(_))), Z) => Sum(a,b) // OK + case Sum(_,_) => Z // OK + case _ => Z // OK +} + +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()) // error + +def block(): Either[Failed, Unit] = { + firstThing().map(_ => secondThing()) // error +} + +class C { + import concurrent._ + import ExecutionContext.Implicits._ + def c = { + def improved = Future(42) + def stale = Future(27) + improved // error + stale + } +} \ No newline at end of file