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