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

Lint needless take-by-value #1556

Merged
merged 9 commits into from
Feb 21, 2017
Merged

Lint needless take-by-value #1556

merged 9 commits into from
Feb 21, 2017

Conversation

sinkuu
Copy link
Contributor

@sinkuu sinkuu commented Feb 18, 2017

Fixes #1551.

@sinkuu sinkuu force-pushed the take_by_value branch 2 times, most recently from 7985a23 to c08643a Compare February 18, 2017 22:22
span_lint_and_then(cx,
NEEDLESS_TAKE_BY_VALUE,
input.span,
"this function taking a value by value, but only using them by reference",
Copy link
Member

@killercup killercup Feb 19, 2017

Choose a reason for hiding this comment

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

"this function [is] taking a value by value, but only using [it] by reference"?

4 | #![deny(needless_take_by_value)]
| ^^^^^^^^^^^^^^^^^^^^^^
help: consider taking a reference instead
| fn foo<T: Default>(v: &Vec<T>, w: Vec<T>, mut x: Vec<T>, y: Vec<T>) -> Vec<T> {
Copy link
Member

Choose a reason for hiding this comment

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

(Sadly, clippy will complain about this on the next run and suggest &[T]. But I guess that's for another issue.)

Copy link
Member

Choose a reason for hiding this comment

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

This looks like a problem quite frustrating for users and I would like this lint to be aware of ptr_arg.

CHANGELOG.md Outdated
@@ -383,6 +383,7 @@ All notable changes to this project will be documented in this file.
[`needless_lifetimes`]: https://github.com/Manishearth/rust-clippy/wiki#needless_lifetimes
[`needless_range_loop`]: https://github.com/Manishearth/rust-clippy/wiki#needless_range_loop
[`needless_return`]: https://github.com/Manishearth/rust-clippy/wiki#needless_return
[`needless_take_by_value`]: https://github.com/Manishearth/rust-clippy/wiki#needless_take_by_value
Copy link
Member

Choose a reason for hiding this comment

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

needless_pass_by_value sounds more idiomatic.

And fixes false-positives for generics and `match`
This `match` is not moving the `String`:

```rust
fn foo(x: Option<String>) -> i32 {
    match x {
        Some(_) => 1,
        None => 2,
    }
}
```

With this change, it will be linted and suggested to add `*` to deref it.

```rust
fn foo(x: &Option<String>) -> i32 {
    match *x {
        Some(_) => 1,
        None => 2,
    }
}
```
}

// Suggests adding `*` to dereference the added reference.
if let Some(spans) = spans_need_deref.get(&defid) {
Copy link
Contributor

Choose a reason for hiding this comment

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

this isn't happening in the Vec case anymore.

It would probably be best if it (both the derefs and the main suggestion) were a single suggestion with multiple spans and replacements. Use util::multispan_sugg to create such a suggestion.

@@ -573,10 +573,10 @@ pub fn span_lint_and_then<'a, 'tcx: 'a, T: LintContext<'tcx>, F>(
///
/// Note: in the JSON format (used by `compiletest_rs`), the help message will appear once per
/// replacement. In human-readable format though, it only appears once before the whole suggestion.
pub fn multispan_sugg(db: &mut DiagnosticBuilder, help_msg: String, sugg: &[(Span, &str)]) {
Copy link
Contributor

Choose a reason for hiding this comment

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

looks like we need the opposite lint, too :D Opened an issue #1563

@@ -146,19 +145,13 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessPassByValue {
format!("&{}", snippet(cx, input.span, "_")));
}

// Suggests adding `*` to dereference the added reference.
// Suggests adding `*` to dereference the added reference if needed.
Copy link
Contributor

Choose a reason for hiding this comment

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

The primary suggestions also need to go into the spans Vec, otherwise a tool like rustfix won't be able to know that they belong together and you could end up applying one but not the other.

@sinkuu
Copy link
Contributor Author

sinkuu commented Feb 21, 2017

Sorry for the churn - updated to create a single suggestion now.

@@ -132,27 +132,25 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessPassByValue {
db.span_suggestion(input.span,
&format!("consider changing the type to `{}`", slice_ty),
slice_ty);
return;
return; // `Vec` and `String` cannot be destructured - no need for `*` suggestion
Copy link
Contributor

Choose a reason for hiding this comment

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

Please add assertions that span_need_deref is empty as a canary for when matching on vec/string becomes possible.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

@oli-obk
Copy link
Contributor

oli-obk commented Feb 21, 2017

Sorry for the churn - updated to create a single suggestion now.

No worries. This PR is already golden, we're just polishing it to a shine.

@oli-obk oli-obk merged commit 27aa309 into rust-lang:master Feb 21, 2017
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.

4 participants