-
Notifications
You must be signed in to change notification settings - Fork 1.6k
unnecessary_lazy_evaluations warns about str::len
#8109
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
Comments
foo.len()
str::len
This is working as intended. |
Is |
The logic is determined by |
The same is true for pub fn fo(x: Vec<usize>) -> usize {
x.get(3).cloned().unwrap_or_else(|| x.len())
} This is somewhat confusing, because function calls used to be wrapped in a closure. I think at least (!) the error message should be extended to reflect the new behavoir or else people will get really confused (including me). |
Yeah considering that this is a warn-by-default lint, I would consider changing that case to |
Is this eagerness check also present for "simple" Edit: Oh maybe the block for |
What about determining if that function is |
I love the idea of having this heuristic, even if it does make it a bit harder to write clippy-compliant code "by hand". However I also agree that the introduction of the heuristic was handled somewhat sub-optimal and has at least introduced quite a bit of unnecessary churn in our code-base. This was from a combination of the confusing error message and the problem outlined in this comment on the relevant pull request: |
These are slightly weird, but basically clippy now uses a heuristic to identify certain method calls that it expects to be resolve to a field access, and flags that these do not need to be wrapped in closures: rust-lang/rust-clippy#8109 (comment)
These are slightly weird, but basically clippy now uses a heuristic to identify certain method calls that it expects to be resolve to a field access, and flags that these do not need to be wrapped in closures: rust-lang/rust-clippy#8109 (comment)
These are slightly weird, but basically clippy now uses a heuristic to identify certain method calls that it expects to be resolve to a field access, and flags that these do not need to be wrapped in closures: rust-lang/rust-clippy#8109 (comment)
These are slightly weird, but basically clippy now uses a heuristic to identify certain method calls that it expects to be resolve to a field access, and flags that these do not need to be wrapped in closures: rust-lang/rust-clippy#8109 (comment)
If we are to de-closure/de-combinator clippy's suggestion, I think the code would end up looking something like this: fn main() {
let x = "str:with_separator";
let default = x.len();
let first_part_pos = if let Some(first_part_pos) = x.find(':') {
first_part_pos
} else {
default
};
dbg!(first_part_pos);
} If I were writing the fn main() {
let x = "str:with_separator";
let first_part_pos = if let Some(first_part_pos) = x.find(':') {
first_part_pos
} else {
x.len()
};
dbg!(first_part_pos);
} I think the original sample with the closure given in this issue looks closer to how I'd write this same code with |
In Rust 1.60 we get Clippy lint warnings that make the build fail. ``` warning: unnecessary closure used to substitute value for `Option::None` --> inlineable/src/json_errors.rs:98:25 | 98 | if let Some(code) = error_type_from_header(headers) | _________________________^ 99 | | .map_err(|_| DeserializeError::custom("X-Amzn-Errortype header was not valid UTF-8"))? 100 | | .or_else(|| code.as_deref()) | |____________________________________^ | = note: `#[warn(clippy::unnecessary_lazy_evaluations)]` on by default = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_lazy_evaluations help: use `or` instead | 98 ~ if let Some(code) = error_type_from_header(headers) 99 + .map_err(|_| DeserializeError::custom("X-Amzn-Errortype header was not valid UTF-8"))?.or(code.as_deref()) ``` Since `len` is cheap and `deref` is supposed to be cheap, these resolve to reading a pointer in assembly and they don't need to be lazily evaluated. https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_lazy_evaluations rust-lang/rust-clippy#8109 https://github.com/rust-lang/rust-clippy/blob/master/clippy_utils/src/eager_or_lazy.rs
Summary
str::len
within anunwrap_or_else
seems to causeunnecessary_lazy_evaluations
to trigger even though it's a method call, not a constant which I assumed to be the only case whereunnecessary_lazy_evaluations
triggers.Reproducer
I tried this code (Playground):
I expected to see this happen: No warnings
Instead, this happened:
Version
Additional Labels
No response
The text was updated successfully, but these errors were encountered: