-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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 new useless_allocation
lint
#12315
Add new useless_allocation
lint
#12315
Conversation
r? @Manishearth rustbot has assigned @Manishearth. Use r? to explicitly pick a reviewer |
Ah funny, it already allowed to find a case in clippy itself. :) |
r? clippy rather busy at the moment |
/// s.remove("b"); | ||
/// ``` | ||
#[clippy::version = "1.78.0"] | ||
pub USELESS_ALLOCATION, |
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.
issue: I think this lint name is quite general for how specific the actual lint is
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.
its a bit as if needless_clone
and unnecessary_to_owned
had a child together.
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.
That makes me wonder if it would make sense to just extend unnecessary_to_owned
with these additional cases.
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.
For example, unnecessary_to_owned
already lints on:
fn f(x: &str) {}
f(&"".to_owned());
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.
its a bit as if
needless_clone
andunnecessary_to_owned
had a child together.
Pretty much yes. 😆
@y21 I wondered about that as well but since it's covering than just to_owned
call, I felt like it should not be there. Same goes for needless_clone
since it's not related to clone
.
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.
For example,
unnecessary_to_owned
already lints on:fn f(x: &str) {} f(&"".to_owned());
But it doesn't work when the argument is generic (yet?) unfortunately.
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.
So what do you want me to do here? Rename it or merge it with another existing lint?
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.
In my opinion, merging it with unnecessary_to_owned
makes the most sense.
I wondered about that as well but since it's covering than just to_owned call
But the lint description for it also says "[...] and other to_owned-like functions", and also covers the same to_owned
, to_vec
and to_string
functions.
But it doesn't work when the argument is generic (yet?) unfortunately.
I mentioned this in my comment, but it does seem to understand some generic cases:
fn f<K: Deref<Target=str>>(x: K) {}
f("".to_owned());
This gets linted
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.
So, in the case of the maps, it gets a bit more complicated because the argument is a generic Q
and Q
doesn't have the Borrow
trait as predicate (as you can see here). So I can merge both lints, but it might require a bit more work than just adding a check for Borrow
in this case...
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 also tested to add the Borrow
trait as check and it doesn't detect this code:
fn borrow_str<Q: Borrow<str>>(s: &Q) {}
fn borrow_slice<Q: Borrow<[u8]>>(s: &Q) {}
fn check_borrow() {
borrow_str(&"a".to_owned());
borrow_str(&"a".to_string());
borrow_slice(&[0].to_vec());
}
So I'll merge this code with the lint for now.
declare_clippy_lint! { | ||
/// ### What it does | ||
/// Checks if an unneeded allocation is performed when trying to get information | ||
/// related to a given key is a `HashMap`-like type. |
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.
s/is/in/ ?
This should be possible by using We should then be able to substitute the generic parameter with the borrowed expression's type (i.e., the unadjusted ty of We're already doing pretty much exactly that in the That said, I'd also be fine with just landing a simpler version which hardcodes a bunch of cases like this, and it could be improved in followups, if that's easier |
... Actually, now looking closer into the |
@GuillaumeGomez with #12324 opened as an alternative, do we want to close this one? |
Absolutely! |
Fixes #8088.
I'm not too happy with this implementation as it currently limits the detection to
String
andVec
. If someone has an idea on how to check that the "argument type" (the one that was being converted) can be used as argument directly without all the checks I added, it'd allow this lint to work on all types implementingBorrow<T>
.changelog: Add new
useless_allocation
lint