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

New lint: Implement ifs_same_cond_fn #4814

Merged
merged 1 commit into from
Nov 23, 2019
Merged

Conversation

popzxc
Copy link
Contributor

@popzxc popzxc commented Nov 14, 2019

changelog:

* New lints:
  * [`ifs_same_cond_fn`] [#4814](https://github.com/rust-lang/rust-clippy/pull/4814)

Current ifs_same_cond lint does not check function calls, since they can have side effects.

However, such a code can be considered too implicit and counterintuitive, so I believe that a lint to detect such scenarios may be useful.

@ghost
Copy link

ghost commented Nov 14, 2019

What code would you suggest as a replacement? People will want to know how to change their code to silence the error.

@popzxc
Copy link
Contributor Author

popzxc commented Nov 14, 2019

Good question. However, I believe that there is no obvious answer here.

In my opinion, implicit mutating within if is pretty dangerous as a concept, since usually you don't expect some check to mutate state.
Of course, there are examples of well-defined mutating interfaces which can be used without confusion (e.g. Iterator::next), but in general case
when you see code like:

if a.method() == some_value {
    // ...
} else if a.method() == some_value {
    // ...
}

or even

if a.method() {
    // ...
} else if a.method() {
    // ...
}

you won't think that a changes here in the first place.

However, the code like

let a_value = a.method();
if a_value == some_value {
    /// ...
}

let b_value = a.method();
if b_value == some_value {
    /// ...
}

is more likely to be understood correctly.

I've created a snippet on the Rust playground to explain what I mean in the code.

Surely, this check won't suite everyones needs and there are cases when mutating within if is good, but the same applies for e.g. match_same_arms lint.

That's why this lint is pedantic: it won't affect anybody who don't want it explicitly.

@popzxc
Copy link
Contributor Author

popzxc commented Nov 14, 2019

And one more small note: even taking mutating functions into account, this case is pretty rare, and most of the time this lint will complain about situations like:

if some_vec.len() == 1 {
  // ...
} else if some_vec.len() == 1 {
 // ...
}

and that's the main purpose of the lint.

I guess it will be obvious to user that it's an error and he'll be able to resolve this issue himself :)

@popzxc
Copy link
Contributor Author

popzxc commented Nov 16, 2019

@flip1995 r?

Copy link
Member

@flip1995 flip1995 left a comment

Choose a reason for hiding this comment

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

Impl LGTM. Can you add a test, where the arguments of the function/method calls differ?

CHANGELOG.md Outdated
@@ -8,6 +8,9 @@ document.

[3aea860...master](https://github.com/rust-lang/rust-clippy/compare/3aea860...master)

* New lints:
* [`ifs_same_cond_fn`] [#4814](https://github.com/rust-lang/rust-clippy/pull/4814)
Copy link
Member

Choose a reason for hiding this comment

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

This has to be done anyway for many more PRs, so just write the changelog in the PR body.

/// …
/// }
/// ```
pub IFS_SAME_COND_FN,
Copy link
Member

Choose a reason for hiding this comment

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

SAME_FUNCTIONS_IN_IF_CONDITION, as per naming conventions. (putting allow before the lint name should produce an english sentence (more or less))

@flip1995
Copy link
Member

Can you add a example to the lint doc, that shows how to rewrite such a if chain?

@popzxc
Copy link
Contributor Author

popzxc commented Nov 19, 2019

Weird: travis fails, but locally cargo test passes just fine.

@flip1995
Copy link
Member

Travis probably fails because of #4825. Don't worry about this.

src/driver.rs Outdated Show resolved Hide resolved
Run ./util/dev

Revert changelog entry

Rename lint to same_functions_in_if_condition and add a doc example

Add testcases with different arg in fn invocation
Copy link
Member

@flip1995 flip1995 left a comment

Choose a reason for hiding this comment

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

Thanks! Waiting for the rustup.

bors added a commit that referenced this pull request Nov 23, 2019
Rollup of 4 Pull requests with new lints

Rollup of pull requests

- #4816 (New lint: zst_offset)
- #4814 (New lint: Implement ifs_same_cond_fn)
- #4807 (Add `large_stack_arrays` lint)
- #4806 (Issue/4623)

changelog: add [`zst_offset`] lint
changelog: New lint: [`ifs_same_cond_fn`]
cahngelog: Add new lint [large_stack_arrays]
changelog: added lint [`tabs_in_doc_comments`]
@bors bors merged commit bbb8cd4 into rust-lang:master Nov 23, 2019
@popzxc popzxc deleted the if-same-cond-fn branch November 23, 2019 19:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants