• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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