]> git.lizzy.rs Git - rust.git/blob - src/tools/clippy/tests/ui/escape_analysis.rs
Merge commit '2f6439ae6a6803d030cceb3ee14c9150e91b328b' into clippyup
[rust.git] / src / tools / clippy / tests / ui / escape_analysis.rs
1 #![feature(box_syntax)]
2 #![allow(
3     clippy::borrowed_box,
4     clippy::needless_pass_by_value,
5     clippy::unused_unit,
6     clippy::redundant_clone,
7     clippy::match_single_binding
8 )]
9 #![warn(clippy::boxed_local)]
10
11 #[derive(Clone)]
12 struct A;
13
14 impl A {
15     fn foo(&self) {}
16 }
17
18 trait Z {
19     fn bar(&self);
20 }
21
22 impl Z for A {
23     fn bar(&self) {
24         //nothing
25     }
26 }
27
28 fn main() {}
29
30 fn ok_box_trait(boxed_trait: &Box<dyn Z>) {
31     let boxed_local = boxed_trait;
32     // done
33 }
34
35 fn warn_call() {
36     let x = box A;
37     x.foo();
38 }
39
40 fn warn_arg(x: Box<A>) {
41     x.foo();
42 }
43
44 fn nowarn_closure_arg() {
45     let x = Some(box A);
46     x.map_or((), |x| take_ref(&x));
47 }
48
49 fn warn_rename_call() {
50     let x = box A;
51
52     let y = x;
53     y.foo(); // via autoderef
54 }
55
56 fn warn_notuse() {
57     let bz = box A;
58 }
59
60 fn warn_pass() {
61     let bz = box A;
62     take_ref(&bz); // via deref coercion
63 }
64
65 fn nowarn_return() -> Box<A> {
66     box A // moved out, "escapes"
67 }
68
69 fn nowarn_move() {
70     let bx = box A;
71     drop(bx) // moved in, "escapes"
72 }
73 fn nowarn_call() {
74     let bx = box A;
75     bx.clone(); // method only available to Box, not via autoderef
76 }
77
78 fn nowarn_pass() {
79     let bx = box A;
80     take_box(&bx); // fn needs &Box
81 }
82
83 fn take_box(x: &Box<A>) {}
84 fn take_ref(x: &A) {}
85
86 fn nowarn_ref_take() {
87     // false positive, should actually warn
88     let x = box A;
89     let y = &x;
90     take_box(y);
91 }
92
93 fn nowarn_match() {
94     let x = box A; // moved into a match
95     match x {
96         y => drop(y),
97     }
98 }
99
100 fn warn_match() {
101     let x = box A;
102     match &x {
103         // not moved
104         ref y => (),
105     }
106 }
107
108 fn nowarn_large_array() {
109     // should not warn, is large array
110     // and should not be on stack
111     let x = box [1; 10000];
112     match &x {
113         // not moved
114         ref y => (),
115     }
116 }
117
118 /// ICE regression test
119 pub trait Foo {
120     type Item;
121 }
122
123 impl<'a> Foo for &'a () {
124     type Item = ();
125 }
126
127 pub struct PeekableSeekable<I: Foo> {
128     _peeked: I::Item,
129 }
130
131 pub fn new(_needs_name: Box<PeekableSeekable<&()>>) -> () {}
132
133 /// Regression for #916, #1123
134 ///
135 /// This shouldn't warn for `boxed_local`as the implementation of a trait
136 /// can't change much about the trait definition.
137 trait BoxedAction {
138     fn do_sth(self: Box<Self>);
139 }
140
141 impl BoxedAction for u64 {
142     fn do_sth(self: Box<Self>) {
143         println!("{}", *self)
144     }
145 }
146
147 /// Regression for #1478
148 ///
149 /// This shouldn't warn for `boxed_local`as self itself is a box type.
150 trait MyTrait {
151     fn do_sth(self);
152 }
153
154 impl<T> MyTrait for Box<T> {
155     fn do_sth(self) {}
156 }
157
158 // Issue #3739 - capture in closures
159 mod issue_3739 {
160     use super::A;
161
162     fn consume<T>(_: T) {}
163     fn borrow<T>(_: &T) {}
164
165     fn closure_consume(x: Box<A>) {
166         let _ = move || {
167             consume(x);
168         };
169     }
170
171     fn closure_borrow(x: Box<A>) {
172         let _ = || {
173             borrow(&x);
174         };
175     }
176 }
177
178 /// Issue #5542
179 ///
180 /// This shouldn't warn for `boxed_local` as it is intended to called from non-Rust code.
181 pub extern "C" fn do_not_warn_me(_c_pointer: Box<String>) -> () {}
182
183 #[rustfmt::skip] // Forces rustfmt to not add ABI
184 pub extern fn do_not_warn_me_no_abi(_c_pointer: Box<String>) -> () {}