Skip to content

Commit

Permalink
redundant_allocation: generic
Browse files Browse the repository at this point in the history
  • Loading branch information
lengyijun committed Jun 30, 2021
1 parent 140d9a5 commit b6aa612
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 71 deletions.
48 changes: 26 additions & 22 deletions clippy_lints/src/types/redundant_allocation.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::source::snippet_with_applicability;
use clippy_utils::source::{snippet, snippet_with_applicability};
use clippy_utils::{get_qpath_generic_tys, is_ty_param_diagnostic_item, is_ty_param_lang_item};
use rustc_errors::Applicability;
use rustc_hir::{self as hir, def_id::DefId, LangItem, QPath, TyKind};
Expand All @@ -21,21 +21,18 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_

if let Some(span) = utils::match_borrows_parameter(cx, qpath) {
let mut applicability = Applicability::MaybeIncorrect;
let generic_snippet = snippet_with_applicability(cx, span, "..", &mut applicability);
span_lint_and_then(
cx,
REDUNDANT_ALLOCATION,
hir_ty.span,
&format!("usage of `{}<&T>`", outer_sym),
&format!("usage of `{}<{}>`", outer_sym, generic_snippet),
|diag| {
diag.span_suggestion(
hir_ty.span,
"try",
format!("{}", snippet_with_applicability(cx, span, "..", &mut applicability)),
applicability,
);
diag.span_suggestion(hir_ty.span, "try", format!("{}", generic_snippet), applicability);
diag.note(&format!(
"`&T` is already a pointer, `{}<&T>` allocate a pointer on heap",
outer_sym,
"`{generic}` is already a pointer, `{outer}<{generic}>` allocates a pointer on the heap",
outer = outer_sym,
generic = generic_snippet
));
},
);
Expand All @@ -62,40 +59,47 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_
};
if inner_sym == outer_sym {
let mut applicability = Applicability::MaybeIncorrect;
let generic_snippet = snippet_with_applicability(cx, inner_span, "..", &mut applicability);
span_lint_and_then(
cx,
REDUNDANT_ALLOCATION,
hir_ty.span,
&format!("usage of `{}<{}<T>>`", outer_sym, inner_sym),
&format!("usage of `{}<{}<{}>>`", outer_sym, inner_sym, generic_snippet),
|diag| {
diag.span_suggestion(
hir_ty.span,
"try",
format!(
"{}<{}>",
outer_sym,
snippet_with_applicability(cx, inner_span, "..", &mut applicability)
),
format!("{}<{}>", outer_sym, generic_snippet),
applicability,
);
diag.note(&format!(
"`{}<T>` is already on the heap, `{}<{}<T>>` makes an extra allocation",
inner_sym, outer_sym, inner_sym,
"`{inner}<{generic}>` is already on the heap, `{outer}<{inner}<{generic}>>` makes an extra allocation",
outer = outer_sym,
inner = inner_sym,
generic = generic_snippet
));
},
);
} else {
let generic_snippet = snippet(cx, inner_span, "..");
span_lint_and_then(
cx,
REDUNDANT_ALLOCATION,
hir_ty.span,
&format!("usage of `{}<{}<T>>`", outer_sym, inner_sym),
&format!("usage of `{}<{}<{}>>`", outer_sym, inner_sym, generic_snippet),
|diag| {
diag.note(&format!(
"`{}<T>` is already on the heap, `{}<{}<T>>` makes an extra allocation",
inner_sym, outer_sym, inner_sym,
"`{inner}<{generic}>` is already on the heap, `{outer}<{inner}<{generic}>>` makes an extra allocation",
outer = outer_sym,
inner = inner_sym,
generic = generic_snippet
));
diag.help(&format!(
"consider using just `{outer}<{generic}>` or `{inner}<{generic}>`",
outer = outer_sym,
inner = inner_sym,
generic = generic_snippet
));
diag.help(&format!("consider using just `{}<T>` or `{}<T>`", outer_sym, inner_sym,));
},
);
}
Expand Down
60 changes: 30 additions & 30 deletions tests/ui/redundant_allocation.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ LL | pub fn box_test7<T>(foo: Box<Arc<T>>) {}
= note: `Arc<T>` is already on the heap, `Box<Arc<T>>` makes an extra allocation
= help: consider using just `Box<T>` or `Arc<T>`

