Skip to content

Commit 5e10fdd

Browse files
committed
redundant_allocation: only fix Box/Rc/Arc<&T>, Box<Box<T>>, Rc<Rc<T>>,
Arc<Arc<T>>. Others like Rc<Box<T>> only give suggestion.
1 parent 74d4fe8 commit 5e10fdd

6 files changed

+253
-195
lines changed

clippy_lints/src/types/redundant_allocation.rs

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use clippy_utils::diagnostics::span_lint_and_sugg;
1+
use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg};
22
use clippy_utils::source::snippet_with_applicability;
33
use clippy_utils::{get_qpath_generic_tys, is_ty_param_diagnostic_item, is_ty_param_lang_item};
44
use rustc_errors::Applicability;
@@ -51,19 +51,36 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_
5151
Some(ty) => ty.span,
5252
None => return false,
5353
};
54-
let mut applicability = Applicability::MaybeIncorrect;
55-
span_lint_and_sugg(
56-
cx,
57-
REDUNDANT_ALLOCATION,
58-
hir_ty.span,
59-
&format!("usage of `{}<{}<T>>`", outer_sym, inner_sym),
60-
"try",
61-
format!(
62-
"{}<{}>",
63-
outer_sym,
64-
snippet_with_applicability(cx, inner_span, "..", &mut applicability)
65-
),
66-
applicability,
67-
);
54+
if inner_sym == outer_sym {
55+
let mut applicability = Applicability::MaybeIncorrect;
56+
span_lint_and_sugg(
57+
cx,
58+
REDUNDANT_ALLOCATION,
59+
hir_ty.span,
60+
&format!("usage of `{}<{}<T>>`", outer_sym, inner_sym),
61+
"try",
62+
format!(
63+
"{}<{}>",
64+
outer_sym,
65+
snippet_with_applicability(cx, inner_span, "..", &mut applicability)
66+
),
67+
applicability,
68+
);
69+
} else {
70+
span_lint_and_help(
71+
cx,
72+
REDUNDANT_ALLOCATION,
73+
hir_ty.span,
74+
&format!(
75+
"you seem to be trying to use `{}<{}<T>>`. Consider using just `{}<T>` or `{}<T>`",
76+
outer_sym, inner_sym, outer_sym, inner_sym,
77+
),
78+
None,
79+
&format!(
80+
"`{}<T>` is already on the heap, `{}<{}<T>>` makes an extra allocation",
81+
inner_sym, outer_sym, inner_sym,
82+
),
83+
);
84+
}
6885
true
6986
}

