-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Reconsider return_self_not_must_use? #8197
Comments
Hey, thank you for your question! The lint is especially targeted towards instances like I, personally, think the lint is reasonable, but I would only use it in real projects and not smaller tests and tinkering projects. We could move it to Would you think that having it in a different category might be a better idea? (See README for the categories) Or did I misunderstand your question? |
After reviewing the 71 cases mentioned above, using As for categories, this lint is unusual in that it doesn't concern (possibly) incorrect code in the methods (or library) checked, but in users of those methods/library. None of the existing categories feel appropriate, though it borders on |
I used As for the category, I didn't know which one was the most appropriate. As long as it warns by default, it's fine for me. (Thanks @xFrednet for the ping!) |
Clippy tries to be general enough, that it applies to binary and library crates. The lint is only emitted for public items to only warn if they can be used by other modules. We have some lints which actually work the other way around that they don't trigger for public functions to avoid breaking the API of crates, these checks can be enabled with the
We're trying to improve how we introduce new lints and have less false positives in them. It's always a big help if projects also run Clippy's nightly version and report bugs or make suggestions this way. Also thank you for asking the question 🙃
This category seems the best to me if we want to have it warn by default, this also makes sense if the goal is to enforce more usage of
I think this is actually an excellent point. Currently, it might not be obvious by the description and lint trigger that this is an option. I'll create a PR to clearly mention this option in the lint description. 🙃 |
Good idea! For the context: I actually discovered this "corner case" when testing the lint on gtk-rs. |
Should we perhaps extend the lint to find if a type has more than a certain number of |
We could do that by going through an impl block and then checking each function instead of each method like it's currently done. Now I've added a help message suggesting either adding the attribute to the function or type like this: error: missing `#[must_use]` attribute on a method returning `Self`
--> $DIR/return_self_not_must_use.rs:17:5
|
LL | / pub fn foo(&self) -> Self {
LL | | Self
LL | | }
| |_____^
|
= help: consider adding the `#[must_use]` attribute to the method or `Self` type I'm uncertain if it would be super beneficial to add more complicated logic when we could always have it like this 🤔 |
Done: #8209 |
@llogiq: I'm not sure if it's the right idea either because it includes an arbitrary check: at which point do we consider the type should be marked as @xFrednet I would reword it a bit:
EDIT: ah my comment arrived too late, I'll comment on the PR then. |
Inspired by a discussion in #8197 --- r? `@llogiq` changelog: none The lint is this on nightly, therefore no changelog entry for you xD
…ogiq return_self_not_must_use document `#[must_use]` on the type Inspired by a discussion in #8197 --- r? `@llogiq` changelog: none The lint is this on nightly, therefore no changelog entry for you xD
My feeling is that warning makes sense only when I ran into this warning in a few places when I just upgraded Clippy for my project. Most cases were builders with signatures like Another case where I got the warning was for functions like I don't know what I think about functions that take Thoughts? I think I'll disable this lint for now (it will be the first one I ignore). Am I just missing something? |
The issue is basically the same: if you take |
Even if it's very unlikely, would it be wrong to add the |
My 2c:
|
No, but it also wouldn't be wrong to add it on pretty much every function taking |
Ah, good point (I should fix that in my project). However, the point still stands if the function is called |
I think it is very subjective whether or not adding |
It's the point of this lint: it's not subjective and induced mistakes on some API usage. If it's not emitting a warning by default, the number of people using it by default will be very low. Important to be noted: it doesn't warn if the item isn't publicly exported, so in your case, it should be fine. If you don't want/care about |
Can you share some examples? I think the only example I've seen was |
I'm not sure if personal experience count. My logic is as follow: if it happened to me, it might happen to others. To expand a bit more: constructors aren't impacted, types having |
Can you link to the function you're thinking of? If it's not open-source, can you describe the case?
I have done that but it's the first Clippy warning I have disabled. I'd be all for enabling the lint by default if it applied only to |
I don't have the code anymore (it's been years now...). But I can describe it. It was a wrapper for a C library pointer which was returning a copy of the array reversed.
It took me a while to understand that it wasn't modifying my |
Interesting, thanks for sharing. So what do you think about making this lint trigger only when |
In my case, it could have been a struct Builder;
impl Builder {
pub fn set_this(self, x: u32) -> Self {}
pub fn set_that(self, x: u32) -> Self {}
} It's really tricky overall, which is why we reached this decision. To quote the end of your commit message:
Wouldn't it be better to have the compiler have your back in case you forget? It's all about enforcing good usage of an API through the compiler so error aren't uncovered at the execution time. |
It typically already does. If I forgot to use the return value, the code would look something like this: let builder = ThingBuilder::new();
builder.set_this(42);
# Compilation error saying something like "'builder' was moved on line 2"
let thing = builder.build(); Right? |
If your builder doesn't implement |
I guess I worry that false positives in this case, can mean not just 'disable this clippy warning', but if you follow clippy's advice, can actually have 2nd order effects by introducing a warning downstream, anyone found a false positive in a popular library? |
I tried it on gtk-rs and sysinfo, no false positive there. Curious to hear from others. |
The first project I looked at was Clap. They addressed this new lint by adding |
I think they are useful. The name of these methods don't really make you expect that it's actually returning something. But that's the root of our disagreement. 😄 |
I think my argument has been unrelated to naming. I'm arguing that the compiler already tells you if you mess up, thanks to Rust's ownership rules. (Again, I agree with having this lint for |
User expectations have a large impact on usefuless. Most of those clap fixes were on types where the user primarily interacts with it through the Overall, I would say this lint will be useful even if there are some cases where the |
@epage, how do you imagine users "who is more used to let mut app = App::new("git");
app.arg(App::new("commit"));
let matches = app.get_matches(); However, that fails to compile on line 3 because In the case of Anyway, I just wanted to make sure you understood my argument. I think you all do by now, so I'll stop nagging :) |
I believe this is resolved since the lint was moved to |
Description
From #8071:
While I agree with the notion that the result of methods taking
self
argument and returningSelf
very likely should be used, I am less convinced that adding the lint without a period for consideration is appropriate. As noted above, it's high impact. In one project alone, I counted 71 affected methods. Given this, the new lint deserves extra consideration.Mostly, this lint hits builder methods without side-effects where obtaining the output is the whole point.
#[must_use]
was originally a tool for pointing out potentially dangerous behaviour, notably forgetting to check the result of a method returningResult<(), Error>
. Using it to point out forgetting something harmless feels like abuse. Clippy is free to complain about generating unused values, but that's not what's happening here: it pushes the lint onto the compiler proper for users of the library using Clippy.Regarding
libstd
, I see thatstd::ops::Add::add
does have#[must_use]
(since four years ago), and here there is justification:x + 1;
looks quite similar tox += 1;
. Similarly,fn f64::floor(self) -> Self
has#[must_use]
(users might assume that the method mutates its own state). In contrast,Option::filter
,Option::map
, etc. don't (users may abuse side-effects here, but it feels like bad style).Iterator
does have#[must_use]
on everything.OptionOptions::new
has#[must_use]
(even though it's a boring constructor).Rc::into_raw
doesn't have#[must_use]
but should (memory leak), though this wouldn't be picked up by this lint anyway.Duration::from_nanos
does even though it's obviously a constructor. So the standard library is not entirely consistent but seems to err on the side of using#[must_use]
.Back to this lint, I'm not sure what to think about it. It can't be called a style lint but does it actually prevent dangerous behaviour?
Version
No response
See also
Additional Labels
@rustbot label +C-question
The text was updated successfully, but these errors were encountered: