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