tests/ui/redundant_allocation.rs

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
// run-rustfix
21
#![warn(clippy::all)]
32
#![allow(clippy::boxed_local, clippy::needless_pass_by_value)]
43
#![allow(clippy::blacklisted_name, unused_variables, dead_code)]
@@ -23,16 +22,6 @@ mod outer_box {
2322
use std::rc::Rc;
2423
use std::sync::Arc;
2524

26-
pub fn box_test1<T>(foo: Box<&T>) {}
27-
28-
pub fn box_test2(foo: Box<&MyStruct>) {}
29-
30-
pub fn box_test3(foo: Box<&MyEnum>) {}
31-
32-
pub fn box_test4_neg(foo: Box<SubT<&usize>>) {}
33-
34-
pub fn box_test5<T>(foo: Box<Box<T>>) {}
35-
3625
pub fn box_test6<T>(foo: Box<Rc<T>>) {}
3726

3827
pub fn box_test7<T>(foo: Box<Arc<T>>) {}
@@ -54,18 +43,8 @@ mod outer_rc {
5443
use std::rc::Rc;
5544
use std::sync::Arc;
5645

57-
pub fn rc_test1<T>(foo: Rc<&T>) {}
58-
59-
pub fn rc_test2(foo: Rc<&MyStruct>) {}
60-
61-
pub fn rc_test3(foo: Rc<&MyEnum>) {}
62-
63-
pub fn rc_test4_neg(foo: Rc<SubT<&usize>>) {}
64-
6546
pub fn rc_test5(a: Rc<Box<bool>>) {}
6647

67-
pub fn rc_test6(a: Rc<Rc<bool>>) {}
68-
6948
pub fn rc_test7(a: Rc<Arc<bool>>) {}
7049

7150
pub fn rc_test8() -> Rc<Box<SubT<usize>>> {
@@ -85,20 +64,10 @@ mod outer_arc {
8564
use std::rc::Rc;
8665
use std::sync::Arc;
8766

88-
pub fn arc_test1<T>(foo: Arc<&T>) {}
89-
90-
pub fn arc_test2(foo: Arc<&MyStruct>) {}
91-
92-
pub fn arc_test3(foo: Arc<&MyEnum>) {}
93-
94-
pub fn arc_test4_neg(foo: Arc<SubT<&usize>>) {}
95-
9667
pub fn arc_test5(a: Arc<Box<bool>>) {}
9768

9869
pub fn arc_test6(a: Arc<Rc<bool>>) {}
9970

100-
pub fn arc_test7(a: Arc<Arc<bool>>) {}
101-
10271
pub fn arc_test8() -> Arc<Box<SubT<usize>>> {
10372
unimplemented!();
10473
}

tests/ui/redundant_allocation.stderr

Lines changed: 70 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -1,166 +1,123 @@
1-
error: usage of `Box<&T>`
2-
--> $DIR/redundant_allocation.rs:26:30
1+
error: you seem to be trying to use `Box<Rc<T>>`. Consider using just `Box<T>` of `Rc<T>`
2+
--> $DIR/redundant_allocation.rs:25:30
33
|
4-
LL | pub fn box_test1<T>(foo: Box<&T>) {}
5-
| ^^^^^^^ help: try: `&T`
4+
LL | pub fn box_test6<T>(foo: Box<Rc<T>>) {}
5+
| ^^^^^^^^^^
66
|
77
= note: `-D clippy::redundant-allocation` implied by `-D warnings`
8+
= help: `Rc<T>` is already on the heap, `Box<Rc<T>>` makes an extra allocation
89

9-
error: usage of `Box<&T>`
10-
--> $DIR/redundant_allocation.rs:28:27
11-
|
12-
LL | pub fn box_test2(foo: Box<&MyStruct>) {}
13-
| ^^^^^^^^^^^^^^ help: try: `&MyStruct`
14-
15-
error: usage of `Box<&T>`
16-
--> $DIR/redundant_allocation.rs:30:27
17-
|
18-
LL | pub fn box_test3(foo: Box<&MyEnum>) {}
19-
| ^^^^^^^^^^^^ help: try: `&MyEnum`
20-
21-
error: usage of `Box<Box<T>>`
22-
--> $DIR/redundant_allocation.rs:34:30
23-
|
24-
LL | pub fn box_test5<T>(foo: Box<Box<T>>) {}
25-
| ^^^^^^^^^^^ help: try: `Box<T>`
26-
27-
error: usage of `Box<Rc<T>>`
28-
--> $DIR/redundant_allocation.rs:36:30
29-
|
30-
LL | pub fn box_test6<T>(foo: Box<Rc<T>>) {}
31-
| ^^^^^^^^^^ help: try: `Box<T>`
32-
33-
error: usage of `Box<Arc<T>>`
34-
--> $DIR/redundant_allocation.rs:38:30
10+
error: you seem to be trying to use `Box<Arc<T>>`. Consider using just `Box<T>` of `Arc<T>`
11+
--> $DIR/redundant_allocation.rs:27:30
3512
|
3613
LL | pub fn box_test7<T>(foo: Box<Arc<T>>) {}
37-
| ^^^^^^^^^^^ help: try: `Box<T>`
14+
| ^^^^^^^^^^^
15+
|
16+
= help: `Arc<T>` is already on the heap, `Box<Arc<T>>` makes an extra allocation
3817

39-
error: usage of `Box<Rc<T>>`
40-
--> $DIR/redundant_allocation.rs:40:27
18+
error: you seem to be trying to use `Box<Rc<T>>`. Consider using just `Box<T>` of `Rc<T>`
19+
--> $DIR/redundant_allocation.rs:29:27
4120
|
4221
LL | pub fn box_test8() -> Box<Rc<SubT<usize>>> {
43-
| ^^^^^^^^^^^^^^^^^^^^ help: try: `Box<SubT<usize>>`
44-
45-
error: usage of `Box<Arc<T>>`
46-
--> $DIR/redundant_allocation.rs:44:30
22+
| ^^^^^^^^^^^^^^^^^^^^
4723
|
48-
LL | pub fn box_test9<T>(foo: Box<Arc<T>>) -> Box<Arc<SubT<T>>> {
49-
| ^^^^^^^^^^^ help: try: `Box<T>`
24+
= help: `Rc<T>` is already on the heap, `Box<Rc<T>>` makes an extra allocation
5025

51-
error: usage of `Box<Arc<T>>`
52-
--> $DIR/redundant_allocation.rs:44:46
26+
error: you seem to be trying to use `Box<Arc<T>>`. Consider using just `Box<T>` of `Arc<T>`
27+
--> $DIR/redundant_allocation.rs:33:30
5328
|
5429
LL | pub fn box_test9<T>(foo: Box<Arc<T>>) -> Box<Arc<SubT<T>>> {
55-
| ^^^^^^^^^^^^^^^^^ help: try: `Box<SubT<T>>`
56-
57-
error: usage of `Rc<&T>`
58-
--> $DIR/redundant_allocation.rs:57:29
30+
| ^^^^^^^^^^^
5931
|
60-
LL | pub fn rc_test1<T>(foo: Rc<&T>) {}
61-
| ^^^^^^ help: try: `&T`
32+
= help: `Arc<T>` is already on the heap, `Box<Arc<T>>` makes an extra allocation
6233

63-
error: usage of `Rc<&T>`
64-
--> $DIR/redundant_allocation.rs:59:26
34+
error: you seem to be trying to use `Box<Arc<T>>`. Consider using just `Box<T>` of `Arc<T>`
35+
--> $DIR/redundant_allocation.rs:33:46
6536
|
66-
LL | pub fn rc_test2(foo: Rc<&MyStruct>) {}
67-
| ^^^^^^^^^^^^^ help: try: `&MyStruct`
68-
69-
error: usage of `Rc<&T>`
70-
--> $DIR/redundant_allocation.rs:61:26
37+
LL | pub fn box_test9<T>(foo: Box<Arc<T>>) -> Box<Arc<SubT<T>>> {
38+
| ^^^^^^^^^^^^^^^^^
7139
|
72-
LL | pub fn rc_test3(foo: Rc<&MyEnum>) {}
73-
| ^^^^^^^^^^^ help: try: `&MyEnum`
40+
= help: `Arc<T>` is already on the heap, `Box<Arc<T>>` makes an extra allocation
7441

75-
error: usage of `Rc<Box<T>>`
76-
--> $DIR/redundant_allocation.rs:65:24
42+
error: you seem to be trying to use `Rc<Box<T>>`. Consider using just `Rc<T>` of `Box<T>`
43+
--> $DIR/redundant_allocation.rs:46:24
7744
|
7845
LL | pub fn rc_test5(a: Rc<Box<bool>>) {}
79-
| ^^^^^^^^^^^^^ help: try: `Rc<bool>`
80-
81-
error: usage of `Rc<Rc<T>>`
82-
--> $DIR/redundant_allocation.rs:67:24
46+
| ^^^^^^^^^^^^^
8347
|
84-
LL | pub fn rc_test6(a: Rc<Rc<bool>>) {}
85-
| ^^^^^^^^^^^^ help: try: `Rc<bool>`
48+
= help: `Box<T>` is already on the heap, `Rc<Box<T>>` makes an extra allocation
8649

87-
error: usage of `Rc<Arc<T>>`
88-
--> $DIR/redundant_allocation.rs:69:24
50+
error: you seem to be trying to use `Rc<Arc<T>>`. Consider using just `Rc<T>` of `Arc<T>`
51+
--> $DIR/redundant_allocation.rs:48:24
8952
|
9053
LL | pub fn rc_test7(a: Rc<Arc<bool>>) {}
91-
| ^^^^^^^^^^^^^ help: try: `Rc<bool>`
54+
| ^^^^^^^^^^^^^
55+
|
56+
= help: `Arc<T>` is already on the heap, `Rc<Arc<T>>` makes an extra allocation
9257

93-
error: usage of `Rc<Box<T>>`
94-
--> $DIR/redundant_allocation.rs:71:26
58+
error: you seem to be trying to use `Rc<Box<T>>`. Consider using just `Rc<T>` of `Box<T>`
59+
--> $DIR/redundant_allocation.rs:50:26
9560
|
9661
LL | pub fn rc_test8() -> Rc<Box<SubT<usize>>> {
97-
| ^^^^^^^^^^^^^^^^^^^^ help: try: `Rc<SubT<usize>>`
98-
99-
error: usage of `Rc<Arc<T>>`
100-
--> $DIR/redundant_allocation.rs:75:29
62+
| ^^^^^^^^^^^^^^^^^^^^
10163
|
102-
LL | pub fn rc_test9<T>(foo: Rc<Arc<T>>) -> Rc<Arc<SubT<T>>> {
103-
| ^^^^^^^^^^ help: try: `Rc<T>`
64+
= help: `Box<T>` is already on the heap, `Rc<Box<T>>` makes an extra allocation
10465

105-
error: usage of `Rc<Arc<T>>`
106-
--> $DIR/redundant_allocation.rs:75:44
66+
error: you seem to be trying to use `Rc<Arc<T>>`. Consider using just `Rc<T>` of `Arc<T>`
67+
--> $DIR/redundant_allocation.rs:54:29
10768
|
10869
LL | pub fn rc_test9<T>(foo: Rc<Arc<T>>) -> Rc<Arc<SubT<T>>> {
109-
| ^^^^^^^^^^^^^^^^ help: try: `Rc<SubT<T>>`
110-
111-
error: usage of `Arc<&T>`
112-
--> $DIR/redundant_allocation.rs:88:30
70+
| ^^^^^^^^^^
11371
|
114-
LL | pub fn arc_test1<T>(foo: Arc<&T>) {}
115-
| ^^^^^^^ help: try: `&T`
72+
= help: `Arc<T>` is already on the heap, `Rc<Arc<T>>` makes an extra allocation
11673

117-
error: usage of `Arc<&T>`
118-
--> $DIR/redundant_allocation.rs:90:27
74+
error: you seem to be trying to use `Rc<Arc<T>>`. Consider using just `Rc<T>` of `Arc<T>`
75+
--> $DIR/redundant_allocation.rs:54:44
11976
|
120-
LL | pub fn arc_test2(foo: Arc<&MyStruct>) {}
121-
| ^^^^^^^^^^^^^^ help: try: `&MyStruct`
122-
123-
error: usage of `Arc<&T>`
124-
--> $DIR/redundant_allocation.rs:92:27
77+
LL | pub fn rc_test9<T>(foo: Rc<Arc<T>>) -> Rc<Arc<SubT<T>>> {
78+
| ^^^^^^^^^^^^^^^^
12579
|
126-
LL | pub fn arc_test3(foo: Arc<&MyEnum>) {}
127-
| ^^^^^^^^^^^^ help: try: `&MyEnum`
80+
= help: `Arc<T>` is already on the heap, `Rc<Arc<T>>` makes an extra allocation
12881

129-
error: usage of `Arc<Box<T>>`
130-
--> $DIR/redundant_allocation.rs:96:25
82+
error: you seem to be trying to use `Arc<Box<T>>`. Consider using just `Arc<T>` of `Box<T>`
83+
--> $DIR/redundant_allocation.rs:67:25
13184
|
13285
LL | pub fn arc_test5(a: Arc<Box<bool>>) {}
133-
| ^^^^^^^^^^^^^^ help: try: `Arc<bool>`
86+
| ^^^^^^^^^^^^^^
87+
|
88+
= help: `Box<T>` is already on the heap, `Arc<Box<T>>` makes an extra allocation
13489

135-
error: usage of `Arc<Rc<T>>`
136-
--> $DIR/redundant_allocation.rs:98:25
90+
error: you seem to be trying to use `Arc<Rc<T>>`. Consider using just `Arc<T>` of `Rc<T>`
91+
--> $DIR/redundant_allocation.rs:69:25
13792
|
13893
LL | pub fn arc_test6(a: Arc<Rc<bool>>) {}
139-
| ^^^^^^^^^^^^^ help: try: `Arc<bool>`
140-
141-
error: usage of `Arc<Arc<T>>`
142-
--> $DIR/redundant_allocation.rs:100:25
94+
| ^^^^^^^^^^^^^
14395
|
144-
LL | pub fn arc_test7(a: Arc<Arc<bool>>) {}
145-
| ^^^^^^^^^^^^^^ help: try: `Arc<bool>`
96+
= help: `Rc<T>` is already on the heap, `Arc<Rc<T>>` makes an extra allocation
14697

147-
error: usage of `Arc<Box<T>>`
148-
--> $DIR/redundant_allocation.rs:102:27
98+
error: you seem to be trying to use `Arc<Box<T>>`. Consider using just `Arc<T>` of `Box<T>`
99+
--> $DIR/redundant_allocation.rs:71:27
149100
|
150101
LL | pub fn arc_test8() -> Arc<Box<SubT<usize>>> {
151-
| ^^^^^^^^^^^^^^^^^^^^^ help: try: `Arc<SubT<usize>>`
102+
| ^^^^^^^^^^^^^^^^^^^^^
103+
|
104+
= help: `Box<T>` is already on the heap, `Arc<Box<T>>` makes an extra allocation
152105

153-
error: usage of `Arc<Rc<T>>`
154-
--> $DIR/redundant_allocation.rs:106:30
106+
error: you seem to be trying to use `Arc<Rc<T>>`. Consider using just `Arc<T>` of `Rc<T>`
107+
--> $DIR/redundant_allocation.rs:75:30
155108
|
156109
LL | pub fn arc_test9<T>(foo: Arc<Rc<T>>) -> Arc<Rc<SubT<T>>> {
157-
| ^^^^^^^^^^ help: try: `Arc<T>`
110+
| ^^^^^^^^^^
111+
|
112+
= help: `Rc<T>` is already on the heap, `Arc<Rc<T>>` makes an extra allocation
158113

159-
error: usage of `Arc<Rc<T>>`
160-
--> $DIR/redundant_allocation.rs:106:45
114+
error: you seem to be trying to use `Arc<Rc<T>>`. Consider using just `Arc<T>` of `Rc<T>`
115+
--> $DIR/redundant_allocation.rs:75:45
161116
|
162117
LL | pub fn arc_test9<T>(foo: Arc<Rc<T>>) -> Arc<Rc<SubT<T>>> {
163-
| ^^^^^^^^^^^^^^^^ help: try: `Arc<SubT<T>>`
118+
| ^^^^^^^^^^^^^^^^
119+
|
120+
= help: `Rc<T>` is already on the heap, `Arc<Rc<T>>` makes an extra allocation
164121

165-
error: aborting due to 27 previous errors
122+
error: aborting due to 15 previous errors
166123

0 commit comments

Comments
 (0)