@@ -171,11 +171,34 @@ declare_clippy_lint! {
171171 "a borrow of a boxed type"
172172}
173173
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+
174197pub struct Types {
175198 vec_box_size_threshold : u64 ,
176199}
177200
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 ] ) ;
179202
180203impl < ' a , ' tcx > LateLintPass < ' a , ' tcx > for Types {
181204 fn check_fn (
@@ -257,6 +280,7 @@ impl Types {
257280 /// The parameter `is_local` distinguishes the context of the type; types from
258281 /// local bindings should only be checked for the `BORROWED_BOX` lint.
259282 #[ allow( clippy:: too_many_lines) ]
283+ #[ allow( clippy:: cognitive_complexity) ]
260284 fn check_ty ( & mut self , cx : & LateContext < ' _ , ' _ > , hir_ty : & hir:: Ty < ' _ > , is_local : bool ) {
261285 if hir_ty. span . from_expansion ( ) {
262286 return ;
@@ -267,6 +291,27 @@ impl Types {
267291 let res = qpath_res ( cx, qpath, hir_id) ;
268292 if let Some ( def_id) = res. opt_def_id ( ) {
269293 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+ }
270315 if match_type_parameter ( cx, qpath, & paths:: VEC ) {
271316 span_lint_and_help (
272317 cx,
0 commit comments