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