@@ -171,11 +171,34 @@ declare_clippy_lint! {
171
171
"a borrow of a boxed type"
172
172
}
173
173
174
+ declare_clippy_lint ! {
175
+ /// **What it does:** Checks for use of `Box<&T>` anywhere in the code.
176
+ ///
177
+ /// **Why is this bad?** Any `Box<&T>` can also be a `&T`, which is more
178
+ /// general.
179
+ ///
180
+ /// **Known problems:** None.
181
+ ///
182
+ /// **Example:**
183
+ /// ```rust
184
+ /// fn foo(bar: Box<&usize>) {}
185
+ /// ```
186
+ ///
187
+ /// Better:
188
+ ///
189
+ /// ```rust
190
+ /// fn foo(bar: &usize) {}
191
+ /// ```
192
+ pub BOX_BORROWS ,
193
+ perf,
194
+ "a box of borrowed type"
195
+ }
196
+
174
197
pub struct Types {
175
198
vec_box_size_threshold : u64 ,
176
199
}
177
200
178
- impl_lint_pass ! ( Types => [ BOX_VEC , VEC_BOX , OPTION_OPTION , LINKEDLIST , BORROWED_BOX ] ) ;
201
+ impl_lint_pass ! ( Types => [ BOX_VEC , VEC_BOX , OPTION_OPTION , LINKEDLIST , BORROWED_BOX , BOX_BORROWS ] ) ;
179
202
180
203
impl < ' a , ' tcx > LateLintPass < ' a , ' tcx > for Types {
181
204
fn check_fn (
@@ -257,6 +280,7 @@ impl Types {
257
280
/// The parameter `is_local` distinguishes the context of the type; types from
258
281
/// local bindings should only be checked for the `BORROWED_BOX` lint.
259
282
#[ allow( clippy:: too_many_lines) ]
283
+ #[ allow( clippy:: cognitive_complexity) ]
260
284
fn check_ty ( & mut self , cx : & LateContext < ' _ , ' _ > , hir_ty : & hir:: Ty < ' _ > , is_local : bool ) {
261
285
if hir_ty. span . from_expansion ( ) {
262
286
return ;
@@ -267,6 +291,27 @@ impl Types {
267
291
let res = qpath_res ( cx, qpath, hir_id) ;
268
292
if let Some ( def_id) = res. opt_def_id ( ) {
269
293
if Some ( def_id) == cx. tcx . lang_items ( ) . owned_box ( ) {
294
+ if_chain ! {
295
+ let last = last_path_segment( qpath) ;
296
+ if let Some ( ref params) = last. args;
297
+ if !params. parenthesized;
298
+ if let Some ( ty) = params. args. iter( ) . find_map( |arg| match arg {
299
+ GenericArg :: Type ( ty) => Some ( ty) ,
300
+ _ => None ,
301
+ } ) ;
302
+ if let TyKind :: Rptr ( ..) = ty. kind;
303
+ let ty_ty = hir_ty_to_ty( cx. tcx, ty) ;
304
+ then {
305
+ span_lint_and_help(
306
+ cx,
307
+ BOX_BORROWS ,
308
+ hir_ty. span,
309
+ "usage of `Box<&T>`" ,
310
+ format!( "try `{}`" , ty_ty) . as_str( ) ,
311
+ ) ;
312
+ return ; // don't recurse into the type
313
+ }
314
+ }
270
315
if match_type_parameter ( cx, qpath, & paths:: VEC ) {
271
316
span_lint_and_help (
272
317
cx,
0 commit comments