How to deliberately ignore the result of a method?

Then you’d also need an idiom for “really, really discard.”

Besides @noReallyNoWarn, maybe e: Unit @nowarn would work.

Haha, the regular discard would work.

But I have code like

def likelyWillError(): MayErrorType =
  mayError:
    doThing
  mayError:
    doAnotherThing

and it doesn’t warn that the first is discarded.

Do you also have -Wnonunit-statement enabled?

Also I’d like to see a self-contained reproducer of the issue you’re talking about.

2 Likes

I had turned -Wnonunit-statement off because it warns about inlined code when some random bit of code somewhere inside the inline statement discards a value.

But then I forgot I did that, which explains why many things weren’t being caught. :person_facepalming:

Anyway, at least on 3.5, -Wnonunit-statement doesn’t interact as expected with inlining. Maybe that’s the actual problem.

Edit: the warning-from-within-inlined-code issue isn’t consistent. I never minimized that one. I probably should.

But I’m not sure this is the entire problem. Regular discard-warning doesn’t work well with a fluent style. If you use java.lang.StringBuilder, for example, append returns the StringBuilder just in case you want to use it with fluent style. But StringBuilder has internal mutability! It’s a pain to notate every single one as “no, I don’t care about this”.

An annotation that would let you mark things as “this value is important” would still be a big help, even if -Wnonunit-statement is on and either inlining is fixed or everyone writes their inline methods to be compatible.

Are you sure? -Wnonunit-statement does not warn on self-returning methods, to my knowledge. Such methods were exempted on purpose.

Yes, very sure. It doesn’t come up in a bare statement, but it comes up other places. Here’s an example: Scastie - An interactive playground for Scala.

(Three examples, actually.)

The correct behavior on Scala 2 is don’t warn for Java, and don’t warn for Scala StringBuilder because append returns this.type. (The signature was updated for this purpose.)

I don’t know whether the difference is intended.

Now that Scala 3 -Wconf supports origin filter, the warning should be issued with origin=java.lang.StringBuilder (if that is intended) to make it easy to turn off.

Turning warnings off on every fluent interface with origin isn’t really practical if you use more than a little Java. ByteBuffer, FileChannel, ZipEntry, etc. also use the pattern just within the standard Java library, and you’ll find more if you use other Java libraries.

Yes, that’s why I thought it futile to cope with Java API in the warning.

Not to argue for this method overmuch, but you could silence origin=java.*, those Wconf strings are patterns. (The official docs would escape the dot, java\.*. In Strings you need extra slashes, on the command line you need extra quotes, etc, etc.)

I’m sorry you need to use Java API. I realize you have superior coping mechanisms.

I suggest opening a ticket about Scala 3 not being up to Scala 2’s standard on this point.

I don’t know whether the difference is intended.

Well I don’t know for sure either, but it’s a good bet it wasn’t. I bet someone wanted to land the feature first and figure niceties like this could come alter.

I just noticed that -Wnonunit-statement is more careful (or less strict) about warning than -Wvalue-discard:

➜  ~ scala -Wvalue-discard -Wnonunit-statement
Welcome to Scala 2.13.15 (OpenJDK 64-Bit Server VM, Java 23).
Type in expressions for evaluation. Or try :help.

scala> def f(sb: java.lang.StringBuilder): Unit = sb.append("")
                                                           ^
       warning: discarded non-Unit value of type StringBuilder
def f(sb: StringBuilder): Unit

scala> def f(sb: java.lang.StringBuilder): Unit = { sb.append(""); () }
def f(sb: StringBuilder): Unit

scala> def f(i: Int): Unit = { i + 1; () }
                                 ^
       warning: unused value of type Int
def f(i: Int): Unit

scala>

The warnings use different words, but it might not be obvious which is which.

Note that -Wnonunit-statement will warn about discarded values if that other warning is off:

➜  ~ scala -Wnonunit-statement
Welcome to Scala 2.13.15 (OpenJDK 64-Bit Server VM, Java 23).
Type in expressions for evaluation. Or try :help.

scala> def f(i: Int): Unit = i + 1
                               ^
       warning: unused value of type Int
def f(i: Int): Unit

scala>