Skip to content
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

unused_results is stricter on Nightly and Beta than on Stable #44119

Closed
briansmith opened this issue Aug 28, 2017 · 30 comments
Closed

unused_results is stricter on Nightly and Beta than on Stable #44119

briansmith opened this issue Aug 28, 2017 · 30 comments
Labels
A-diagnostics Area: Messages for errors, warnings, and lints C-bug Category: This is a bug. final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. regression-from-stable-to-beta Performance or correctness regression from stable to beta. T-lang Relevant to the language team, which will review and decide on the PR/issue.
Milestone

Comments

@briansmith
Copy link
Contributor

briansmith commented Aug 28, 2017

This compiles fine on stable, but fails on nightly and beta:

https://play.rust-lang.org/?gist=9504fbb631c253be8e43bcb872524e0e&version=nightly

#![deny(unused_results)]

fn main() {
   let mut p = std::path::PathBuf::from("asdf");
   p.set_extension("foo");
}

Nightly results:

  Compiling playground v0.0.1 (file:///playground)
error: unused result
 --> src/main.rs:5:4
  |
5 |    p.set_extension("foo");
  |    ^^^^^^^^^^^^^^^^^^^^^^^
  |
note: lint level defined here
 --> src/main.rs:1:9
  |
1 | #![deny(unused_results)]
  |         ^^^^^^^^^^^^^^

error: aborting due to previous error

Regardless of whether the change in behavior is an intentional backward compatibility break, it should be documented in the release notes.

See also #43806.

@zackmdavis
Copy link
Member

This is specific to booleans. Not intentional. (I could see a case for the new behavior, but that doesn't matter; if we're going to change this, it should be on purpose.) Fix forthcoming (if it doesn't make the 1.21 beta branch cut, it would need to be backported). Very sorry for regression. 😞 😰 ☠️

zackmdavis added a commit to zackmdavis/rust that referenced this issue Aug 28, 2017
This, as rust-lang#43813, is due to the author of rust-lang#43728 (specifically,
3645b06) being a damnably contemptible fool. Before this entire
fiasco, we would return early from the unusedness late lints pass if
the type of the expression within the `hir::StmtSemi` was `!`, `()`,
or a boolean: these types would never get to the point of being marked
as unused results. That is, until the dunce who somehow (!?) came to
be trusted with the plum responsibility of implementing RFC
1940 (`#[must_use]` for functions) went and fouled everything up,
removing the early returns based on the (stupid) thought that there
would be no harm in it, since we would need to continue to check these
types being returned from must_use functions (which was true for the
booleans, at least). But there was harm—harm that any
quarter-way-competent programmer would have surely forseen! For after
the new functional-must-use checks, there was nothing to stop the
previously-returned-early types from falling through to be marked by
the unused-results lint!—a monumentally idiotic error that has cost
the project tens of precious developer- and reviewer-minutes dealing
with the fallout here and in rust-lang#43813.

If 3645b06 is representative of the standard of craftsmanship the
rising generation of software engineers holds themselves to, I weep
for the future of our technological civilization.

Resolves rust-lang#44119.
@alexcrichton alexcrichton added the regression-from-stable-to-nightly Performance or correctness regression from stable to nightly. label Aug 28, 2017
@eddyb
Copy link
Member

eddyb commented Aug 28, 2017

FWIW lint changes are not considered backwards-compatibility breaking.
cc @rust-lang/lang

@whitequark
Copy link
Member

whitequark commented Aug 28, 2017

@eddyb Then we should mention that Rust's (or perhaps rustc's?) backwards compatibility guarantee only holds with --cap-lints warn. It's the default in Cargo for non-root crates, but root crates could still result in breakage on rustc updates if e.g. compiled by scripts.

@eddyb
Copy link
Member

eddyb commented Aug 28, 2017

