Reduce false-positives for needless_pass_by_value lint
Excluding a type whose reference also fulfills the trait bound.
This commit is contained in:
parent
12a7d1489a
commit
bf97cd0338
3 changed files with 108 additions and 77 deletions
|
|
@ -4,6 +4,9 @@
|
|||
#![warn(needless_pass_by_value)]
|
||||
#![allow(dead_code, single_match, if_let_redundant_pattern_matching, many_single_char_names)]
|
||||
|
||||
use std::borrow::Borrow;
|
||||
use std::convert::AsRef;
|
||||
|
||||
// `v` should be warned
|
||||
// `w`, `x` and `y` are allowed (moved or mutated)
|
||||
fn foo<T: Default>(v: Vec<T>, w: Vec<T>, mut x: Vec<T>, y: Vec<T>) -> Vec<T> {
|
||||
|
|
@ -25,10 +28,11 @@ fn bar(x: String, y: Wrapper) {
|
|||
assert_eq!(y.0.len(), 42);
|
||||
}
|
||||
|
||||
// U implements `Borrow<U>`, but should be warned correctly
|
||||
fn test_borrow_trait<T: std::borrow::Borrow<str>, U>(t: T, u: U) {
|
||||
// V implements `Borrow<V>`, but should be warned correctly
|
||||
fn test_borrow_trait<T: Borrow<str>, U: AsRef<str>, V>(t: T, u: U, v: V) {
|
||||
println!("{}", t.borrow());
|
||||
consume(&u);
|
||||
println!("{}", u.as_ref());
|
||||
consume(&v);
|
||||
}
|
||||
|
||||
// ok
|
||||
|
|
@ -59,4 +63,13 @@ fn test_destructure(x: Wrapper, y: Wrapper, z: Wrapper) {
|
|||
println!("{}", t);
|
||||
}
|
||||
|
||||
trait Foo {}
|
||||
|
||||
// `S: Serialize` can be passed by value
|
||||
trait Serialize {}
|
||||
impl<'a, T> Serialize for &'a T where T: Serialize {}
|
||||
impl Serialize for i32 {}
|
||||
|
||||
fn test_blanket_ref<T: Foo, S: Serialize>(_foo: T, _serializable: S) {}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
|
|
@ -1,58 +1,64 @@
|
|||
error: this argument is passed by value, but not consumed in the function body
|
||||
--> $DIR/needless_pass_by_value.rs:9:23
|
||||
|
|
||||
9 | fn foo<T: Default>(v: Vec<T>, w: Vec<T>, mut x: Vec<T>, y: Vec<T>) -> Vec<T> {
|
||||
| ^^^^^^ help: consider changing the type to: `&[T]`
|
||||
|
|
||||
= note: `-D needless-pass-by-value` implied by `-D warnings`
|
||||
--> $DIR/needless_pass_by_value.rs:12:23
|
||||
|
|
||||
12 | fn foo<T: Default>(v: Vec<T>, w: Vec<T>, mut x: Vec<T>, y: Vec<T>) -> Vec<T> {
|
||||
| ^^^^^^ help: consider changing the type to: `&[T]`
|
||||
|
|
||||
= note: `-D needless-pass-by-value` implied by `-D warnings`
|
||||
|
||||
error: this argument is passed by value, but not consumed in the function body
|
||||
--> $DIR/needless_pass_by_value.rs:23:11
|
||||
--> $DIR/needless_pass_by_value.rs:26:11
|
||||
|
|
||||
23 | fn bar(x: String, y: Wrapper) {
|
||||
26 | fn bar(x: String, y: Wrapper) {
|
||||
| ^^^^^^ help: consider changing the type to: `&str`
|
||||
|
||||
error: this argument is passed by value, but not consumed in the function body
|
||||
--> $DIR/needless_pass_by_value.rs:23:22
|
||||
--> $DIR/needless_pass_by_value.rs:26:22
|
||||
|
|
||||
23 | fn bar(x: String, y: Wrapper) {
|
||||
26 | fn bar(x: String, y: Wrapper) {
|
||||
| ^^^^^^^ help: consider taking a reference instead: `&Wrapper`
|
||||
|
||||
error: this argument is passed by value, but not consumed in the function body
|
||||
--> $DIR/needless_pass_by_value.rs:29:63
|
||||
--> $DIR/needless_pass_by_value.rs:32:71
|
||||
|
|
||||
29 | fn test_borrow_trait<T: std::borrow::Borrow<str>, U>(t: T, u: U) {
|
||||
| ^ help: consider taking a reference instead: `&U`
|
||||
32 | fn test_borrow_trait<T: Borrow<str>, U: AsRef<str>, V>(t: T, u: U, v: V) {
|
||||
| ^ help: consider taking a reference instead: `&V`
|
||||
|
||||
error: this argument is passed by value, but not consumed in the function body
|
||||
--> $DIR/needless_pass_by_value.rs:40:18
|
||||
--> $DIR/needless_pass_by_value.rs:44:18
|
||||
|
|
||||
40 | fn test_match(x: Option<Option<String>>, y: Option<Option<String>>) {
|
||||
44 | fn test_match(x: Option<Option<String>>, y: Option<Option<String>>) {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: consider taking a reference instead
|
||||
|
|
||||
40 | fn test_match(x: &Option<Option<String>>, y: Option<Option<String>>) {
|
||||
41 | match *x {
|
||||
44 | fn test_match(x: &Option<Option<String>>, y: Option<Option<String>>) {
|
||||
45 | match *x {
|
||||
|
|
||||
|
||||
error: this argument is passed by value, but not consumed in the function body
|
||||
--> $DIR/needless_pass_by_value.rs:53:24
|
||||
--> $DIR/needless_pass_by_value.rs:57:24
|
||||
|
|
||||
53 | fn test_destructure(x: Wrapper, y: Wrapper, z: Wrapper) {
|
||||
57 | fn test_destructure(x: Wrapper, y: Wrapper, z: Wrapper) {
|
||||
| ^^^^^^^ help: consider taking a reference instead: `&Wrapper`
|
||||
|
||||
error: this argument is passed by value, but not consumed in the function body
|
||||
--> $DIR/needless_pass_by_value.rs:53:36
|
||||
--> $DIR/needless_pass_by_value.rs:57:36
|
||||
|
|
||||
53 | fn test_destructure(x: Wrapper, y: Wrapper, z: Wrapper) {
|
||||
57 | fn test_destructure(x: Wrapper, y: Wrapper, z: Wrapper) {
|
||||
| ^^^^^^^
|
||||
|
|
||||
help: consider taking a reference instead
|
||||
|
|
||||
53 | fn test_destructure(x: Wrapper, y: &Wrapper, z: Wrapper) {
|
||||
54 | let Wrapper(s) = z; // moved
|
||||
55 | let Wrapper(ref t) = *y; // not moved
|
||||
56 | let Wrapper(_) = *y; // still not moved
|
||||
57 | fn test_destructure(x: Wrapper, y: &Wrapper, z: Wrapper) {
|
||||
58 | let Wrapper(s) = z; // moved
|
||||
59 | let Wrapper(ref t) = *y; // not moved
|
||||
60 | let Wrapper(_) = *y; // still not moved
|
||||
|
|
||||
|
||||
error: this argument is passed by value, but not consumed in the function body
|
||||
--> $DIR/needless_pass_by_value.rs:73:49
|
||||
|
|
||||
73 | fn test_blanket_ref<T: Foo, S: Serialize>(_foo: T, _serializable: S) {}
|
||||
| ^ help: consider taking a reference instead: `&T`
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue