Skip to content

Commit 4128b1d

Browse files
committed
useless Rc<Rc<T>>, Rc<Box<T>>, Rc<&T>
1 parent 3abac0a commit 4128b1d

12 files changed

+241
-127
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1195,7 +1195,6 @@ Released 2018-09-13
11951195
[`bool_comparison`]: https://rust-lang.github.io/rust-clippy/master/index.html#bool_comparison
11961196
[`borrow_interior_mutable_const`]: https://rust-lang.github.io/rust-clippy/master/index.html#borrow_interior_mutable_const
11971197
[`borrowed_box`]: https://rust-lang.github.io/rust-clippy/master/index.html#borrowed_box
1198-
[`box_borrows`]: https://rust-lang.github.io/rust-clippy/master/index.html#box_borrows
11991198
[`box_vec`]: https://rust-lang.github.io/rust-clippy/master/index.html#box_vec
12001199
[`boxed_local`]: https://rust-lang.github.io/rust-clippy/master/index.html#boxed_local
12011200
[`builtin_type_shadow`]: https://rust-lang.github.io/rust-clippy/master/index.html#builtin_type_shadow
@@ -1434,6 +1433,7 @@ Released 2018-09-13
14341433
[`range_plus_one`]: https://rust-lang.github.io/rust-clippy/master/index.html#range_plus_one
14351434
[`range_step_by_zero`]: https://rust-lang.github.io/rust-clippy/master/index.html#range_step_by_zero
14361435
[`range_zip_with_len`]: https://rust-lang.github.io/rust-clippy/master/index.html#range_zip_with_len
1436+
[`redundant_allocation`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_allocation
14371437
[`redundant_clone`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_clone
14381438
[`redundant_closure`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_closure
14391439
[`redundant_closure_call`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_closure_call

clippy_lints/src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -795,7 +795,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
795795
&try_err::TRY_ERR,
796796
&types::ABSURD_EXTREME_COMPARISONS,
797797
&types::BORROWED_BOX,
798-
&types::BOX_BORROWS,
799798
&types::BOX_VEC,
800799
&types::CAST_LOSSLESS,
801800
&types::CAST_POSSIBLE_TRUNCATION,
@@ -812,6 +811,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
812811
&types::LET_UNIT_VALUE,
813812
&types::LINKEDLIST,
814813
&types::OPTION_OPTION,
814+
&types::REDUNDANT_ALLOCATION,
815815
&types::TYPE_COMPLEXITY,
816816
&types::UNIT_ARG,
817817
&types::UNIT_CMP,
@@ -1368,7 +1368,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
13681368
LintId::of(&try_err::TRY_ERR),
13691369
LintId::of(&types::ABSURD_EXTREME_COMPARISONS),
13701370
LintId::of(&types::BORROWED_BOX),
1371-
LintId::of(&types::BOX_BORROWS),
13721371
LintId::of(&types::BOX_VEC),
13731372
LintId::of(&types::CAST_PTR_ALIGNMENT),
13741373
LintId::of(&types::CAST_REF_TO_MUT),
@@ -1378,6 +1377,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
13781377
LintId::of(&types::IMPLICIT_HASHER),
13791378
LintId::of(&types::LET_UNIT_VALUE),
13801379
LintId::of(&types::OPTION_OPTION),
1380+
LintId::of(&types::REDUNDANT_ALLOCATION),
13811381
LintId::of(&types::TYPE_COMPLEXITY),
13821382
LintId::of(&types::UNIT_ARG),
13831383
LintId::of(&types::UNIT_CMP),
@@ -1662,8 +1662,8 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
16621662
LintId::of(&redundant_clone::REDUNDANT_CLONE),
16631663
LintId::of(&slow_vector_initialization::SLOW_VECTOR_INITIALIZATION),
16641664
LintId::of(&trivially_copy_pass_by_ref::TRIVIALLY_COPY_PASS_BY_REF),
1665-
LintId::of(&types::BOX_BORROWS),
16661665
LintId::of(&types::BOX_VEC),
1666+
LintId::of(&types::REDUNDANT_ALLOCATION),
16671667
LintId::of(&vec::USELESS_VEC),
16681668
]);
16691669

clippy_lints/src/types.rs

Lines changed: 79 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -172,33 +172,35 @@ declare_clippy_lint! {
172172
}
173173

174174
declare_clippy_lint! {
175-
/// **What it does:** Checks for use of `Box<&T>` anywhere in the code.
175+
/// **What it does:** Checks for use of redundant allocations anywhere in the code.
176176
///
177-
/// **Why is this bad?** Any `Box<&T>` can also be a `&T`, which is more
178-
/// general.
177+
/// **Why is this bad?** Expressions such as `Rc<&T>`, `Rc<Rc<T>>`, `Rc<Box<T>>`, `Box<&T>`
178+
/// add an unnecessary level of indirection.
179179
///
180180
/// **Known problems:** None.
181181
///
182182
/// **Example:**
183183
/// ```rust
184-
/// fn foo(bar: Box<&usize>) {}
184+
/// # use std::rc::Rc;
185+
/// fn foo(bar: Rc<&usize>) {}
185186
/// ```
186187
///
187188
/// Better:
188189
///
189190
/// ```rust
191+
/// # use std::rc::Rc;
190192
/// fn foo(bar: &usize) {}
191193
/// ```
192-
pub BOX_BORROWS,
194+
pub REDUNDANT_ALLOCATION,
193195
perf,
194-
"a box of borrowed type"
196+
"redundant allocation"
195197
}
196198

197199
pub struct Types {
198200
vec_box_size_threshold: u64,
199201
}
200202

201-
impl_lint_pass!(Types => [BOX_VEC, VEC_BOX, OPTION_OPTION, LINKEDLIST, BORROWED_BOX, BOX_BORROWS]);
203+
impl_lint_pass!(Types => [BOX_VEC, VEC_BOX, OPTION_OPTION, LINKEDLIST, BORROWED_BOX, REDUNDANT_ALLOCATION]);
202204

203205
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Types {
204206
fn check_fn(
@@ -240,7 +242,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Types {
240242
}
241243

242244
/// Checks if `qpath` has last segment with type parameter matching `path`
243-
fn match_type_parameter(cx: &LateContext<'_, '_>, qpath: &QPath<'_>, path: &[&str]) -> bool {
245+
fn match_type_parameter(cx: &LateContext<'_, '_>, qpath: &QPath<'_>, path: &[&str]) -> Option<Span> {
244246
let last = last_path_segment(qpath);
245247
if_chain! {
246248
if let Some(ref params) = last.args;
@@ -253,10 +255,27 @@ fn match_type_parameter(cx: &LateContext<'_, '_>, qpath: &QPath<'_>, path: &[&st
253255
if let Some(did) = qpath_res(cx, qpath, ty.hir_id).opt_def_id();
254256
if match_def_path(cx, did, path);
255257
then {
256-
return true;
258+
return Some(ty.span);
257259
}
258260
}
259-
false
261+
None
262+
}
263+
264+
fn match_borrows_parameter(_cx: &LateContext<'_, '_>, qpath: &QPath<'_>) -> Option<Span> {
265+
let last = last_path_segment(qpath);
266+
if_chain! {
267+
if let Some(ref params) = last.args;
268+
if !params.parenthesized;
269+
if let Some(ty) = params.args.iter().find_map(|arg| match arg {
270+
GenericArg::Type(ty) => Some(ty),
271+
_ => None,
272+
});
273+
if let TyKind::Rptr(..) = ty.kind;
274+
then {
275+
return Some(ty.span);
276+
}
277+
}
278+
None
260279
}
261280

262281
impl Types {
@@ -280,7 +299,6 @@ impl Types {
280299
/// The parameter `is_local` distinguishes the context of the type; types from
281300
/// local bindings should only be checked for the `BORROWED_BOX` lint.
282301
#[allow(clippy::too_many_lines)]
283-
#[allow(clippy::cognitive_complexity)]
284302
fn check_ty(&mut self, cx: &LateContext<'_, '_>, hir_ty: &hir::Ty<'_>, is_local: bool) {
285303
if hir_ty.span.from_expansion() {
286304
return;
@@ -291,28 +309,19 @@ impl Types {
291309
let res = qpath_res(cx, qpath, hir_id);
292310
if let Some(def_id) = res.opt_def_id() {
293311
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-
}
312+
if let Some(span) = match_borrows_parameter(cx, qpath) {
313+
span_lint_and_sugg(
314+
cx,
315+
REDUNDANT_ALLOCATION,
316+
hir_ty.span,
317+
"usage of `Box<&T>`",
318+
"try",
319+
snippet(cx, span, "..").to_string(),
320+
Applicability::MachineApplicable,
321+
);
322+
return; // don't recurse into the type
314323
}
315-
if match_type_parameter(cx, qpath, &paths::VEC) {
324+
if let Some(_) = match_type_parameter(cx, qpath, &paths::VEC) {
316325
span_lint_and_help(
317326
cx,
318327
BOX_VEC,
@@ -322,6 +331,43 @@ impl Types {
322331
);
323332
return; // don't recurse into the type
324333
}
334+
} else if Some(def_id) == cx.tcx.lang_items().rc() {
335+
if let Some(span) = match_type_parameter(cx, qpath, &paths::RC) {
336+
span_lint_and_sugg(
337+
cx,
338+
REDUNDANT_ALLOCATION,
339+
hir_ty.span,
340+
"usage of `Rc<Rc<T>>`",
341+
"try",
342+
snippet(cx, span, "..").to_string(),
343+
Applicability::MachineApplicable,
344+
);
345+
return; // don't recurse into the type
346+
}
347+
if let Some(span) = match_type_parameter(cx, qpath, &paths::BOX) {
348+
span_lint_and_sugg(
349+
cx,
350+
REDUNDANT_ALLOCATION,
351+
hir_ty.span,
352+
"usage of `Rc<Box<T>>`",
353+
"try",
354+
snippet(cx, span, "..").to_string(),
355+
Applicability::MachineApplicable,
356+
);
357+
return; // don't recurse into the type
358+
}
359+
if let Some(span) = match_borrows_parameter(cx, qpath) {
360+
span_lint_and_sugg(
361+
cx,
362+
REDUNDANT_ALLOCATION,
363+
hir_ty.span,
364+
"usage of `Rc<&T>`",
365+
"try",
366+
snippet(cx, span, "..").to_string(),
367+
Applicability::MachineApplicable,
368+
);
369+
return; // don't recurse into the type
370+
}
325371
} else if cx.tcx.is_diagnostic_item(Symbol::intern("vec_type"), def_id) {
326372
if_chain! {
327373
// Get the _ part of Vec<_>
@@ -359,7 +405,7 @@ impl Types {
359405
}
360406
}
361407
} else if match_def_path(cx, def_id, &paths::OPTION) {
362-
if match_type_parameter(cx, qpath, &paths::OPTION) {
408+
if let Some(_) = match_type_parameter(cx, qpath, &paths::OPTION) {
363409
span_lint(
364410
cx,
365411
OPTION_OPTION,

clippy_lints/src/utils/paths.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ pub const BEGIN_PANIC: [&str; 3] = ["std", "panicking", "begin_panic"];
1010
pub const BEGIN_PANIC_FMT: [&str; 3] = ["std", "panicking", "begin_panic_fmt"];
1111
pub const BINARY_HEAP: [&str; 4] = ["alloc", "collections", "binary_heap", "BinaryHeap"];
1212
pub const BORROW_TRAIT: [&str; 3] = ["core", "borrow", "Borrow"];
13+
pub const BOX: [&str; 3] = ["alloc", "boxed", "Box"];
1314
pub const BTREEMAP: [&str; 5] = ["alloc", "collections", "btree", "map", "BTreeMap"];
1415
pub const BTREEMAP_ENTRY: [&str; 5] = ["alloc", "collections", "btree", "map", "Entry"];
1516
pub const BTREESET: [&str; 5] = ["alloc", "collections", "btree", "set", "BTreeSet"];

src/lintlist/mod.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -101,13 +101,6 @@ pub static ref ALL_LINTS: Vec<Lint> = vec![
101101
deprecation: None,
102102
module: "types",
103103
},
104-
Lint {
105-
name: "box_borrows",
106-
group: "perf",
107-
desc: "a box of borrowed type",
108-
deprecation: None,
109-
module: "types",
110-
},
111104
Lint {
112105
name: "box_vec",
113106
group: "perf",
@@ -1732,6 +1725,13 @@ pub static ref ALL_LINTS: Vec<Lint> = vec![
17321725
deprecation: None,
17331726
module: "ranges",
17341727
},
1728+
Lint {
1729+
name: "redundant_allocation",
1730+
group: "perf",
1731+
desc: "redundant allocation",
1732+
deprecation: None,
1733+
module: "types",
1734+
},
17351735
Lint {
17361736
name: "redundant_clone",
17371737
group: "perf",

tests/ui/box_borrows.rs

Lines changed: 0 additions & 30 deletions
This file was deleted.

tests/ui/box_borrows.stderr

Lines changed: 0 additions & 51 deletions
This file was deleted.

tests/ui/must_use_candidates.fixed

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// run-rustfix
22
#![feature(never_type)]
3-
#![allow(unused_mut)]
3+
#![allow(unused_mut, clippy::redundant_allocation)]
44
#![warn(clippy::must_use_candidate)]
55
use std::rc::Rc;
66
use std::sync::atomic::{AtomicBool, Ordering};

tests/ui/must_use_candidates.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// run-rustfix
22
#![feature(never_type)]
3-
#![allow(unused_mut)]
3+
#![allow(unused_mut, clippy::redundant_allocation)]
44
#![warn(clippy::must_use_candidate)]
55
use std::rc::Rc;
66
use std::sync::atomic::{AtomicBool, Ordering};

0 commit comments

Comments
 (0)