@whitequark Yeah, --cap-lints is a relatively new trick and the stability document (I don't even know where to look for it - I think it was an RFC) should be updated if it hasn't been already.

@briansmith
Copy link
Contributor Author

@alexcrichton This isn't just a regression from stable to nightly, it is a regression from stable to beta.

FWIW lint changes are not considered backwards-compatibility breaking.

OTOH, this is probably the most common lint for which #[deny(...)] and #[forbid(...)] are used.

@eddyb
Copy link
Member

eddyb commented Aug 28, 2017

@briansmith As @whitequark mentioned above, lints can't break dependencies from compiling.

@arielb1
Copy link
Contributor

arielb1 commented Aug 28, 2017

1.21 is now beta - this needs to be backported.

@est31
Copy link
Member

est31 commented Aug 28, 2017

I think this issue is treated wrongly by reverting behaviour (#44122). Rustc needs the ability to add and remove lints in any way wanted, otherwise there won't be any improvement of lints in the future.

E.g. I've seen the "unused_mut" lint become more powerful, it detected some non required mut annotations. Why shouldn't it be possible to improve it? Stability? If you say #![deny(lint)] you give up that stability guarantee, except if its some very obvious thing like unsafe.

Of course though, @zackmdavis is right, a lint change should be done knowingly and on purpose.

@alexcrichton alexcrichton added regression-from-stable-to-beta Performance or correctness regression from stable to beta. regression-from-stable-to-nightly Performance or correctness regression from stable to nightly. and removed regression-from-stable-to-nightly Performance or correctness regression from stable to nightly. labels Aug 28, 2017
@carols10cents carols10cents changed the title unused_results is stricter on Nightly than on Beta or Stable unused_results is stricter on Nightly and Beta than on Stable Aug 28, 2017
@carols10cents carols10cents added A-diagnostics Area: Messages for errors, warnings, and lints T-lang Relevant to the language team, which will review and decide on the PR/issue. C-bug Category: This is a bug. labels Aug 28, 2017
@nikomatsakis
Copy link
Contributor

Wait, I am a bit confused. The unused_results lint is something that warns whenever a function calls result is not used? And it doesn't warn about booleans? That surprises me a bit (in fact, I was not aware of this lint in general). But handling bool does feel more like a bug fix to the lint -- how did it come about?

@zackmdavis
Copy link
Member

how did it come about?

The booleans-are-not-unused-results behavior dates back to the introduction of the (default allow) lint itself in the 0.10 timeframe. No explicit justification seems to be given, although one might imagine that APIs that do something and return a bool that the caller is likely to not care about (e.g., HashSet::insert) were considered common enough to merit special treatment? The regression (because it was unintended, I don't think it's prejudicial to call it a regression) was in #43728.

@withoutboats
Copy link
Contributor

withoutboats commented Aug 28, 2017

Can I get confirmation that I understand the situation? My impression is that #43728 was an incorrect implementation of rust-lang/rfcs#1940.

The unused_results lint is only triggered on types which have been tagged #[must_use]. The boolean primitive has never been considered a #[must_use] type; this isn't because boolean was missed by the lint or anything, but because we intentionally opt into the types we use with this lint, and bool has never been one of them.

What we agreed was to allow you to tag specific functions with #[must_use], and to tag PartialEq::eq in that way. Until we decide otherwise, only PartialEq::eq should raise this lint, not any other function that returns bool.

Unless I've misunderstood the situation, it seems to me that we need to backport the revert because we have not decided to consider bool a must_use type.

@briansmith
Copy link
Contributor Author

@withoutboats That's my understanding; i.e. the fix for this should be in 1.20 that is being released this week.

@withoutboats
Copy link
Contributor

@briansmith Agreed. I just want to make the distinction that we can add new lints (in particular, we agreed to add this lint to ==), we just haven't decided to add the lint that's been added by mistake.

@zackmdavis
Copy link
Member

@withoutboats

Can I get confirmation that I understand the situation?

Almost (skip or skim details below if uninterested)—

My impression is that #43728 was an incorrect implementation of rust-lang/rfcs#1940.

Yes.

The unused_results lint is only triggered on types which have been tagged #[must_use].

Not quite. There are two relevant lints here: unused_must_use (which defaults to warn), and unused_results (which defaults to allow, which is why no one has heard of it), which both get set during the same lint pass. The first, unused_must_use, triggers for for unused types—and now, with the fn_must_use feature flag, return values of functions annotated with #[must_use]. Whereas the historical behavior of unused_results has been to trigger for all unused values that didn't already trigger unused_must_use, except for values of the types !, (), or bool. (I'm not aware of this detailed behavior of unused_results being documented anywhere.) #43728 unintentionally stopped exempting !, (), and bool from unused_results, but the old behavior has been or is being restored in #43813 (landed, for ! and ()) and #44122 (r+'d, and the beta-backport at issue, for bool) because no one had intended to modify the relatively obscure unused_results lint in the first place.

and to tag PartialEq::eq in that way. Until we decide otherwise, only PartialEq::eq should raise this lint

The libs team has also approved must_use for the other comparison methods (implemented in f5ac228). This is less consequential than you might think, because unfortunately—and contrary to the assumptions of many of the RFC discussants—making the comparison methods must_use doesn't automatically trigger lints for the much more common comparison operators (unless anyone has any alternative implementation ideas that would do so??). #44103 is currently open to also lint the operators (under the same fn_must_use feature flag).

@withoutboats
Copy link
Contributor

@zackmdavis Oh wow! I was unaware of this default-allow lint, that explains how no one found this.

Its unfortunate this was found so close to the release; I'd like to consider whether its actually worth backporting a revert but we only have a day or two to decide what to do.

frewsxcv added a commit to frewsxcv/rust that referenced this issue Aug 29, 2017
…_results, r=eddyb

un-regress behavior of `unused_results` lint for booleans

Resolves rust-lang#44119.
@briansmith
Copy link
Contributor Author

@zackmdavis Oh wow! I was unaware of this default-allow lint, that explains how no one found this.

Its unfortunate this was found so close to the release; I'd like to consider whether its actually worth backporting a revert but we only have a day or two to decide what to do.

I was confusing unused_results with unused_must_use above, especially when I said that it is one of the lints that #![deny]/#![forbid] are most frequently used for. For unused_results, I actually do think it is reasonable to warn on unused bool results and I wouldn't mind if it were decided that the new behavior is correct. I already updated my code to build on 1.20 as it exists today anyway.

@eddyb
Copy link
Member

eddyb commented Aug 29, 2017

Wait now I'm curious, what is unused_results, if not unused_must_use? Is it allow by default by any chance?

@sfackler
Copy link
Member

unused_results warns on every non unit return type like gcc's -Wunused-result.

@withoutboats
Copy link
Contributor

withoutboats commented Aug 29, 2017

@eddyb It appears that unused_results is a lint that treats every type except (), !, and bool as must_use. I don't have any idea why bool has been excepted from this.

@withoutboats
Copy link
Contributor

@rfcbot fcp close

I want to propose we treat this as a bugfix in the unused_result lint (hence closing this issue). We kind of have to decide within the next 24 hours, but I'll try to bring it to everyone's attention tomorrow.

@zackmdavis
Copy link
Member

I don't have any idea why bool has be excepted from [unused_results].

@alexcrichton might remember?

@rfcbot
Copy link

rfcbot commented Aug 29, 2017

Team member @withoutboats has proposed to close this. The next step is review by the rest of the tagged teams:

No concerns currently listed.

Once these reviewers reach consensus, this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!

See this document for info about what commands tagged team members can give me.

@rfcbot rfcbot added the proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. label Aug 29, 2017
@eddyb
Copy link
Member

eddyb commented Aug 29, 2017

We kind of have to decide within the next 24 hours

I thought @alexcrichton was talking about beta being already branched off somewhere else?

@nikomatsakis
Copy link
Contributor

@zackmdavis

First, thanks for the detailed summary.

With respect to the question at hand, I personally consider exempting bool from the lint to be a bug -- I feel like the whole point of the lint is to be pedantic, and bool is one of the exact types where I would most want this lint, precisely because it's the kind of type that people sometimes return as an error indicator but which also has many other uses (similar to Option but unlike, say, Result). That said, I personally never use the lint in practice, and I certainly see the value in preserving existing behavior absent an affirmative decision to change it.

Anyway, on a different topic:

doesn't automatically trigger lints for the much more common comparison operators (unless anyone has any alternative implementation ideas that would do so??

I can probably help with this. =) Where should I comment? (Tracking issue?)

frewsxcv added a commit to frewsxcv/rust that referenced this issue Aug 29, 2017
…_results, r=eddyb

un-regress behavior of `unused_results` lint for booleans

Resolves rust-lang#44119.
@alexcrichton
Copy link
Member

I don't have any idea why bool has be excepted from [unused_results].

@alexcrichton might remember?

Nothing like trying to remember a commit from three years ago! Nah unfortunately though I don't remember why bool was excepted. Your explanation above though, sounds like the most plausible reason!


We kind of have to decide within the next 24 hours

I thought @alexcrichton was talking about beta being already branched off somewhere else?

Yes beta branched a few days ago so this, but with the current disposition to close I don't think we're going to backport/stop anything at this point.

frewsxcv added a commit to frewsxcv/rust that referenced this issue Aug 29, 2017
…_results, r=eddyb

un-regress behavior of `unused_results` lint for booleans

Resolves rust-lang#44119.
frewsxcv added a commit to frewsxcv/rust that referenced this issue Aug 29, 2017
…_results, r=eddyb

un-regress behavior of `unused_results` lint for booleans

Resolves rust-lang#44119.
arielb1 pushed a commit to arielb1/rust that referenced this issue Aug 29, 2017
…_results, r=eddyb

un-regress behavior of `unused_results` lint for booleans

Resolves rust-lang#44119.
@zackmdavis
Copy link
Member

@nikomatsakis

doesn't automatically trigger lints for the much more common comparison operators (unless anyone has any alternative implementation ideas that would do so??

I can probably help with this. =) Where should I comment? (Tracking issue?)

Tracking issue is #43302, although I would argue that the currently-unreviewed #44103 (having the lint look at the operators) adequately solves the problem even if it's not the "automatic" implementation folks originally imagined.

@rfcbot
Copy link

rfcbot commented Aug 31, 2017

🔔 This is now entering its final comment period, as per the review above. 🔔

1 similar comment
@rfcbot
Copy link

rfcbot commented Aug 31, 2017

🔔 This is now entering its final comment period, as per the review above. 🔔

@rfcbot rfcbot added final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. and removed proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. labels Aug 31, 2017
@alexcrichton alexcrichton added this to the 1.21 milestone Sep 2, 2017
@rfcbot
Copy link

rfcbot commented Sep 10, 2017

The final comment period is now complete.

@Mark-Simulacrum
Copy link
Member

Closing, seems we've sufficiently figured this out and no objections were raised.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints C-bug Category: This is a bug. final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. regression-from-stable-to-beta Performance or correctness regression from stable to beta. T-lang Relevant to the language team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests