]> git.lizzy.rs Git - rust.git/blob - tests/ui/needless_pass_by_value.rs
Merge branch 'master' of github.com:Manishearth/rust-clippy into fold_any
[rust.git] / tests / ui / needless_pass_by_value.rs
1
2
3
4 #![warn(needless_pass_by_value)]
5 #![allow(dead_code, single_match, if_let_redundant_pattern_matching, many_single_char_names, option_option)]
6
7 #![feature(collections_range)]
8
9 use std::borrow::Borrow;
10 use std::convert::AsRef;
11
12 // `v` should be warned
13 // `w`, `x` and `y` are allowed (moved or mutated)
14 fn foo<T: Default>(v: Vec<T>, w: Vec<T>, mut x: Vec<T>, y: Vec<T>) -> Vec<T> {
15     assert_eq!(v.len(), 42);
16
17     consume(w);
18
19     x.push(T::default());
20
21     y
22 }
23
24 fn consume<T>(_: T) {}
25
26 struct Wrapper(String);
27
28 fn bar(x: String, y: Wrapper) {
29     assert_eq!(x.len(), 42);
30     assert_eq!(y.0.len(), 42);
31 }
32
33 // V implements `Borrow<V>`, but should be warned correctly
34 fn test_borrow_trait<T: Borrow<str>, U: AsRef<str>, V>(t: T, u: U, v: V) {
35     println!("{}", t.borrow());
36     println!("{}", u.as_ref());
37     consume(&v);
38 }
39
40 // ok
41 fn test_fn<F: Fn(i32) -> i32>(f: F) {
42     f(1);
43 }
44
45 // x should be warned, but y is ok
46 fn test_match(x: Option<Option<String>>, y: Option<Option<String>>) {
47     match x {
48         Some(Some(_)) => 1, // not moved
49         _ => 0,
50     };
51
52     match y {
53         Some(Some(s)) => consume(s), // moved
54         _ => (),
55     };
56 }
57
58 // x and y should be warned, but z is ok
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
63
64     assert_eq!(x.0.len(), s.len());
65     println!("{}", t);
66 }
67
68 trait Foo {}
69
70 // `S: Serialize` is allowed to be passed by value, since a caller can pass `&S` instead
71 trait Serialize {}
72 impl<'a, T> Serialize for &'a T where T: Serialize {}
73 impl Serialize for i32 {}
74
75 fn test_blanket_ref<T: Foo, S: Serialize>(_foo: T, _serializable: S) {}
76
77 fn issue_2114(s: String, t: String, u: Vec<i32>, v: Vec<i32>) {
78     s.capacity();
79     let _ = t.clone();
80     u.capacity();
81     let _ = v.clone();
82 }
83
84 struct S<T, U>(T, U);
85
86 impl<T: Serialize, U> S<T, U> {
87     fn foo(
88         self, // taking `self` by value is always allowed
89         s: String,
90         t: String,
91     ) -> usize {
92         s.len() + t.capacity()
93     }
94
95     fn bar(
96         _t: T, // Ok, since `&T: Serialize` too
97     ) {
98     }
99
100     fn baz(
101         &self,
102         _u: U,
103         _s: Self,
104     ) {
105     }
106 }
107
108 trait FalsePositive {
109     fn visit_str(s: &str);
110     fn visit_string(s: String) {
111         Self::visit_str(&s);
112     }
113 }
114
115 // shouldn't warn on extern funcs
116 extern "C" fn ext(x: String) -> usize { x.len() }
117
118 // whitelist RangeArgument
119 fn range<T: ::std::collections::range::RangeArgument<usize>>(range: T) {
120     let _ = range.start();
121 }
122
123 struct CopyWrapper(u32);
124
125 fn bar_copy(x: u32, y: CopyWrapper) {
126     assert_eq!(x, 42);
127     assert_eq!(y.0, 42);
128 }
129
130 // x and y should be warned, but z is ok
131 fn test_destructure_copy(x: CopyWrapper, y: CopyWrapper, z: CopyWrapper) {
132     let CopyWrapper(s) = z; // moved
133     let CopyWrapper(ref t) = y; // not moved
134     let CopyWrapper(_) = y; // still not moved
135
136     assert_eq!(x.0, s);
137     println!("{}", t);
138 }
139
140 fn main() {}