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

Improve heuristic for eagerness suggestion #7639

Merged
merged 1 commit into from
Nov 16, 2021

Conversation

Jarcho
Copy link
Contributor

@Jarcho Jarcho commented Sep 5, 2021

Still to be done:

  • a more complete list of cheap functions
  • a way to limit the complexity of cheap expressions

changelog: Improve heuristics for or_fun_call and unnecessary_lazy_evaluations

@rust-highfive
Copy link

r? @Manishearth

(rust-highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties label Sep 5, 2021
@camsteffen
Copy link
Contributor

I don't really love the idea of teaching Clippy an exhaustive list of cheap functions in std.

@Manishearth
Copy link
Member

Hmm, yeah, I'm unsure. @rust-lang/clippy ?

@xFrednet
Copy link
Member

xFrednet commented Sep 7, 2021

I think it would be better to have it consistent for all functions, regardless of how simple they are. It could be confusing for newcomers why some functions are accepted and some not.

Also, I'm not sure how such simple closures are handled in rustc, but they could be stored as function pointers, which would still make them cheaper than calling them beforehand. Function calls are still more expensive than passing a function pointer as an argument, as far as I know.

The PR description states:

Fix false positives on or_fun_call for cheap std functions.

Have we ever had FP reports like these? 🤔

@Jarcho
Copy link
Contributor Author

Jarcho commented Sep 8, 2021

Practically speaking it isn't a performance issue. Everything will be inlined anyways (don't know where debug builds stand on this).

Have we ever had FP reports like these? 🤔

No reported issues, but people have mentioned it being dumb. Changing foo.unwrap_or(bar.len()) to foo.unwrap_or_else(|| bar.len()) just isn't a good suggestion.

I don't really love the idea of teaching Clippy an exhaustive list of cheap functions in std.

I agree it's an unwieldy list. Would a shortlist of the worst offenders be ok? Off the top of my head would be len and is_empty and various conversions such as as_slice and as_ref.

Do we have access to the mir for external crates from clippy? Then we could just look at the function and check if it's trivial or not.

@Manishearth
Copy link
Member

Then we could just look at the function and check if it's trivial or not.

This does get close to the kinds of analyses we'd like to avoid having to do.

But I'm not opposed to an allowlist of functions, I just want to be sure that's the path we want to go down.

@camsteffen
Copy link
Contributor

How bout a blanket allow on names as_*, len and is_empty? All these names are cheap by convention, right?

@Manishearth
Copy link
Member

That works

@Jarcho
Copy link
Contributor Author

Jarcho commented Sep 9, 2021

This does get close to the kinds of analyses we'd like to avoid having to do.

Is there a particular reason to avoid doing so in this case?

How bout a blanket allow on names as_*, len and is_empty? All these names are cheap by convention, right?

That would remove almost every case I've had it trigger on. Should it be limited to std functions just to be safe? I've seen len involve iterators before. (e.g. self.chunks.iter().map(|x| x.len()).sum())

@Manishearth
Copy link
Member

Is there a particular reason to avoid doing so in this case?

Global analyses tend to be more expensive and brittle

@bors
Copy link
Collaborator

bors commented Sep 13, 2021

