49

I have added the scalac command line argument -Ywarn-value-discard to my build because this would have caught a subtle bug that I just found in my code. However, I now get some warnings for "discarded non-Unit value" that are about intentional discards, not bugs. How do I suppress those warnings?

Robin Green
  • 32,079
  • 16
  • 104
  • 187

3 Answers3

69

You suppress these warning by explictly returning unit (that is ()). By example turn this:

def method1() = {
   println("Hello")
   "Bye"
}
def method2() {
  method1() // Returns "Bye", which is implicitly discarded
}

into:

def method1() = {
   println("Hello")
   "Bye"
}
def method2() {
  method1()
  () // Explicitly return unit
}
Régis Jean-Gilles
  • 32,541
  • 5
  • 83
  • 97
  • don't you discard _non-Unit value_ when calling `method1` in `method2`? – botchniaque Nov 30 '16 at 08:55
  • 2
    The first snippet illustrates a case that **does** trigger the warning (when `-Ywarn-value-discard` is enabled), so yes indeed in this case a non-unit value (the return value of `method1`) is discarded when calling `method1` in `method2`. The second snippet explicitly returns "unit" (in other words `()`), thereby removing the warning. – Régis Jean-Gilles Nov 30 '16 at 09:07
25

According to this answer, you can also use the syntax val _, i.e.

def method2(): Unit = {
  val _ = method1()
}

But there is some dispute over whether this or the answer by @Régis is the preferred style.

Community
  • 1
  • 1
Todd Owen
  • 15,650
  • 7
  • 54
  • 52
  • 1
    Would be `method1() match { case _ => }` acceptable as well? – Netsu May 31 '18 at 12:27
  • I had issue with this solution where you need for instance: `val _ = rdd1.unpersist()` and the line below it `val _ = rdd2.unpersist()` the compiler says that the value `_` have already been defined – Wonay Oct 22 '18 at 21:49
  • 1
    @Wonay: Only the _last_ line of a method needs this treatment, so there is no need to turn the line above it into an assignment. In more detail: `-Ywarn-value-discard` does not issue warnings for merely ignoring non-Unit values. "Value discarding" as defined in [section 6.26.1](https://www.scala-lang.org/files/archive/spec/2.11/06-expressions.html#value-discarding) of the language spec is specifically about a value appearing _where Unit is expected_, for example as the return value of a method. – Todd Owen Oct 23 '18 at 14:07
  • Ah ok, I think it is because I am using the one from ScalaStyle – Wonay Oct 23 '18 at 18:08
7

Now you can suppress value-discard warning via type ascription to Unit in Scala 2.13.

This is an example:

def suppressValueDiscard(): Unit =
  "": Unit
Régis Jean-Gilles
  • 32,541
  • 5
  • 83
  • 97
floating cat
  • 678
  • 7
  • 11
  • 1
    @nafg The `: Unit` can still suppress that warning in the Scala 2.13.2. But this feature won't work in some cases like https://github.com/scala/scala/pull/7563#issuecomment-460419680. I guess you may experience the same cases, or you just find a bug in Scalac. – floating cat May 17 '20 at 14:10