New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add -Wnonunit-statement
to warn about discarded values in statement position
#9893
Add -Wnonunit-statement
to warn about discarded values in statement position
#9893
Conversation
abe01d8
to
ac7478d
Compare
Update to handle Typing the user expression yields the block, so additional work would be needed to copy attachments from the explicit apply to the implicit. |
I haven't seen so many yellow thumbs since my last all-day Simpsons-watching marathon. Looks like this will be popular if you can finish it. |
It's a bit niggling, but the warm reception means I can't stop at mile 18 despite the pain in my side. |
This comment has been hidden.
This comment has been hidden.
This comment has been hidden.
This comment has been hidden.
This comment has been hidden.
This comment has been hidden.
This comment has been hidden.
This comment has been hidden.
This comment has been hidden.
This comment has been hidden.
This comment has been hidden.
This comment has been hidden.
ac7478d
to
28a7770
Compare
It would be nice to provide an audit of Also a sibling option for I just needed that feature, A method was used a few times but only one warned because I'd previously slapped on the What should the output look like? Just turning off suppression could result in many errors. Possibly specify a region of audit using Or a general mechanism |
28a7770
to
20bcb8e
Compare
20bcb8e
to
f33a40e
Compare
This comment has been hidden.
This comment has been hidden.
2d26b75
to
1cd6506
Compare
This comment has been hidden.
This comment has been hidden.
1cd6506
to
4f94491
Compare
This comment has been hidden.
This comment has been hidden.
4f94491
to
6b5adcc
Compare
This will require re-tweaks, as it still yields what I assume are spurious warnings on the standard library.
Probably because it doesn't have a getter.
|
It still nags at me that the distinction between (Less importantly, I'm having doubts about whether we want to use the word "statement" in the flag name and documentation. And namingwise, I guess "statement" bothers me because it seems like importing terminology from other programming languages outside of the functional tradition. In Scala, a few things like |
I would distinguish They are statements when in statement position. The spec for "block" calls them statements, for example. Maybe time for a neologism. Blockpression. Exstatement. I'll tear myself away from Fringe season 5 to update the message with the fine suggestions to suggest something. Edit: OK, I figured out that I was confusing Georgina Haig from Fringe and Katherine McNamara from Arrow, they both play daughter heroines in the future. |
Okay, I'll take that (but perhaps we'll merge them Someday
Touché. I yield! (https://scala-lang.org/files/archive/spec/2.13/06-expressions.html#blocks) |
|
|
Question: this warns - should it count as a Unit
ascription?
class C {
def f(x: Int): Int = 1 + x
def g: Unit = f(0)
}
receiver match { | ||
case Apply(_, _) => Precedence(op.decoded).level == 0 // xs(i) += x | ||
case _ => receiver.symbol != null && | ||
(receiver.symbol.isGetter || receiver.symbol.isField) // xs.addOne(x) for var xs |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This part I don't understand... I don't see anything about var
or addOne
.
IIUC, it catches any method call on a field, no?
How about calls on local values / variables?
Also addOne
and +=
are defined with return type this.type
- why do you need to handle them separately?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If a value is not stable, in v().addOne(x)
, I can witness different values in v()
and the result. I think that is the gist of why, even if addOne
is side-effecting and returns this
, I've lost the value produced by v
; I can't assume I can recover it by calling v
again.
I see a test class Variant
. I'll add more variants to ensure this check is not too wide a net. I think it applies only to this
-typed methods. But is that even correct? I'm sure I noticed it by testing on this code base. But maybe v.addOne(x)
is bad form.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just took this for a spin on Skunk. Only two (spurious?) warnings!
Seems like the issue is the |
37e12e1
to
68080c2
Compare
The Skunk warning is due to this call in the expansion. I added a commit that tweaks the signature, which may pass MiMA. There are probably other bits of reflect API that deserve similar tweaking.
|
@lrytz As to whether explicit result type means "I intend to discard on RHS", I think the answer is no, because Explicit result types are supplied often: to specify API, or to accommodate recursion. I like the "transposed" form:
which is somewhat equivalent but does show "intention to discard", and also is not redundant. |
2918434
to
d07263e
Compare
receiver match { | ||
case Apply(_, _) => Precedence(op.decoded).level == 0 // xs(i) += x | ||
case _ => receiver.symbol != null && | ||
(receiver.symbol.isGetter || receiver.symbol.isField) // xs.addOne(x) for var xs |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
needs rebase @som-snytt is #9893 (comment) considered resolved? |
Since I have to rebase anyway, sigh, I'll add a code comment where lrytz had to read it twice. I had to read it more than that. Edit: instead of a comment, added self-documenting method name. |
d6a03c9
to
d261352
Compare
needs checkfile update, looks like. once CI likes it let's merge |
because the other warning jumped the queue, need to update on the first commit
|
Warn about any interesting value in statement position, for some definition of interest. Generalizes the current warning for "pure" expressions. By default, warns about unibranch if, which lack an else in user code. Specify -Wnonunit-if:false to turn off warning about unibranch if. (That also turns off -Wvalue-discard for those cases.) Improve explicit Unit check Accommodate field when method is this.type Handle Match
d261352
to
9fe44e8
Compare
|
Is there a chance that we will have something like this in Dotty? |
Summary
New compiler option
-Wnonunit-statement
warns about any interesting expression whose value is ignored because it is followed by another expression.The new warnings are not included in
-Xlint
; they must be separately enabled with-Wnonunit-statement
. Users of-Wnonunit-statement
may also wish to enable a related option,-Wvalue-discard
.Example
How to silence
The warning can be suppressed at a particular site by explicit ascription:
e: Unit
. This is the same convention used to ignore warnings about "value discard" conversions.As always, any warning is also suppressible with
@nowarn
.Relation to other warnings
This generalizes the current warning for "pure" expressions, which only warns for limited cases where the expression can be proved not to be side-effecting.
-Wvalue-discard
remains separate. It warns only when a value is discarded because it's the final expression in a block whose expected type isUnit
, as specified by the language.Details on what warns or doesn't
"Statement position" means statements in templates (i.e., constructors) and statements in blocks (everything in a block except the result expression). If a statement is an expression (and not a definition or assignment), then
-Wnonunit-statement
warns if the type of the expression is notUnit
. There are heuristic exceptions, such as for methods that returnthis.type
, where there is no loss of information. (The method is inherently side-effecting.) There is an additional flag whether to take anif
statement as side-effecting, so that its result can be ignored.By default, warns about
if
withoutelse
. Specify-Wnonunit-if:false
to turn that off. (That also turns off-Wvalue-discard
for those cases.)The heuristic for
this.type
-returning methods intends to accommodate usual idioms updating unstable values.Motivation
As requested on Discord!
This is especially useful in pure-functional code where it's unusual for values ever to be intentionally discarded.