@@ -194,11 +194,57 @@ declare_clippy_lint! {
194
194
"a box of borrowed type"
195
195
}
196
196
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
+
197
243
pub struct Types {
198
244
vec_box_size_threshold : u64 ,
199
245
}
200
246
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 ] ) ;
202
248
203
249
impl < ' a , ' tcx > LateLintPass < ' a , ' tcx > for Types {
204
250
fn check_fn (
@@ -322,6 +368,27 @@ impl Types {
322
368
) ;
323
369
return ; // don't recurse into the type
324
370
}
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
+ }
325
392
} else if cx. tcx . is_diagnostic_item ( Symbol :: intern ( "vec_type" ) , def_id) {
326
393
if_chain ! {
327
394
// Get the _ part of Vec<_>
0 commit comments