error: usage of `Box<Rc<T>>`
error: usage of `Box<Rc<SubT<usize>>>`
--> $DIR/redundant_allocation.rs:29:27
|
LL | pub fn box_test8() -> Box<Rc<SubT<usize>>> {
| ^^^^^^^^^^^^^^^^^^^^
|
= note: `Rc<T>` is already on the heap, `Box<Rc<T>>` makes an extra allocation
= help: consider using just `Box<T>` or `Rc<T>`
= note: `Rc<SubT<usize>>` is already on the heap, `Box<Rc<SubT<usize>>>` makes an extra allocation
= help: consider using just `Box<SubT<usize>>` or `Rc<SubT<usize>>`

error: usage of `Box<Arc<T>>`
--> $DIR/redundant_allocation.rs:33:30
Expand All @@ -35,41 +35,41 @@ LL | pub fn box_test9<T>(foo: Box<Arc<T>>) -> Box<Arc<SubT<T>>> {
= note: `Arc<T>` is already on the heap, `Box<Arc<T>>` makes an extra allocation
= help: consider using just `Box<T>` or `Arc<T>`

error: usage of `Box<Arc<T>>`
error: usage of `Box<Arc<SubT<T>>>`
--> $DIR/redundant_allocation.rs:33:46
|
LL | pub fn box_test9<T>(foo: Box<Arc<T>>) -> Box<Arc<SubT<T>>> {
| ^^^^^^^^^^^^^^^^^
|
= note: `Arc<T>` is already on the heap, `Box<Arc<T>>` makes an extra allocation
= help: consider using just `Box<T>` or `Arc<T>`
= note: `Arc<SubT<T>>` is already on the heap, `Box<Arc<SubT<T>>>` makes an extra allocation
= help: consider using just `Box<SubT<T>>` or `Arc<SubT<T>>`

error: usage of `Rc<Box<T>>`
error: usage of `Rc<Box<bool>>`
--> $DIR/redundant_allocation.rs:46:24
|
LL | pub fn rc_test5(a: Rc<Box<bool>>) {}
| ^^^^^^^^^^^^^
|
= note: `Box<T>` is already on the heap, `Rc<Box<T>>` makes an extra allocation
= help: consider using just `Rc<T>` or `Box<T>`
= note: `Box<bool>` is already on the heap, `Rc<Box<bool>>` makes an extra allocation
= help: consider using just `Rc<bool>` or `Box<bool>`

error: usage of `Rc<Arc<T>>`
error: usage of `Rc<Arc<bool>>`
--> $DIR/redundant_allocation.rs:48:24
|
LL | pub fn rc_test7(a: Rc<Arc<bool>>) {}
| ^^^^^^^^^^^^^
|
= note: `Arc<T>` is already on the heap, `Rc<Arc<T>>` makes an extra allocation
= help: consider using just `Rc<T>` or `Arc<T>`
= note: `Arc<bool>` is already on the heap, `Rc<Arc<bool>>` makes an extra allocation
= help: consider using just `Rc<bool>` or `Arc<bool>`

error: usage of `Rc<Box<T>>`
error: usage of `Rc<Box<SubT<usize>>>`
--> $DIR/redundant_allocation.rs:50:26
|
LL | pub fn rc_test8() -> Rc<Box<SubT<usize>>> {
| ^^^^^^^^^^^^^^^^^^^^
|
= note: `Box<T>` is already on the heap, `Rc<Box<T>>` makes an extra allocation
= help: consider using just `Rc<T>` or `Box<T>`
= note: `Box<SubT<usize>>` is already on the heap, `Rc<Box<SubT<usize>>>` makes an extra allocation
= help: consider using just `Rc<SubT<usize>>` or `Box<SubT<usize>>`

error: usage of `Rc<Arc<T>>`
--> $DIR/redundant_allocation.rs:54:29
Expand All @@ -80,41 +80,41 @@ LL | pub fn rc_test9<T>(foo: Rc<Arc<T>>) -> Rc<Arc<SubT<T>>> {
= note: `Arc<T>` is already on the heap, `Rc<Arc<T>>` makes an extra allocation
= help: consider using just `Rc<T>` or `Arc<T>`

error: usage of `Rc<Arc<T>>`
error: usage of `Rc<Arc<SubT<T>>>`
--> $DIR/redundant_allocation.rs:54:44
|
LL | pub fn rc_test9<T>(foo: Rc<Arc<T>>) -> Rc<Arc<SubT<T>>> {
| ^^^^^^^^^^^^^^^^
|
= note: `Arc<T>` is already on the heap, `Rc<Arc<T>>` makes an extra allocation
= help: consider using just `Rc<T>` or `Arc<T>`
= note: `Arc<SubT<T>>` is already on the heap, `Rc<Arc<SubT<T>>>` makes an extra allocation
= help: consider using just `Rc<SubT<T>>` or `Arc<SubT<T>>`

error: usage of `Arc<Box<T>>`
error: usage of `Arc<Box<bool>>`
--> $DIR/redundant_allocation.rs:67:25
|
LL | pub fn arc_test5(a: Arc<Box<bool>>) {}
| ^^^^^^^^^^^^^^
|
= note: `Box<T>` is already on the heap, `Arc<Box<T>>` makes an extra allocation
= help: consider using just `Arc<T>` or `Box<T>`
= note: `Box<bool>` is already on the heap, `Arc<Box<bool>>` makes an extra allocation
= help: consider using just `Arc<bool>` or `Box<bool>`

error: usage of `Arc<Rc<T>>`
error: usage of `Arc<Rc<bool>>`
--> $DIR/redundant_allocation.rs:69:25
|
LL | pub fn arc_test6(a: Arc<Rc<bool>>) {}
| ^^^^^^^^^^^^^
|
= note: `Rc<T>` is already on the heap, `Arc<Rc<T>>` makes an extra allocation
= help: consider using just `Arc<T>` or `Rc<T>`
= note: `Rc<bool>` is already on the heap, `Arc<Rc<bool>>` makes an extra allocation
= help: consider using just `Arc<bool>` or `Rc<bool>`

error: usage of `Arc<Box<T>>`
error: usage of `Arc<Box<SubT<usize>>>`
--> $DIR/redundant_allocation.rs:71:27
|
LL | pub fn arc_test8() -> Arc<Box<SubT<usize>>> {
| ^^^^^^^^^^^^^^^^^^^^^
|
= note: `Box<T>` is already on the heap, `Arc<Box<T>>` makes an extra allocation
= help: consider using just `Arc<T>` or `Box<T>`
= note: `Box<SubT<usize>>` is already on the heap, `Arc<Box<SubT<usize>>>` makes an extra allocation
= help: consider using just `Arc<SubT<usize>>` or `Box<SubT<usize>>`

error: usage of `Arc<Rc<T>>`
--> $DIR/redundant_allocation.rs:75:30
Expand All @@ -125,14 +125,14 @@ LL | pub fn arc_test9<T>(foo: Arc<Rc<T>>) -> Arc<Rc<SubT<T>>> {
= note: `Rc<T>` is already on the heap, `Arc<Rc<T>>` makes an extra allocation
= help: consider using just `Arc<T>` or `Rc<T>`

error: usage of `Arc<Rc<T>>`
error: usage of `Arc<Rc<SubT<T>>>`
--> $DIR/redundant_allocation.rs:75:45
|
LL | pub fn arc_test9<T>(foo: Arc<Rc<T>>) -> Arc<Rc<SubT<T>>> {
| ^^^^^^^^^^^^^^^^
|
= note: `Rc<T>` is already on the heap, `Arc<Rc<T>>` makes an extra allocation
= help: consider using just `Arc<T>` or `Rc<T>`
= note: `Rc<SubT<T>>` is already on the heap, `Arc<Rc<SubT<T>>>` makes an extra allocation
= help: consider using just `Arc<SubT<T>>` or `Rc<SubT<T>>`

error: aborting due to 15 previous errors

38 changes: 19 additions & 19 deletions tests/ui/redundant_allocation_fixable.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,23 @@ LL | pub fn box_test1<T>(foo: Box<&T>) {}
| ^^^^^^^ help: try: `&T`
|
= note: `-D clippy::redundant-allocation` implied by `-D warnings`
= note: `&T` is already a pointer, `Box<&T>` allocate a pointer on heap
= note: `&T` is already a pointer, `Box<&T>` allocates a pointer on the heap

error: usage of `Box<&T>`
error: usage of `Box<&MyStruct>`
--> $DIR/redundant_allocation_fixable.rs:28:27
|
LL | pub fn box_test2(foo: Box<&MyStruct>) {}
| ^^^^^^^^^^^^^^ help: try: `&MyStruct`
|
= note: `&T` is already a pointer, `Box<&T>` allocate a pointer on heap
= note: `&MyStruct` is already a pointer, `Box<&MyStruct>` allocates a pointer on the heap

error: usage of `Box<&T>`
error: usage of `Box<&MyEnum>`
--> $DIR/redundant_allocation_fixable.rs:30:27
|
LL | pub fn box_test3(foo: Box<&MyEnum>) {}
| ^^^^^^^^^^^^ help: try: `&MyEnum`
|
= note: `&T` is already a pointer, `Box<&T>` allocate a pointer on heap
= note: `&MyEnum` is already a pointer, `Box<&MyEnum>` allocates a pointer on the heap

error: usage of `Box<Box<T>>`
--> $DIR/redundant_allocation_fixable.rs:34:30
Expand All @@ -37,63 +37,63 @@ error: usage of `Rc<&T>`
LL | pub fn rc_test1<T>(foo: Rc<&T>) {}
| ^^^^^^ help: try: `&T`
|
= note: `&T` is already a pointer, `Rc<&T>` allocate a pointer on heap
= note: `&T` is already a pointer, `Rc<&T>` allocates a pointer on the heap

error: usage of `Rc<&T>`
error: usage of `Rc<&MyStruct>`
--> $DIR/redundant_allocation_fixable.rs:47:26
|
LL | pub fn rc_test2(foo: Rc<&MyStruct>) {}
| ^^^^^^^^^^^^^ help: try: `&MyStruct`
|
= note: `&T` is already a pointer, `Rc<&T>` allocate a pointer on heap
= note: `&MyStruct` is already a pointer, `Rc<&MyStruct>` allocates a pointer on the heap

error: usage of `Rc<&T>`
error: usage of `Rc<&MyEnum>`
--> $DIR/redundant_allocation_fixable.rs:49:26
|
LL | pub fn rc_test3(foo: Rc<&MyEnum>) {}
| ^^^^^^^^^^^ help: try: `&MyEnum`
|
= note: `&T` is already a pointer, `Rc<&T>` allocate a pointer on heap
= note: `&MyEnum` is already a pointer, `Rc<&MyEnum>` allocates a pointer on the heap

error: usage of `Rc<Rc<T>>`
error: usage of `Rc<Rc<bool>>`
--> $DIR/redundant_allocation_fixable.rs:53:24
|
LL | pub fn rc_test6(a: Rc<Rc<bool>>) {}
| ^^^^^^^^^^^^ help: try: `Rc<bool>`
|
= note: `Rc<T>` is already on the heap, `Rc<Rc<T>>` makes an extra allocation
= note: `Rc<bool>` is already on the heap, `Rc<Rc<bool>>` makes an extra allocation

error: usage of `Arc<&T>`
--> $DIR/redundant_allocation_fixable.rs:64:30
|
LL | pub fn arc_test1<T>(foo: Arc<&T>) {}
| ^^^^^^^ help: try: `&T`
|
= note: `&T` is already a pointer, `Arc<&T>` allocate a pointer on heap
= note: `&T` is already a pointer, `Arc<&T>` allocates a pointer on the heap

error: usage of `Arc<&T>`
error: usage of `Arc<&MyStruct>`
--> $DIR/redundant_allocation_fixable.rs:66:27
|
LL | pub fn arc_test2(foo: Arc<&MyStruct>) {}
| ^^^^^^^^^^^^^^ help: try: `&MyStruct`
|
= note: `&T` is already a pointer, `Arc<&T>` allocate a pointer on heap
= note: `&MyStruct` is already a pointer, `Arc<&MyStruct>` allocates a pointer on the heap

error: usage of `Arc<&T>`
error: usage of `Arc<&MyEnum>`
--> $DIR/redundant_allocation_fixable.rs:68:27
|
LL | pub fn arc_test3(foo: Arc<&MyEnum>) {}
| ^^^^^^^^^^^^ help: try: `&MyEnum`
|
= note: `&T` is already a pointer, `Arc<&T>` allocate a pointer on heap
= note: `&MyEnum` is already a pointer, `Arc<&MyEnum>` allocates a pointer on the heap

error: usage of `Arc<Arc<T>>`
error: usage of `Arc<Arc<bool>>`
--> $DIR/redundant_allocation_fixable.rs:72:25
|
LL | pub fn arc_test7(a: Arc<Arc<bool>>) {}
| ^^^^^^^^^^^^^^ help: try: `Arc<bool>`
|
= note: `Arc<T>` is already on the heap, `Arc<Arc<T>>` makes an extra allocation
= note: `Arc<bool>` is already on the heap, `Arc<Arc<bool>>` makes an extra allocation

error: aborting due to 12 previous errors

0 comments on commit b6aa612

Please sign in to comment.