Skip to content

Commit ef2e2f0

Browse files
committed
Auto merge of #7693 - F3real:vec2, r=Manishearth
Expand box_vec lint to box_collection fixed #7451 changelog: Expand `box_vec` into [`box_collection`], and have it error on all sorts of boxed collections
2 parents 3cd54ba + bb971e0 commit ef2e2f0

File tree

9 files changed

+99
-49
lines changed

9 files changed

+99
-49
lines changed

CHANGELOG.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -1050,7 +1050,7 @@ Released 2020-11-19
10501050
[#5913](https://github.com/rust-lang/rust-clippy/pull/5913)
10511051
* Add example of false positive to [`ptr_arg`] docs.
10521052
[#5885](https://github.com/rust-lang/rust-clippy/pull/5885)
1053-
* [`box_vec`], [`vec_box`] and [`borrowed_box`]: add link to the documentation of `Box`
1053+
* [`box_vec`](https://rust-lang.github.io/rust-clippy/master/index.html#box_collection), [`vec_box`] and [`borrowed_box`]: add link to the documentation of `Box`
10541054
[#6023](https://github.com/rust-lang/rust-clippy/pull/6023)
10551055

10561056
## Rust 1.47
@@ -2570,7 +2570,7 @@ Released 2018-09-13
25702570
[`bool_comparison`]: https://rust-lang.github.io/rust-clippy/master/index.html#bool_comparison
25712571
[`borrow_interior_mutable_const`]: https://rust-lang.github.io/rust-clippy/master/index.html#borrow_interior_mutable_const
25722572
[`borrowed_box`]: https://rust-lang.github.io/rust-clippy/master/index.html#borrowed_box
2573-
[`box_vec`]: https://rust-lang.github.io/rust-clippy/master/index.html#box_vec
2573+
[`box_collection`]: https://rust-lang.github.io/rust-clippy/master/index.html#box_collection
25742574
[`boxed_local`]: https://rust-lang.github.io/rust-clippy/master/index.html#boxed_local
25752575
[`branches_sharing_code`]: https://rust-lang.github.io/rust-clippy/master/index.html#branches_sharing_code
25762576
[`builtin_type_shadow`]: https://rust-lang.github.io/rust-clippy/master/index.html#builtin_type_shadow

clippy_lints/src/lib.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -956,7 +956,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
956956
transmuting_null::TRANSMUTING_NULL,
957957
try_err::TRY_ERR,
958958
types::BORROWED_BOX,
959-
types::BOX_VEC,
959+
types::BOX_COLLECTION,
960960
types::LINKEDLIST,
961961
types::OPTION_OPTION,
962962
types::RC_BUFFER,
@@ -1454,7 +1454,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
14541454
LintId::of(transmuting_null::TRANSMUTING_NULL),
14551455
LintId::of(try_err::TRY_ERR),
14561456
LintId::of(types::BORROWED_BOX),
1457-
LintId::of(types::BOX_VEC),
1457+
LintId::of(types::BOX_COLLECTION),
14581458
LintId::of(types::REDUNDANT_ALLOCATION),
14591459
LintId::of(types::TYPE_COMPLEXITY),
14601460
LintId::of(types::VEC_BOX),
@@ -1792,7 +1792,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
17921792
LintId::of(redundant_clone::REDUNDANT_CLONE),
17931793
LintId::of(slow_vector_initialization::SLOW_VECTOR_INITIALIZATION),
17941794
LintId::of(stable_sort_primitive::STABLE_SORT_PRIMITIVE),
1795-
LintId::of(types::BOX_VEC),
1795+
LintId::of(types::BOX_COLLECTION),
17961796
LintId::of(types::REDUNDANT_ALLOCATION),
17971797
LintId::of(vec::USELESS_VEC),
17981798
LintId::of(vec_init_then_push::VEC_INIT_THEN_PUSH),
@@ -2193,6 +2193,7 @@ pub fn register_renamed(ls: &mut rustc_lint::LintStore) {
21932193
ls.register_renamed("clippy::cyclomatic_complexity", "clippy::cognitive_complexity");
21942194
ls.register_renamed("clippy::const_static_lifetime", "clippy::redundant_static_lifetimes");
21952195
ls.register_renamed("clippy::option_and_then_some", "clippy::bind_instead_of_map");
2196+
ls.register_renamed("clippy::box_vec", "clippy::box_collection");
21962197
ls.register_renamed("clippy::block_in_if_condition_expr", "clippy::blocks_in_if_conditions");
21972198
ls.register_renamed("clippy::block_in_if_condition_stmt", "clippy::blocks_in_if_conditions");
21982199
ls.register_renamed("clippy::option_map_unwrap_or", "clippy::map_unwrap_or");
+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
use clippy_utils::diagnostics::span_lint_and_help;
2+
use clippy_utils::is_ty_param_diagnostic_item;
3+
use rustc_hir::{self as hir, def_id::DefId, QPath};
4+
use rustc_lint::LateContext;
5+
use rustc_span::symbol::sym;
6+
7+
use super::BOX_COLLECTION;
8+
9+
pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_>, def_id: DefId) -> bool {
10+
if_chain! {
11+
if Some(def_id) == cx.tcx.lang_items().owned_box();
12+
if let Some(item_type) = get_std_collection(cx, qpath);
13+
then {
14+
let generic = if item_type == "String" {
15+
""
16+
} else {
17+
"<..>"
18+
};
19+
span_lint_and_help(
20+
cx,
21+
BOX_COLLECTION,
22+
hir_ty.span,
23+
&format!(
24+
"you seem to be trying to use `Box<{outer}{generic}>`. Consider using just `{outer}{generic}`",
25+
outer=item_type,
26+
generic = generic),
27+
None,
28+
&format!(
29+
"`{outer}{generic}` is already on the heap, `Box<{outer}{generic}>` makes an extra allocation",
30+
outer=item_type,
31+
generic = generic)
32+
);
33+
true
34+
} else {
35+
false
36+
}
37+
}
38+
}
39+
40+
fn get_std_collection(cx: &LateContext<'_>, qpath: &QPath<'_>) -> Option<String> {
41+
if is_ty_param_diagnostic_item(cx, qpath, sym::vec_type).is_some() {
42+
Some(String::from("Vec"))
43+
} else if is_ty_param_diagnostic_item(cx, qpath, sym::string_type).is_some() {
44+
Some(String::from("String"))
45+
} else if is_ty_param_diagnostic_item(cx, qpath, sym::hashmap_type).is_some() {
46+
Some(String::from("HashMap"))
47+
} else {
48+
None
49+
}
50+
}

clippy_lints/src/types/box_vec.rs

-25
This file was deleted.

clippy_lints/src/types/mod.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
mod borrowed_box;
2-
mod box_vec;
2+
mod box_collection;
33
mod linked_list;
44
mod option_option;
55
mod rc_buffer;
@@ -21,12 +21,12 @@ use rustc_span::source_map::Span;
2121

2222
declare_clippy_lint! {
2323
/// ### What it does
24-
/// Checks for use of `Box<Vec<_>>` anywhere in the code.
24+
/// Checks for use of `Box<T>` where T is a collection such as Vec anywhere in the code.
2525
/// Check the [Box documentation](https://doc.rust-lang.org/std/boxed/index.html) for more information.
2626
///
2727
/// ### Why is this bad?
28-
/// `Vec` already keeps its contents in a separate area on
29-
/// the heap. So if you `Box` it, you just add another level of indirection
28+
/// Collections already keeps their contents in a separate area on
29+
/// the heap. So if you `Box` them, you just add another level of indirection
3030
/// without any benefit whatsoever.
3131
///
3232
/// ### Example
@@ -43,7 +43,7 @@ declare_clippy_lint! {
4343
/// values: Vec<Foo>,
4444
/// }
4545
/// ```
46-
pub BOX_VEC,
46+
pub BOX_COLLECTION,
4747
perf,
4848
"usage of `Box<Vec<T>>`, vector elements are already on the heap"
4949
}
@@ -298,7 +298,7 @@ pub struct Types {
298298
avoid_breaking_exported_api: bool,
299299
}
300300

301-
impl_lint_pass!(Types => [BOX_VEC, VEC_BOX, OPTION_OPTION, LINKEDLIST, BORROWED_BOX, REDUNDANT_ALLOCATION, RC_BUFFER, RC_MUTEX, TYPE_COMPLEXITY]);
301+
impl_lint_pass!(Types => [BOX_COLLECTION, VEC_BOX, OPTION_OPTION, LINKEDLIST, BORROWED_BOX, REDUNDANT_ALLOCATION, RC_BUFFER, RC_MUTEX, TYPE_COMPLEXITY]);
302302

303303
impl<'tcx> LateLintPass<'tcx> for Types {
304304
fn check_fn(&mut self, cx: &LateContext<'_>, _: FnKind<'_>, decl: &FnDecl<'_>, _: &Body<'_>, _: Span, id: HirId) {
@@ -447,7 +447,7 @@ impl Types {
447447
// in `clippy_lints::utils::conf.rs`
448448

449449
let mut triggered = false;
450-
triggered |= box_vec::check(cx, hir_ty, qpath, def_id);
450+
triggered |= box_collection::check(cx, hir_ty, qpath, def_id);
451451
triggered |= redundant_allocation::check(cx, hir_ty, qpath, def_id);
452452
triggered |= rc_buffer::check(cx, hir_ty, qpath, def_id);
453453
triggered |= vec_box::check(cx, hir_ty, qpath, def_id, self.vec_box_size_threshold);

clippy_lints/src/utils/conf.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ macro_rules! define_Conf {
136136
}
137137

138138
define_Conf! {
139-
/// Lint: ENUM_VARIANT_NAMES, LARGE_TYPES_PASSED_BY_VALUE, TRIVIALLY_COPY_PASS_BY_REF, UNNECESSARY_WRAPS, UPPER_CASE_ACRONYMS, WRONG_SELF_CONVENTION, BOX_VEC, REDUNDANT_ALLOCATION, RC_BUFFER, VEC_BOX, OPTION_OPTION, LINKEDLIST, RC_MUTEX.
139+
/// Lint: ENUM_VARIANT_NAMES, LARGE_TYPES_PASSED_BY_VALUE, TRIVIALLY_COPY_PASS_BY_REF, UNNECESSARY_WRAPS, UPPER_CASE_ACRONYMS, WRONG_SELF_CONVENTION, BOX_COLLECTION, REDUNDANT_ALLOCATION, RC_BUFFER, VEC_BOX, OPTION_OPTION, LINKEDLIST, RC_MUTEX.
140140
///
141141
/// Suppress lints whenever the suggested change would cause breakage for other crates.
142142
(avoid_breaking_exported_api: bool = true),

tests/ui/box_vec.rs renamed to tests/ui/box_collection.rs

+8
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
unused
77
)]
88

9+
use std::collections::HashMap;
10+
911
macro_rules! boxit {
1012
($init:expr, $x:ty) => {
1113
let _: Box<$x> = Box::new($init);
@@ -15,20 +17,26 @@ macro_rules! boxit {
1517
fn test_macro() {
1618
boxit!(Vec::new(), Vec<u8>);
1719
}
20+
1821
fn test(foo: Box<Vec<bool>>) {}
1922

2023
fn test2(foo: Box<dyn Fn(Vec<u32>)>) {
2124
// pass if #31 is fixed
2225
foo(vec![1, 2, 3])
2326
}
2427

28+
fn test3(foo: Box<String>) {}
29+
30+
fn test4(foo: Box<HashMap<String, String>>) {}
31+
2532
fn test_local_not_linted() {
2633
let _: Box<Vec<bool>>;
2734
}
2835

2936
// All of these test should be allowed because they are part of the
3037
// public api and `avoid_breaking_exported_api` is `false` by default.
3138
pub fn pub_test(foo: Box<Vec<bool>>) {}
39+
3240
pub fn pub_test_ret() -> Box<Vec<bool>> {
3341
Box::new(Vec::new())
3442
}

tests/ui/box_collection.stderr

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
error: you seem to be trying to use `Box<Vec<..>>`. Consider using just `Vec<..>`
2+
--> $DIR/box_collection.rs:21:14
3+
|
4+
LL | fn test(foo: Box<Vec<bool>>) {}
5+
| ^^^^^^^^^^^^^^
6+
|
7+
= note: `-D clippy::box-collection` implied by `-D warnings`
8+
= help: `Vec<..>` is already on the heap, `Box<Vec<..>>` makes an extra allocation
9+
10+
error: you seem to be trying to use `Box<String>`. Consider using just `String`
11+
--> $DIR/box_collection.rs:28:15
12+
|
13+
LL | fn test3(foo: Box<String>) {}
14+
| ^^^^^^^^^^^
15+
|
16+
= help: `String` is already on the heap, `Box<String>` makes an extra allocation
17+
18+
error: you seem to be trying to use `Box<HashMap<..>>`. Consider using just `HashMap<..>`
19+
--> $DIR/box_collection.rs:30:15
20+
|
21+
LL | fn test4(foo: Box<HashMap<String, String>>) {}
22+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
23+
|
24+
= help: `HashMap<..>` is already on the heap, `Box<HashMap<..>>` makes an extra allocation
25+
26+
error: aborting due to 3 previous errors
27+

tests/ui/box_vec.stderr

-11
This file was deleted.

0 commit comments

Comments
 (0)