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