needless_pass_by_value: Whitelist RangeArgument (fixes #2357)
This commit is contained in:
parent
2a30c8a194
commit
552e950080
@ -102,10 +102,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessPassByValue {
|
||||
|
||||
// Allow `Borrow` or functions to be taken by value
|
||||
let borrow_trait = need!(get_trait_def_id(cx, &paths::BORROW_TRAIT));
|
||||
let fn_traits = [
|
||||
let whitelisted_traits = [
|
||||
need!(cx.tcx.lang_items().fn_trait()),
|
||||
need!(cx.tcx.lang_items().fn_once_trait()),
|
||||
need!(cx.tcx.lang_items().fn_mut_trait()),
|
||||
need!(get_trait_def_id(cx, &paths::RANGE_ARGUMENT_TRAIT))
|
||||
];
|
||||
|
||||
let sized_trait = need!(cx.tcx.lang_items().sized_trait());
|
||||
@ -189,7 +190,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessPassByValue {
|
||||
if !is_self(arg);
|
||||
if !ty.is_mutable_pointer();
|
||||
if !is_copy(cx, ty);
|
||||
if !fn_traits.iter().any(|&t| implements_trait(cx, ty, t, &[]));
|
||||
if !whitelisted_traits.iter().any(|&t| implements_trait(cx, ty, t, &[]));
|
||||
if !implements_borrow_trait;
|
||||
if !all_borrowable_trait;
|
||||
|
||||
|
@ -55,6 +55,7 @@ pub const OPTION_SOME: [&str; 4] = ["core", "option", "Option", "Some"];
|
||||
pub const PTR_NULL: [&str; 2] = ["ptr", "null"];
|
||||
pub const PTR_NULL_MUT: [&str; 2] = ["ptr", "null_mut"];
|
||||
pub const RANGE: [&str; 3] = ["core", "ops", "Range"];
|
||||
pub const RANGE_ARGUMENT_TRAIT: [&str; 3] = ["alloc", "range", "RangeArgument"];
|
||||
pub const RANGE_FROM: [&str; 3] = ["core", "ops", "RangeFrom"];
|
||||
pub const RANGE_FROM_STD: [&str; 3] = ["std", "ops", "RangeFrom"];
|
||||
pub const RANGE_FULL: [&str; 3] = ["core", "ops", "RangeFull"];
|
||||
|
@ -4,6 +4,8 @@
|
||||
#![warn(needless_pass_by_value)]
|
||||
#![allow(dead_code, single_match, if_let_redundant_pattern_matching, many_single_char_names)]
|
||||
|
||||
#![feature(collections_range)]
|
||||
|
||||
use std::borrow::Borrow;
|
||||
use std::convert::AsRef;
|
||||
|
||||
@ -113,4 +115,9 @@ trait FalsePositive {
|
||||
// shouldn't warn on extern funcs
|
||||
extern "C" fn ext(x: String) -> usize { x.len() }
|
||||
|
||||
// whitelist RangeArgument
|
||||
fn range<T: ::std::collections::range::RangeArgument<usize>>(range: T) {
|
||||
let _ = range.start();
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,151 +1,151 @@
|
||||
error: this argument is passed by value, but not consumed in the function body
|
||||
--> $DIR/needless_pass_by_value.rs:12:23
|
||||
--> $DIR/needless_pass_by_value.rs:14:23
|
||||
|
|
||||
12 | fn foo<T: Default>(v: Vec<T>, w: Vec<T>, mut x: Vec<T>, y: Vec<T>) -> Vec<T> {
|
||||
14 | 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:26:11
|
||||
--> $DIR/needless_pass_by_value.rs:28:11
|
||||
|
|
||||
26 | fn bar(x: String, y: Wrapper) {
|
||||
28 | 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:26:22
|
||||
--> $DIR/needless_pass_by_value.rs:28:22
|
||||
|
|
||||
26 | fn bar(x: String, y: Wrapper) {
|
||||
28 | fn bar(x: String, y: Wrapper) {
|
||||
| ^^^^^^^ help: consider taking a reference instead: `&Wrapper`
|
||||
|
|
||||
help: consider marking this type as Copy if possible
|
||||
--> $DIR/needless_pass_by_value.rs:24:1
|
||||
--> $DIR/needless_pass_by_value.rs:26:1
|
||||
|
|
||||
24 | struct Wrapper(String);
|
||||
26 | struct Wrapper(String);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: this argument is passed by value, but not consumed in the function body
|
||||
--> $DIR/needless_pass_by_value.rs:32:71
|
||||
--> $DIR/needless_pass_by_value.rs:34:71
|
||||
|
|
||||
32 | fn test_borrow_trait<T: Borrow<str>, U: AsRef<str>, V>(t: T, u: U, v: V) {
|
||||
34 | 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:44:18
|
||||
--> $DIR/needless_pass_by_value.rs:46:18
|
||||
|
|
||||
44 | fn test_match(x: Option<Option<String>>, y: Option<Option<String>>) {
|
||||
46 | fn test_match(x: Option<Option<String>>, y: Option<Option<String>>) {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
help: consider taking a reference instead
|
||||
|
|
||||
44 | fn test_match(x: &Option<Option<String>>, y: Option<Option<String>>) {
|
||||
45 | match *x {
|
||||
46 | fn test_match(x: &Option<Option<String>>, y: Option<Option<String>>) {
|
||||
47 | match *x {
|
||||
|
|
||||
|
||||
error: this argument is passed by value, but not consumed in the function body
|
||||
--> $DIR/needless_pass_by_value.rs:57:24
|
||||
--> $DIR/needless_pass_by_value.rs:59:24
|
||||
|
|
||||
57 | fn test_destructure(x: Wrapper, y: Wrapper, z: Wrapper) {
|
||||
59 | fn test_destructure(x: Wrapper, y: Wrapper, z: Wrapper) {
|
||||
| ^^^^^^^ help: consider taking a reference instead: `&Wrapper`
|
||||
|
|
||||
help: consider marking this type as Copy if possible
|
||||
--> $DIR/needless_pass_by_value.rs:24:1
|
||||
--> $DIR/needless_pass_by_value.rs:26:1
|
||||
|
|
||||
24 | struct Wrapper(String);
|
||||
26 | struct Wrapper(String);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: this argument is passed by value, but not consumed in the function body
|
||||
--> $DIR/needless_pass_by_value.rs:57:36
|
||||
--> $DIR/needless_pass_by_value.rs:59:36
|
||||
|
|
||||
57 | fn test_destructure(x: Wrapper, y: Wrapper, z: Wrapper) {
|
||||
59 | fn test_destructure(x: Wrapper, y: Wrapper, z: Wrapper) {
|
||||
| ^^^^^^^
|
||||
|
|
||||
help: consider marking this type as Copy if possible
|
||||
--> $DIR/needless_pass_by_value.rs:24:1
|
||||
--> $DIR/needless_pass_by_value.rs:26:1
|
||||
|
|
||||
24 | struct Wrapper(String);
|
||||
26 | struct Wrapper(String);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
help: consider taking a reference instead
|
||||
|
|
||||
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
|
||||
59 | fn test_destructure(x: Wrapper, y: &Wrapper, z: Wrapper) {
|
||||
60 | let Wrapper(s) = z; // moved
|
||||
61 | let Wrapper(ref t) = *y; // not moved
|
||||
62 | 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
|
||||
--> $DIR/needless_pass_by_value.rs:75:49
|
||||
|
|
||||
73 | fn test_blanket_ref<T: Foo, S: Serialize>(_foo: T, _serializable: S) {}
|
||||
75 | fn test_blanket_ref<T: Foo, S: Serialize>(_foo: T, _serializable: S) {}
|
||||
| ^ help: consider taking a reference instead: `&T`
|
||||
|
||||
error: this argument is passed by value, but not consumed in the function body
|
||||
--> $DIR/needless_pass_by_value.rs:75:18
|
||||
--> $DIR/needless_pass_by_value.rs:77:18
|
||||
|
|
||||
75 | fn issue_2114(s: String, t: String, u: Vec<i32>, v: Vec<i32>) {
|
||||
77 | fn issue_2114(s: String, t: String, u: Vec<i32>, v: Vec<i32>) {
|
||||
| ^^^^^^ help: consider taking a reference instead: `&String`
|
||||
|
||||
error: this argument is passed by value, but not consumed in the function body
|
||||
--> $DIR/needless_pass_by_value.rs:75:29
|
||||
--> $DIR/needless_pass_by_value.rs:77:29
|
||||
|
|
||||
75 | fn issue_2114(s: String, t: String, u: Vec<i32>, v: Vec<i32>) {
|
||||
77 | fn issue_2114(s: String, t: String, u: Vec<i32>, v: Vec<i32>) {
|
||||
| ^^^^^^
|
||||
help: consider changing the type to
|
||||
|
|
||||
75 | fn issue_2114(s: String, t: &str, u: Vec<i32>, v: Vec<i32>) {
|
||||
77 | fn issue_2114(s: String, t: &str, u: Vec<i32>, v: Vec<i32>) {
|
||||
| ^^^^
|
||||
help: change `t.clone()` to
|
||||
|
|
||||
77 | let _ = t.to_string();
|
||||
79 | let _ = t.to_string();
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
error: this argument is passed by value, but not consumed in the function body
|
||||
--> $DIR/needless_pass_by_value.rs:75:40
|
||||
--> $DIR/needless_pass_by_value.rs:77:40
|
||||
|
|
||||
75 | fn issue_2114(s: String, t: String, u: Vec<i32>, v: Vec<i32>) {
|
||||
77 | fn issue_2114(s: String, t: String, u: Vec<i32>, v: Vec<i32>) {
|
||||
| ^^^^^^^^ help: consider taking a reference instead: `&Vec<i32>`
|
||||
|
||||
error: this argument is passed by value, but not consumed in the function body
|
||||
--> $DIR/needless_pass_by_value.rs:75:53
|
||||
--> $DIR/needless_pass_by_value.rs:77:53
|
||||
|
|
||||
75 | fn issue_2114(s: String, t: String, u: Vec<i32>, v: Vec<i32>) {
|
||||
77 | fn issue_2114(s: String, t: String, u: Vec<i32>, v: Vec<i32>) {
|
||||
| ^^^^^^^^
|
||||
help: consider changing the type to
|
||||
|
|
||||
75 | fn issue_2114(s: String, t: String, u: Vec<i32>, v: &[i32]) {
|
||||
77 | fn issue_2114(s: String, t: String, u: Vec<i32>, v: &[i32]) {
|
||||
| ^^^^^^
|
||||
help: change `v.clone()` to
|
||||
|
|
||||
79 | let _ = v.to_owned();
|
||||
81 | let _ = v.to_owned();
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: this argument is passed by value, but not consumed in the function body
|
||||
--> $DIR/needless_pass_by_value.rs:87:12
|
||||
--> $DIR/needless_pass_by_value.rs:89:12
|
||||
|
|
||||
87 | s: String,
|
||||
89 | s: String,
|
||||
| ^^^^^^ 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:88:12
|
||||
--> $DIR/needless_pass_by_value.rs:90:12
|
||||
|
|
||||
88 | t: String,
|
||||
90 | t: String,
|
||||
| ^^^^^^ help: consider taking a reference instead: `&String`
|
||||
|
||||
error: this argument is passed by value, but not consumed in the function body
|
||||
--> $DIR/needless_pass_by_value.rs:100:13
|
||||
--> $DIR/needless_pass_by_value.rs:102:13
|
||||
|
|
||||
100 | _u: U,
|
||||
102 | _u: U,
|
||||
| ^ help: consider taking a reference instead: `&U`
|
||||
|
||||
error: this argument is passed by value, but not consumed in the function body
|
||||
--> $DIR/needless_pass_by_value.rs:101:13
|
||||
--> $DIR/needless_pass_by_value.rs:103:13
|
||||
|
|
||||
101 | _s: Self,
|
||||
103 | _s: Self,
|
||||
| ^^^^ help: consider taking a reference instead: `&Self`
|
||||
|
|
||||
help: consider marking this type as Copy if possible
|
||||
--> $DIR/needless_pass_by_value.rs:82:1
|
||||
--> $DIR/needless_pass_by_value.rs:84:1
|
||||
|
|
||||
82 | struct S<T, U>(T, U);
|
||||
84 | struct S<T, U>(T, U);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 16 previous errors
|
||||
|
Loading…
x
Reference in New Issue
Block a user