☔ The latest upstream changes (presumably #7661) made this pull request unmergeable. Please resolve the merge conflicts.

@Jarcho Jarcho force-pushed the whitelist_cheap_functions branch 2 times, most recently from b09ce5b to 8ecfcbf Compare September 16, 2021 04:58
@Jarcho
Copy link
Contributor Author

Jarcho commented Sep 16, 2021

Removed the list of functions. Now there's only a few heuristics:

  • const functions where all arguments are constant expressions will suggest eager evaluation
  • Methods with the name len is_empty or as_* will suggest eager evaluation if they are from std, or not to change the order otherwise.
  • If the type has no fields other than generic types and the only constraints on those types are marker traits, then methods taking self or &self and returning bool will not suggest changing the evaluation order.

@Jarcho Jarcho force-pushed the whitelist_cheap_functions branch 3 times, most recently from 010a6f3 to bafe94e Compare September 16, 2021 05:33
@camsteffen
Copy link
Contributor

const functions where all arguments are constant expressions will suggest eager evaluation

Does it work to just check that the entire function call is_const_expr?

If the type has no fields other than generic types and the only constraints on those types are marker traits, then methods taking self or &self and returning bool will not suggest changing the evaluation order.

Hmm could you explain how you came up with this?

@Jarcho
Copy link
Contributor Author

Jarcho commented Sep 18, 2021

Does it work to just check that the entire function call is_const_expr?

That would also work. The check should be moved into expr_eagerness.

Hmm could you explain how you came up with this?

The goal with this is to catch the helper functions for enums to check for specific variants. The various constraints on the fields are to limit the function to only checking the variants. Technically the function could do anything, it's just very unlikely given the constraints applied. The name could be limited to is_* as that's the convention used for such functions.

@Manishearth
Copy link
Member

going to r? @camsteffen on this one ; I mostly think it's okay but want someone else to make the call 😄

clippy_utils/src/eager_or_lazy.rs Show resolved Hide resolved
clippy_utils/src/eager_or_lazy.rs Outdated Show resolved Hide resolved
clippy_utils/src/eager_or_lazy.rs Show resolved Hide resolved
clippy_utils/src/eager_or_lazy.rs Outdated Show resolved Hide resolved
clippy_utils/src/eager_or_lazy.rs Outdated Show resolved Hide resolved
clippy_utils/src/eager_or_lazy.rs Outdated Show resolved Hide resolved
clippy_utils/src/eager_or_lazy.rs Show resolved Hide resolved
clippy_utils/src/visitors.rs Outdated Show resolved Hide resolved
clippy_utils/src/visitors.rs Outdated Show resolved Hide resolved
@bors
Copy link
Collaborator

bors commented Sep 22, 2021

☔ The latest upstream changes (presumably #7685) made this pull request unmergeable. Please resolve the merge conflicts.

@camsteffen camsteffen added S-waiting-on-author Status: This is awaiting some action from the author. (Use `@rustbot ready` to update this status) and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties labels Sep 25, 2021
@Jarcho
Copy link
Contributor Author

Jarcho commented Nov 12, 2021

Anything else for the review?

@camsteffen
Copy link
Contributor

Looks like everything from the last review is resolved. Needs a rebase.

@Jarcho Jarcho force-pushed the whitelist_cheap_functions branch 3 times, most recently from a5eb1e5 to 1f80543 Compare November 12, 2021 19:57
@bors
Copy link
Collaborator

bors commented Nov 15, 2021

☔ The latest upstream changes (presumably #7974) made this pull request unmergeable. Please resolve the merge conflicts.

Copy link
Contributor

@camsteffen camsteffen left a comment

Choose a reason for hiding this comment

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

LGTM after another rebase, thanks!

@camsteffen
Copy link
Contributor

Can you remove WIP from the PR title? I could do it but I just want to be sure.

@Jarcho Jarcho changed the title WIP Improve heuristic for eagerness suggestion Improve heuristic for eagerness suggestion Nov 16, 2021
@Jarcho
Copy link
Contributor Author

Jarcho commented Nov 16, 2021

I completely forgot that was still there.

@camsteffen
Copy link
Contributor

@bors r+

@bors
Copy link
Collaborator

bors commented Nov 16, 2021

📌 Commit 2938ffd has been approved by camsteffen

@bors
Copy link
Collaborator

bors commented Nov 16, 2021

⌛ Testing commit 2938ffd with merge 5b1b65b...

@bors
Copy link
Collaborator

bors commented Nov 16, 2021

☀️ Test successful - checks-action_dev_test, checks-action_remark_test, checks-action_test
Approved by: camsteffen
Pushing 5b1b65b to master...

@bors bors merged commit 5b1b65b into rust-lang:master Nov 16, 2021
@cgwalters
Copy link

I think this was a good change, but it did create a situation where old clippy warns about new code, new clippy warns about old code; we hit this in ostreedev/ostree-rs-ext#256 (comment)

We pin to a specific version for linting in our CI, but not every developer uses the same rustc.

For future changes like this, I think it'd be nice to have the new clippy not warn on previously accepted code - at least for a decent period of time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-author Status: This is awaiting some action from the author. (Use `@rustbot ready` to update this status)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants