4

New lint: `iter_overeager_cloned` by pmnoxx · Pull Request #8203 · rust-lang/rus...

 2 years ago
source link: https://github.com/rust-lang/rust-clippy/pull/8203
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Copy link

Collaborator

@llogiq llogiq left a comment •

edited

This looks good to me, modulo running update_lints and checking in the changes. I have an idea how we could make that lint even better. If you want to do that within this PR, go ahead, otherwise let me know and I'll r+.

expr.span,

msg,

"try this",

format!("{}.last().cloned()", iter_snippet),

Copy link

Collaborator

@llogiq llogiq 20 days ago

edited

If the .last() is unwrap()ed or ?d, we could even suggest to .clone() that. Just a suggestion for extending the lint, this won't stop us from merging.

Copy link

Contributor

Author

@pmnoxx pmnoxx 20 days ago

edited

@llogiq That's a great suggestion.

I see: for Option<> / Result<>.
recv.cloned().unwrap()
could be
recv.unwrap().clone.

I see that cloned should be moved furthermost the chain as long as possible, not just for last.
For example here:

 vec.iter().cloned().filter(...).skip(5).take(10).last().unwrap()

That could be just written as

let val = vec.cloned().filter(...).skip(5).take(10).last().unwrap().clone()

This may even allow us to drop the clone() entirely, in some cases, when clone() is not needed.

It may be a good idea to propagate clone from before, to after

  • last
  • take
  • skip
  • next.
  • unwrap
  • filter // has lambda, so requires some more checks
  • find.// has lambda,so requires some more checks
  • map - vec.iter().cloned().map(|x|x.len()) <-- this probably doesn't need clone either.
  • foreach - maybe? vec.iter().cloned().foreach_each(|x|println!{"{}", x)) <-- this doesn't need clone
  • ... probably some others as well

map/for_each/try_foreach require detecting whenever lambda can accept reference instead

The question is, should each be a separate lint, or should they be combined together?

Copy link

Collaborator

@llogiq llogiq 20 days ago

I think your example is a bit off, but otherwise full ack.

I'd be OK with multiple lints if there are useful distinctions to make. E.g. if one part of the check can have false positives, it would be a good idea to put that into a different nursery lint. Or if one part could reasonably be style and another perf. Otherwise, putting all the checks into one lint seems natural. One thing I that comes to mind is that we already have the needless_clone lint, so we could add cases where the cloned can be removed outright to that, making the rest early_iter_cloned or some such.

Again, I'm also OK if you restrict the scope of this PR and do a followup later. Have fun!


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK