@@ -194,11 +194,57 @@ declare_clippy_lint! {
194194 "a box of borrowed type"
195195}
196196
197+ declare_clippy_lint ! {
198+ /// **What it does:** Checks for use of `Rc<Rc<T>>` anywhere in the code.
199+ ///
200+ /// **Why is this bad?** Reference counting pointer of reference counting pointer
201+ /// is an unnecessary level of indirection.
202+ ///
203+ /// **Known problems:** None.
204+ ///
205+ /// **Example:**
206+ /// ```rust
207+ /// fn foo(bar: Rc<Rc<T>>) {}
208+ /// ```
209+ ///
210+ /// Better:
211+ ///
212+ /// ```rust
213+ /// fn foo(bar: Rc<T>) {}
214+ /// ```
215+ pub RC_RC ,
216+ perf,
217+ "an Rc of Rc"
218+ }
219+
220+ declare_clippy_lint ! {
221+ /// **What it does:** Checks for use of `Rc<Box<T>>` anywhere in the code.
222+ ///
223+ /// **Why is this bad?** `Rc` already keeps its contents in a separate area on
224+ /// the heap. So if you `Box` its contents, you just add another level of indirection.
225+ ///
226+ /// **Known problems:** None.
227+ ///
228+ /// **Example:**
229+ /// ```rust
230+ /// fn foo(bar: Rc<Box<T>>) {}
231+ /// ```
232+ ///
233+ /// Better:
234+ ///
235+ /// ```rust
236+ /// fn foo(bar: Rc<T>) {}
237+ /// ```
238+ pub RC_BOX ,
239+ perf,
240+ "an Rc of Box"
241+ }
242+
197243pub struct Types {
198244 vec_box_size_threshold : u64 ,
199245}
200246
201- impl_lint_pass ! ( Types => [ BOX_VEC , VEC_BOX , OPTION_OPTION , LINKEDLIST , BORROWED_BOX , BOX_BORROWS ] ) ;
247+ impl_lint_pass ! ( Types => [ BOX_VEC , VEC_BOX , OPTION_OPTION , LINKEDLIST , BORROWED_BOX , BOX_BORROWS , RC_RC , RC_BOX ] ) ;
202248
203249impl < ' a , ' tcx > LateLintPass < ' a , ' tcx > for Types {
204250 fn check_fn (
@@ -322,6 +368,27 @@ impl Types {
322368 ) ;
323369 return ; // don't recurse into the type
324370 }
371+ } else if Some ( def_id) == cx. tcx . lang_items ( ) . rc ( ) {
372+ if match_type_parameter ( cx, qpath, & paths:: RC ) {
373+ span_lint_and_help (
374+ cx,
375+ RC_RC ,
376+ hir_ty. span ,
377+ "usage of `Rc<Rc<T>>`" ,
378+ "Rc<Rc<T>> can be simplified to Rc<T>" ,
379+ ) ;
380+ return ; // don't recurse into the type
381+ }
382+ if match_type_parameter ( cx, qpath, & paths:: BOX ) {
383+ span_lint_and_help (
384+ cx,
385+ RC_BOX ,
386+ hir_ty. span ,
387+ "usage of `Rc<Box<T>>`" ,
388+ "Rc<Box<T>> can be simplified to Rc<T>" ,
389+ ) ;
390+ return ; // don't recurse into the type
391+ }
325392 } else if cx. tcx . is_diagnostic_item ( Symbol :: intern ( "vec_type" ) , def_id) {
326393 if_chain ! {
327394 // Get the _ part of Vec<_>
0 commit comments