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

Extend #[must_use] to nested structures #62262

Closed
wants to merge 17 commits into from

Conversation

varkor
Copy link
Member

@varkor varkor commented Jul 1, 2019

Extends the #[must_use] lint to apply when #[must_use] types are nested within structs (or one-variant enums), making the lint much more generally useful. This is in line with #61100 extending the lint to tuples.

Fixes #39524.

cc @rust-lang/lang and @rust-lang/compiler for discussion in case this is a controversial change. In particular, we might want to consider allowing annotations on fields containing #[must_use] types in user-defined types (e.g. #[allow(unused_must_use)]) to opt out of this behaviour, if there are cases where we this this is likely to have frequent false positives.

(This is based on top of #62235.)

@rust-highfive
Copy link
Collaborator

r? @estebank

(rust_highfive has picked a reviewer for you, use r? to override)

@rust-highfive
Copy link
Collaborator

⚠️ Warning ⚠️

  • These commits modify submodules.

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jul 1, 2019
@Centril Centril added I-nominated T-lang Relevant to the language team, which will review and decide on the PR/issue. labels Jul 1, 2019
// We ignore ADTs with more than one variant for simplicity and to avoid
// false positives.
// Unions are also ignored (though in theory, we could lint if every field of
// a union was `#[must_use]`).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably go into a separate method and the comments above can become doc comments...

src/librustc_lint/unused.rs Outdated Show resolved Hide resolved
@estebank
Copy link
Contributor

estebank commented Jul 1, 2019

I'm not available for the next couple of days due to personal reasons. I would appreciate it if someone else could take over review.

@Mark-Simulacrum
Copy link
Member

I don't think the review is in any rush - this definitely need lang-team sign off (and maybe libs?); I feel like we've discussed this previously and concluded that we shouldn't do it, IIRC because it expands it far enough that it feels like it "always" works which isn't actually the case. I could be projecting my own thoughts on the matter though.

@Centril
Copy link
Contributor

Centril commented Jul 1, 2019

I don't think the review is in any rush - this definitely need lang-team sign off (and maybe libs?);

I nominated this for the lang team. The libs team doesn't deal with compiler lints.


I personally feel that the false-positive cases are edge cases that are rare enough that they don't outweigh the big benefit this PR brings.

We could however tweak this a bit to look for a Drop implementations for the ADT and then bail on the structural logic tho that might be too subtle. An opt-out would also be decent.

@Mark-Simulacrum
Copy link
Member

I disagree a little bit about the libs team bit here -- it seems like this lint is predominantly used for libraries, not language features/things, and so their opinion matters more. At the very least, they should be notified (cc @rust-lang/libs).

src/libstd/panicking.rs Outdated Show resolved Hide resolved
src/librustc_lint/unused.rs Outdated Show resolved Hide resolved
@Nemo157
Copy link
Member

Nemo157 commented Jul 9, 2019

Would it make sense to do a crater run of this to see how useful the warnings it produces in real code are?

@nikomatsakis
Copy link
Contributor

Discussed briefly in @rust-lang/lang -- we agree a crater run would be the logical next step before making any further decisions. Can we set this to deny by default and do a run?

@estebank
Copy link
Contributor

r? @eddyb

@rust-highfive rust-highfive assigned eddyb and unassigned estebank Jul 12, 2019
@varkor varkor force-pushed the must_use-adt-components-ii branch from 4ea0b40 to 84ae8df Compare July 22, 2019 20:31
@varkor

This comment has been minimized.

@bors

This comment has been minimized.

@bors

This comment has been minimized.

@bors bors mentioned this pull request Jul 22, 2019
@Centril Centril closed this Jul 22, 2019
@Centril Centril reopened this Jul 22, 2019
@varkor
Copy link
Member Author

varkor commented Oct 8, 2019

@bors try

@bors
Copy link
Contributor

bors commented Oct 8, 2019

⌛ Trying commit 8bcf64a with merge ea663bb...

bors added a commit that referenced this pull request Oct 8, 2019
Extend `#[must_use]` to nested structures

Extends the `#[must_use]` lint to apply when `#[must_use]` types are nested within `struct`s (or one-variant `enum`s), making the lint much more generally useful. This is in line with #61100 extending the lint to tuples.

Fixes #39524.

cc @rust-lang/lang and @rust-lang/compiler for discussion in case this is a controversial change. In particular, we might want to consider allowing annotations on fields containing `#[must_use]` types in user-defined types (e.g. `#[allow(unused_must_use)]`) to opt out of this behaviour, if there are cases where we this this is likely to have frequent false positives.

(This is based on top of #62235.)
@bors
Copy link
Contributor

bors commented Oct 9, 2019

☀️ Try build successful - checks-azure
Build commit: ea663bb (ea663bba38739867a4b75ac820991b4f5d093c3b)

@varkor
Copy link
Member Author

varkor commented Oct 9, 2019

@craterbot check

@craterbot
Copy link
Collaborator

👌 Experiment pr-62262-1 created and queued.
🤖 Automatically detected try build ea663bb
🔍 You can check out the queue and this experiment's details.

ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@craterbot craterbot added S-waiting-on-crater Status: Waiting on a crater run to be completed. and removed S-waiting-on-team Status: Awaiting decision from the relevant subteam (see the T-<team> label). labels Oct 9, 2019
@craterbot
Copy link
Collaborator

🚧 Experiment pr-62262-1 is now running

ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@craterbot
Copy link
Collaborator

🎉 Experiment pr-62262-1 is completed!
📊 97 regressed and 0 fixed (74234 total)
📰 Open the full report.

⚠️ If you notice any spurious failure please add them to the blacklist!
ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@craterbot craterbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-crater Status: Waiting on a crater run to be completed. labels Oct 21, 2019
@varkor
Copy link
Member Author

varkor commented Oct 21, 2019

23 crates produced the new lint (most of the regressions caught by crater were downstream). They all seem genuine to me, though in most cases they were deliberately (though not explicitly) ignored (in things like drop impls, etc.). In these cases, let _ = ...; should be appropriate.

I think this crater run demonstrates the change is not very invasive, but can catch genuine errors, and is worth merging.

@estebank
Copy link
Contributor

The one case I noticed that might be reasonable to allow is calling drain.

@varkor
Copy link
Member Author

varkor commented Oct 21, 2019

I don't think that pattern is common: the only reason that instance was linted is because they were implementing clear using drain(..). It seems reasonable to want let _ = self.drain(..); in this case.

@varkor
Copy link
Member Author

varkor commented Oct 23, 2019

Nominating for lang team re-review, now that the original concerns have been addressed.

@cramertj
Copy link
Member

We discussed this in the lang meeting today and there was general agreement that the lint as-implemented in this PR isn't something we're interested in landing. This change would make #[must_use] operate similarly to an auto-trait in that #[must_used]-ness would be inherited from fields, but with no ability to turn off the #[must_used]-ness of a type which contains a #[must_use] type. A number of the examples in the crater run above (e.g. Drain) demonstrate that this is not what authors intend by #[must_use], and in many cases creates warnings that are misleading or unhelpful.

There was some interest in a "conditional-must-use" based on type parameters, e.g. Box<T>/Option<T> could be #[must_use] iff T is #[must_use], but extending this behavior to user-defined types would require an RFC. A #[rustc_conditional_must_use] or similar could be appropriate if we want to limit this to std types.

@eddyb
Copy link
Member

eddyb commented Oct 25, 2019

@cramertj "conditional #[must_use]" sounds like #[must_use] on data types should've been a trait with an associated const (for the reason), since then you can just rely on bounds.

I think we can still do that with an unstable trait, and hook it up either through the trait system, or macro expansion, so both #[must_use] and the trait work with the lint.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-lang Relevant to the language team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

#[must_use] does not work for nested structures