]> git.lizzy.rs Git - rust.git/blob - tests/ui/needless_pass_by_value.rs
Auto merge of #3635 - matthiaskrgr:revert_random_state_3603, r=xfix
[rust.git] / tests / ui / needless_pass_by_value.rs
1 // Copyright 2014-2018 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution.
3 //
4 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
5 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
7 // option. This file may not be copied, modified, or distributed
8 // except according to those terms.
9
10 #![warn(clippy::needless_pass_by_value)]
11 #![allow(
12     dead_code,
13     clippy::single_match,
14     clippy::redundant_pattern_matching,
15     clippy::many_single_char_names,
16     clippy::option_option
17 )]
18
19 use std::borrow::Borrow;
20 use std::convert::AsRef;
21
22 // `v` should be warned
23 // `w`, `x` and `y` are allowed (moved or mutated)
24 fn foo<T: Default>(v: Vec<T>, w: Vec<T>, mut x: Vec<T>, y: Vec<T>) -> Vec<T> {
25     assert_eq!(v.len(), 42);
26
27     consume(w);
28
29     x.push(T::default());
30
31     y
32 }
33
34 fn consume<T>(_: T) {}
35
36 struct Wrapper(String);
37
38 fn bar(x: String, y: Wrapper) {
39     assert_eq!(x.len(), 42);
40     assert_eq!(y.0.len(), 42);
41 }
42
43 // V implements `Borrow<V>`, but should be warned correctly
44 fn test_borrow_trait<T: Borrow<str>, U: AsRef<str>, V>(t: T, u: U, v: V) {
45     println!("{}", t.borrow());
46     println!("{}", u.as_ref());
47     consume(&v);
48 }
49
50 // ok
51 fn test_fn<F: Fn(i32) -> i32>(f: F) {
52     f(1);
53 }
54
55 // x should be warned, but y is ok
56 fn test_match(x: Option<Option<String>>, y: Option<Option<String>>) {
57     match x {
58         Some(Some(_)) => 1, // not moved
59         _ => 0,
60     };
61
62     match y {
63         Some(Some(s)) => consume(s), // moved
64         _ => (),
65     };
66 }
67
68 // x and y should be warned, but z is ok
69 fn test_destructure(x: Wrapper, y: Wrapper, z: Wrapper) {
70     let Wrapper(s) = z; // moved
71     let Wrapper(ref t) = y; // not moved
72     let Wrapper(_) = y; // still not moved
73
74     assert_eq!(x.0.len(), s.len());
75     println!("{}", t);
76 }
77
78 trait Foo {}
79
80 // `S: Serialize` is allowed to be passed by value, since a caller can pass `&S` instead
81 trait Serialize {}
82 impl<'a, T> Serialize for &'a T where T: Serialize {}
83 impl Serialize for i32 {}
84
85 fn test_blanket_ref<T: Foo, S: Serialize>(_foo: T, _serializable: S) {}
86
87 fn issue_2114(s: String, t: String, u: Vec<i32>, v: Vec<i32>) {
88     s.capacity();
89     let _ = t.clone();
90     u.capacity();
91     let _ = v.clone();
92 }
93
94 struct S<T, U>(T, U);
95
96 impl<T: Serialize, U> S<T, U> {
97     fn foo(
98         self,
99         // taking `self` by value is always allowed
100         s: String,
101         t: String,
102     ) -> usize {
103         s.len() + t.capacity()
104     }
105
106     fn bar(_t: T // Ok, since `&T: Serialize` too
107     ) {
108     }
109
110     fn baz(&self, _u: U, _s: Self) {}
111 }
112
113 trait FalsePositive {
114     fn visit_str(s: &str);
115     fn visit_string(s: String) {
116         Self::visit_str(&s);
117     }
118 }
119
120 // shouldn't warn on extern funcs
121 extern "C" fn ext(x: String) -> usize {
122     x.len()
123 }
124
125 // whitelist RangeArgument
126 fn range<T: ::std::ops::RangeBounds<usize>>(range: T) {
127     let _ = range.start_bound();
128 }
129
130 struct CopyWrapper(u32);
131
132 fn bar_copy(x: u32, y: CopyWrapper) {
133     assert_eq!(x, 42);
134     assert_eq!(y.0, 42);
135 }
136
137 // x and y should be warned, but z is ok
138 fn test_destructure_copy(x: CopyWrapper, y: CopyWrapper, z: CopyWrapper) {
139     let CopyWrapper(s) = z; // moved
140     let CopyWrapper(ref t) = y; // not moved
141     let CopyWrapper(_) = y; // still not moved
142
143     assert_eq!(x.0, s);
144     println!("{}", t);
145 }
146
147 // The following 3 lines should not cause an ICE. See #2831
148 trait Bar<'a, A> {}
149 impl<'b, T> Bar<'b, T> for T {}
150 fn some_fun<'b, S: Bar<'b, ()>>(_item: S) {}
151
152 // Also this should not cause an ICE. See #2831
153 trait Club<'a, A> {}
154 impl<T> Club<'static, T> for T {}
155 fn more_fun(_item: impl Club<'static, i32>) {}
156
157 fn main() {}