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

Add new lint unnecessary_wrap #6070

Merged
merged 29 commits into from
Nov 17, 2020
Merged

Conversation

hkmatsumoto
Copy link
Member

@hkmatsumoto hkmatsumoto commented Sep 20, 2020

Fixes #5969

changelog: New lint [unnecessary_wraps]

@rust-highfive
Copy link

r? @flip1995

(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 20, 2020
clippy_lints/src/unnecessary_wrap.rs Outdated Show resolved Hide resolved
tests/ui/unnecessary_wrap.rs Outdated Show resolved Hide resolved
@ghost
Copy link

ghost commented Sep 21, 2020

This lint looks really similar to the unnecessary_filter_map lint. I think you should probably reuse some code between them - particularly the visitor. I've also seen the same visitor implemented in bind_instead_of_map but it looked much more complicated. I get the feeling the one in this PR is missing some edge cases.

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.

I agree with @mikerite, that the visitor implemented here is pretty similar to bind_instead_of_map. I also think, that the bind_instead_of_map visitor is way more complicated than it has to be though.

Anyway, you can at least reuse the visitor of bind_instead_of_map and then use this code to collect all the return paths:

if_chain! {
if !in_macro(ret_expr.span);
if let hir::ExprKind::Call(ref func_path, ref args) = ret_expr.kind;
if let hir::ExprKind::Path(ref qpath) = func_path.kind;
if match_qpath(qpath, Self::BAD_VARIANT_QPATH);
if args.len() == 1;
if !contains_return(&args[0]);
then {
suggs.push((ret_expr.span, args[0].span.source_callsite()));
true
} else {
false
}
}

rustfix doesn't work with multipart suggestions, so don't worry about that. (You can use diag.multipart_suggestion() directly instead of the one from utils, since the utils one is just a useless wrapper, we should remove sometime)

clippy_lints/src/unnecessary_wrap.rs Outdated Show resolved Hide resolved
clippy_lints/src/unnecessary_wrap.rs Outdated Show resolved Hide resolved
clippy_lints/src/unnecessary_wrap.rs Outdated Show resolved Hide resolved
@flip1995 flip1995 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 21, 2020
@hkmatsumoto
Copy link
Member Author

Sorry for the late reply, I could not use computers as I was replacing my desk.

I agree with @mikerite, that the visitor implemented here is pretty similar to bind_instead_of_map. I also think, that the bind_instead_of_map visitor is way more complicated than it has to be though.

Anyway, you can at least reuse the visitor of bind_instead_of_map and then use this code to collect all the return paths:

if_chain! {
if !in_macro(ret_expr.span);
if let hir::ExprKind::Call(ref func_path, ref args) = ret_expr.kind;
if let hir::ExprKind::Path(ref qpath) = func_path.kind;
if match_qpath(qpath, Self::BAD_VARIANT_QPATH);
if args.len() == 1;
if !contains_return(&args[0]);
then {
suggs.push((ret_expr.span, args[0].span.source_callsite()));
true
} else {
false
}
}

Got it, made the changes accordingly.
find_all_ret_expressions() is convenient and potential contributors might make use of it as well, so I think the function can go into utils crate.

@hkmatsumoto hkmatsumoto marked this pull request as ready for review September 22, 2020 18:18
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.

I would prefer if you could split the suggestion in two parts, so that it looks like the following:

error: this function returns unnecessarily wrapping data
  --> $DIR/unnecessary_wrap.rs:39:1
   |
LL | / fn func4() -> Option<i32> {
LL | |     Some(1)
LL | | }
   | |_^
   |
help: remove `Option` from the return type...
   |
LL | fn func4() -> i32 {
   |               ^^^
help: ...and change the returning expressions
   |
LL |     1
   |

clippy_lints/src/unnecessary_wrap.rs Outdated Show resolved Hide resolved
tests/ui/unnecessary_wrap.stderr Outdated Show resolved Hide resolved
Copy link
Contributor

@giraffate giraffate left a comment

Choose a reason for hiding this comment

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

FYI it looks like that rust-lang/rust-clippy repo follows rustc no-merge policy. For example #5694 (comment).

@hkmatsumoto
Copy link
Member Author

FYI it looks like that rust-lang/rust-clippy repo follows rustc no-merge policy. For example #5694 (comment).

Oops, thanks for pointing out.

clippy_lints/src/unnecessary_wrap.rs Outdated Show resolved Hide resolved
@hkmatsumoto
Copy link
Member Author

hkmatsumoto commented Oct 18, 2020

Some lines in clippy itself are linted and I noticed that this lint should not check fns named partial_cmp as they likely to return an expression like Some(self.cmp(other)).

tests/ui/or_fun_call.fixed Outdated Show resolved Hide resolved
clippy_lints/src/unnecessary_wrap.rs Outdated Show resolved Hide resolved
@bors
Copy link
Contributor

bors commented Nov 8, 2020

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

Note that reviewers usually do not review pull requests until merge conflicts are resolved! Once you resolve the conflicts, you should change the labels applied by bors to indicate that your PR is ready for review. Post this as a comment to change the labels:

@rustbot modify labels: +S-waiting-on-review -S-waiting-on-author

@hkmatsumoto
Copy link
Member Author

@rustbot modify labels: +S-waiting-on-review -S-waiting-on-author

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties and removed S-waiting-on-author Status: This is awaiting some action from the author. (Use `@rustbot ready` to update this status) labels Nov 14, 2020
@flip1995
Copy link
Member

@bors r+

Thanks!

@bors
Copy link
Contributor

bors commented Nov 16, 2020

📌 Commit 2881bbd has been approved by flip1995

@flip1995
Copy link
Member

@bors r+

Thanks!

@bors
Copy link
Contributor

bors commented Nov 17, 2020

📌 Commit c7445d7 has been approved by flip1995

bors added a commit that referenced this pull request Nov 17, 2020
Add new lint `unnecessary_wrap`

Fixes #5969

changelog: New lint [`unnecessary_wraps`]
@bors
Copy link
Contributor

bors commented Nov 17, 2020

⌛ Testing commit c7445d7 with merge 6c116ed...

@bors
Copy link
Contributor

bors commented Nov 17, 2020

💔 Test failed - checks-action_test

@flip1995
Copy link
Member

@bors retry

@bors
Copy link
Contributor

bors commented Nov 17, 2020

⌛ Testing commit c7445d7 with merge 7fcf385...

bors added a commit that referenced this pull request Nov 17, 2020
Add new lint `unnecessary_wrap`

Fixes #5969

changelog: New lint [`unnecessary_wraps`]
@bors
Copy link
Contributor

bors commented Nov 17, 2020

💔 Test failed - checks-action_test

@flip1995
Copy link
Member

@bors retry

@bors
Copy link
Contributor

bors commented Nov 17, 2020

⌛ Testing commit c7445d7 with merge 44d9445...

@bors
Copy link
Contributor

bors commented Nov 17, 2020

☀️ Test successful - checks-action_dev_test, checks-action_remark_test, checks-action_test
Approved by: flip1995
Pushing 44d9445 to master...

@bors bors merged commit 44d9445 into rust-lang:master Nov 17, 2020
@bors bors mentioned this pull request Nov 17, 2020
@hkmatsumoto hkmatsumoto deleted the unnecessary_wrap branch November 18, 2020 09:55
@couchand
Copy link
Contributor

Maybe it's just me, but this lint seems awfully aggressive. There are plenty of reasons an interface might be written to return an Option or Result even if the specific implementation in question doesn't fail.

For instance, I'm very frequently factoring out the last step of initialization into a helper method; the pub constructors all return a Result because they can fail their validation, but once validated they delegate directly to the infallible internal constructor. All of these usages are now linted against here. But moving the Ok-wrapping to the pub constructors seems to be a violation of DRY.

Please move this to pedantic.

@emilk
Copy link

emilk commented Nov 25, 2020

I'm very frequently factoring out the last step of initialization into a helper method; the pub constructors all return a Result because they can fail their validation, but once validated they delegate directly to the infallible internal constructor. All of these usages are now linted against here. But moving the Ok-wrapping to the pub constructors seems to be a violation of DRY.

I'm not sure I follow you. Wrapping an infallible call in Ok(...) seems exactly the right thing to do!

It seems to me that the situation you describe is best solved with this:

impl Foo {
    pub fn new(args: Args) -> Result<Self, Error> {
        if args.are_bad() {
           Err(...)
        } else {
            Ok(Foo::private_new(args))
        }
    }

    fn private_new(args: Args) -> Self { ... }
}

But I feel like I am probably missing something!

@couchand
Copy link
Contributor

@emilk Personally, I don't think it's the role of linting to make these sorts of invasive signature requirements by default. The authors seem to agree, at least in part, given that the lint doesn't apply to functions with a visiblity of pub.

That being said, I don't think I have the bandwidth to pursue this further. Thanks for your consideration.

ozerovandrei added a commit to ozerovandrei/opentelemetry-rust that referenced this pull request Feb 14, 2021
Remove `Result` from return types in tests of `opentelemetry-datadog`,
`opentelemetry-jaeger`, `opentelemetry-otlp`, `opentelemetry-zipkin`.

Reference: rust-lang/rust-clippy#6070
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: Awaiting review from the assignee but also interested parties
Projects
None yet
Development

Successfully merging this pull request may close these issues.

new lint: functions that return unneeded options/results
9 participants