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