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