From e575610fb32c50236d56d7001f13d1143205ae5a Mon Sep 17 00:00:00 2001 From: lyj Date: Wed, 2 Jun 2021 13:41:52 +0800 Subject: [PATCH] redundant_allocation: add Arc; some refractoring. --- clippy_lints/src/types/mod.rs | 4 +- .../src/types/redundant_allocation.rs | 153 ++++++++++------- tests/ui/redundant_allocation.fixed | 48 ------ tests/ui/redundant_allocation.rs | 68 ++++++-- tests/ui/redundant_allocation.stderr | 158 ++++++++++++++---- tests/ui/redundant_allocation_fixable.fixed | 75 +++++++++ tests/ui/redundant_allocation_fixable.rs | 75 +++++++++ tests/ui/redundant_allocation_fixable.stderr | 99 +++++++++++ 8 files changed, 512 insertions(+), 168 deletions(-) delete mode 100644 tests/ui/redundant_allocation.fixed create mode 100644 tests/ui/redundant_allocation_fixable.fixed create mode 100644 tests/ui/redundant_allocation_fixable.rs create mode 100644 tests/ui/redundant_allocation_fixable.stderr diff --git a/clippy_lints/src/types/mod.rs b/clippy_lints/src/types/mod.rs index c26268a875c..7d629b5455b 100644 --- a/clippy_lints/src/types/mod.rs +++ b/clippy_lints/src/types/mod.rs @@ -178,8 +178,8 @@ declare_clippy_lint! { /// **What it does:** Checks for use of redundant allocations anywhere in the code. /// - /// **Why is this bad?** Expressions such as `Rc<&T>`, `Rc>`, `Rc>`, `Box<&T>` - /// add an unnecessary level of indirection. + /// **Why is this bad?** Expressions such as `Rc<&T>`, `Rc>`, `Rc>`, `Rc>`, Arc<&T>`, `Arc>`, + /// `Arc>`, `Arc>`, `Box<&T>`, `Box>`, `Box>`, `Box>`, add an unnecessary level of indirection. /// /// **Known problems:** None. /// diff --git a/clippy_lints/src/types/redundant_allocation.rs b/clippy_lints/src/types/redundant_allocation.rs index c0c1f340583..8e83dcbf704 100644 --- a/clippy_lints/src/types/redundant_allocation.rs +++ b/clippy_lints/src/types/redundant_allocation.rs @@ -1,5 +1,5 @@ -use clippy_utils::diagnostics::span_lint_and_sugg; -use clippy_utils::source::snippet_with_applicability; +use clippy_utils::diagnostics::span_lint_and_then; +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}; @@ -9,74 +9,99 @@ use super::{utils, REDUNDANT_ALLOCATION}; pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_>, def_id: DefId) -> bool { - if Some(def_id) == cx.tcx.lang_items().owned_box() { - if let Some(span) = utils::match_borrows_parameter(cx, qpath) { - let mut applicability = Applicability::MachineApplicable; - span_lint_and_sugg( - cx, - REDUNDANT_ALLOCATION, - hir_ty.span, - "usage of `Box<&T>`", - "try", - snippet_with_applicability(cx, span, "..", &mut applicability).to_string(), - applicability, - ); - return true; - } + let outer_sym = if Some(def_id) == cx.tcx.lang_items().owned_box() { + "Box" + } else if cx.tcx.is_diagnostic_item(sym::Rc, def_id) { + "Rc" + } else if cx.tcx.is_diagnostic_item(sym::Arc, def_id) { + "Arc" + } else { + return false; + }; + + 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 `{}<{}>`", outer_sym, generic_snippet), + |diag| { + diag.span_suggestion(hir_ty.span, "try", format!("{}", generic_snippet), applicability); + diag.note(&format!( + "`{generic}` is already a pointer, `{outer}<{generic}>` allocates a pointer on the heap", + outer = outer_sym, + generic = generic_snippet + )); + }, + ); + return true; } - if cx.tcx.is_diagnostic_item(sym::Rc, def_id) { - if let Some(ty) = is_ty_param_diagnostic_item(cx, qpath, sym::Rc) { - let mut applicability = Applicability::MachineApplicable; - span_lint_and_sugg( - cx, - REDUNDANT_ALLOCATION, - hir_ty.span, - "usage of `Rc>`", - "try", - snippet_with_applicability(cx, ty.span, "..", &mut applicability).to_string(), - applicability, - ); - true - } else if let Some(ty) = is_ty_param_lang_item(cx, qpath, LangItem::OwnedBox) { - let qpath = match &ty.kind { - TyKind::Path(qpath) => qpath, - _ => return false, - }; - let inner_span = match get_qpath_generic_tys(qpath).next() { - Some(ty) => ty.span, - None => return false, - }; - let mut applicability = Applicability::MachineApplicable; - span_lint_and_sugg( - cx, - REDUNDANT_ALLOCATION, - hir_ty.span, - "usage of `Rc>`", - "try", - format!( - "Rc<{}>", - snippet_with_applicability(cx, inner_span, "..", &mut applicability) - ), - applicability, - ); - true - } else { - utils::match_borrows_parameter(cx, qpath).map_or(false, |span| { - let mut applicability = Applicability::MachineApplicable; - span_lint_and_sugg( - cx, - REDUNDANT_ALLOCATION, + let (inner_sym, ty) = if let Some(ty) = is_ty_param_lang_item(cx, qpath, LangItem::OwnedBox) { + ("Box", ty) + } else if let Some(ty) = is_ty_param_diagnostic_item(cx, qpath, sym::Rc) { + ("Rc", ty) + } else if let Some(ty) = is_ty_param_diagnostic_item(cx, qpath, sym::Arc) { + ("Arc", ty) + } else { + return false; + }; + + let inner_qpath = match &ty.kind { + TyKind::Path(inner_qpath) => inner_qpath, + _ => return false, + }; + let inner_span = match get_qpath_generic_tys(inner_qpath).next() { + Some(ty) => ty.span, + None => return false, + }; + 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 `{}<{}<{}>>`", outer_sym, inner_sym, generic_snippet), + |diag| { + diag.span_suggestion( hir_ty.span, - "usage of `Rc<&T>`", "try", - snippet_with_applicability(cx, span, "..", &mut applicability).to_string(), + format!("{}<{}>", outer_sym, generic_snippet), applicability, ); - true - }) - } + diag.note(&format!( + "`{inner}<{generic}>` is already on the heap, `{outer}<{inner}<{generic}>>` makes an extra allocation", + outer = outer_sym, + inner = inner_sym, + generic = generic_snippet + )); + }, + ); } else { - false + let generic_snippet = snippet(cx, inner_span, ".."); + span_lint_and_then( + cx, + REDUNDANT_ALLOCATION, + hir_ty.span, + &format!("usage of `{}<{}<{}>>`", outer_sym, inner_sym, generic_snippet), + |diag| { + diag.note(&format!( + "`{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 + )); + }, + ); } + true } diff --git a/tests/ui/redundant_allocation.fixed b/tests/ui/redundant_allocation.fixed deleted file mode 100644 index 6514fd6d1ac..00000000000 --- a/tests/ui/redundant_allocation.fixed +++ /dev/null @@ -1,48 +0,0 @@ -// run-rustfix -#![warn(clippy::all)] -#![allow(clippy::boxed_local, clippy::needless_pass_by_value)] -#![allow(clippy::blacklisted_name, unused_variables, dead_code)] - -use std::boxed::Box; -use std::rc::Rc; - -pub struct MyStruct {} - -pub struct SubT { - foo: T, -} - -pub enum MyEnum { - One, - Two, -} - -// Rc<&T> - -pub fn test1(foo: &T) {} - -pub fn test2(foo: &MyStruct) {} - -pub fn test3(foo: &MyEnum) {} - -pub fn test4_neg(foo: Rc>) {} - -// Rc> - -pub fn test5(a: Rc) {} - -// Rc> - -pub fn test6(a: Rc) {} - -// Box<&T> - -pub fn test7(foo: &T) {} - -pub fn test8(foo: &MyStruct) {} - -pub fn test9(foo: &MyEnum) {} - -pub fn test10_neg(foo: Box>) {} - -fn main() {} diff --git a/tests/ui/redundant_allocation.rs b/tests/ui/redundant_allocation.rs index 677b3e56d4d..1b4f2a66c70 100644 --- a/tests/ui/redundant_allocation.rs +++ b/tests/ui/redundant_allocation.rs @@ -1,10 +1,7 @@ -// run-rustfix #![warn(clippy::all)] #![allow(clippy::boxed_local, clippy::needless_pass_by_value)] #![allow(clippy::blacklisted_name, unused_variables, dead_code)] - -use std::boxed::Box; -use std::rc::Rc; +#![allow(unused_imports)] pub struct MyStruct {} @@ -17,32 +14,67 @@ pub enum MyEnum { Two, } -// Rc<&T> +mod outer_box { + use crate::MyEnum; + use crate::MyStruct; + use crate::SubT; + use std::boxed::Box; + use std::rc::Rc; + use std::sync::Arc; -pub fn test1(foo: Rc<&T>) {} + pub fn box_test6(foo: Box>) {} -pub fn test2(foo: Rc<&MyStruct>) {} + pub fn box_test7(foo: Box>) {} -pub fn test3(foo: Rc<&MyEnum>) {} + pub fn box_test8() -> Box>> { + unimplemented!(); + } -pub fn test4_neg(foo: Rc>) {} + pub fn box_test9(foo: Box>) -> Box>> { + unimplemented!(); + } +} -// Rc> +mod outer_rc { + use crate::MyEnum; + use crate::MyStruct; + use crate::SubT; + use std::boxed::Box; + use std::rc::Rc; + use std::sync::Arc; -pub fn test5(a: Rc>) {} + pub fn rc_test5(a: Rc>) {} -// Rc> + pub fn rc_test7(a: Rc>) {} -pub fn test6(a: Rc>) {} + pub fn rc_test8() -> Rc>> { + unimplemented!(); + } -// Box<&T> + pub fn rc_test9(foo: Rc>) -> Rc>> { + unimplemented!(); + } +} -pub fn test7(foo: Box<&T>) {} +mod outer_arc { + use crate::MyEnum; + use crate::MyStruct; + use crate::SubT; + use std::boxed::Box; + use std::rc::Rc; + use std::sync::Arc; -pub fn test8(foo: Box<&MyStruct>) {} + pub fn arc_test5(a: Arc>) {} -pub fn test9(foo: Box<&MyEnum>) {} + pub fn arc_test6(a: Arc>) {} -pub fn test10_neg(foo: Box>) {} + pub fn arc_test8() -> Arc>> { + unimplemented!(); + } + + pub fn arc_test9(foo: Arc>) -> Arc>> { + unimplemented!(); + } +} fn main() {} diff --git a/tests/ui/redundant_allocation.stderr b/tests/ui/redundant_allocation.stderr index 92e4f67f5db..fdab74eb538 100644 --- a/tests/ui/redundant_allocation.stderr +++ b/tests/ui/redundant_allocation.stderr @@ -1,52 +1,138 @@ -error: usage of `Rc<&T>` - --> $DIR/redundant_allocation.rs:22:22 +error: usage of `Box>` + --> $DIR/redundant_allocation.rs:25:30 | -LL | pub fn test1(foo: Rc<&T>) {} - | ^^^^^^ help: try: `&T` +LL | pub fn box_test6(foo: Box>) {} + | ^^^^^^^^^^ | = note: `-D clippy::redundant-allocation` implied by `-D warnings` + = note: `Rc` is already on the heap, `Box>` makes an extra allocation + = help: consider using just `Box` or `Rc` -error: usage of `Rc<&T>` - --> $DIR/redundant_allocation.rs:24:19 +error: usage of `Box>` + --> $DIR/redundant_allocation.rs:27:30 | -LL | pub fn test2(foo: Rc<&MyStruct>) {} - | ^^^^^^^^^^^^^ help: try: `&MyStruct` - -error: usage of `Rc<&T>` - --> $DIR/redundant_allocation.rs:26:19 +LL | pub fn box_test7(foo: Box>) {} + | ^^^^^^^^^^^ | -LL | pub fn test3(foo: Rc<&MyEnum>) {} - | ^^^^^^^^^^^ help: try: `&MyEnum` + = note: `Arc` is already on the heap, `Box>` makes an extra allocation + = help: consider using just `Box` or `Arc` -error: usage of `Rc>` - --> $DIR/redundant_allocation.rs:32:17 +error: usage of `Box>>` + --> $DIR/redundant_allocation.rs:29:27 | -LL | pub fn test5(a: Rc>) {} - | ^^^^^^^^^^^^ help: try: `Rc` - -error: usage of `Rc>` - --> $DIR/redundant_allocation.rs:36:17 +LL | pub fn box_test8() -> Box>> { + | ^^^^^^^^^^^^^^^^^^^^ | -LL | pub fn test6(a: Rc>) {} - | ^^^^^^^^^^^^^ help: try: `Rc` + = note: `Rc>` is already on the heap, `Box>>` makes an extra allocation + = help: consider using just `Box>` or `Rc>` -error: usage of `Box<&T>` - --> $DIR/redundant_allocation.rs:40:22 +error: usage of `Box>` + --> $DIR/redundant_allocation.rs:33:30 | -LL | pub fn test7(foo: Box<&T>) {} - | ^^^^^^^ help: try: `&T` - -error: usage of `Box<&T>` - --> $DIR/redundant_allocation.rs:42:19 +LL | pub fn box_test9(foo: Box>) -> Box>> { + | ^^^^^^^^^^^ | -LL | pub fn test8(foo: Box<&MyStruct>) {} - | ^^^^^^^^^^^^^^ help: try: `&MyStruct` + = note: `Arc` is already on the heap, `Box>` makes an extra allocation + = help: consider using just `Box` or `Arc` -error: usage of `Box<&T>` - --> $DIR/redundant_allocation.rs:44:19 +error: usage of `Box>>` + --> $DIR/redundant_allocation.rs:33:46 | -LL | pub fn test9(foo: Box<&MyEnum>) {} - | ^^^^^^^^^^^^ help: try: `&MyEnum` +LL | pub fn box_test9(foo: Box>) -> Box>> { + | ^^^^^^^^^^^^^^^^^ + | + = note: `Arc>` is already on the heap, `Box>>` makes an extra allocation + = help: consider using just `Box>` or `Arc>` -error: aborting due to 8 previous errors +error: usage of `Rc>` + --> $DIR/redundant_allocation.rs:46:24 + | +LL | pub fn rc_test5(a: Rc>) {} + | ^^^^^^^^^^^^^ + | + = note: `Box` is already on the heap, `Rc>` makes an extra allocation + = help: consider using just `Rc` or `Box` + +error: usage of `Rc>` + --> $DIR/redundant_allocation.rs:48:24 + | +LL | pub fn rc_test7(a: Rc>) {} + | ^^^^^^^^^^^^^ + | + = note: `Arc` is already on the heap, `Rc>` makes an extra allocation + = help: consider using just `Rc` or `Arc` + +error: usage of `Rc>>` + --> $DIR/redundant_allocation.rs:50:26 + | +LL | pub fn rc_test8() -> Rc>> { + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: `Box>` is already on the heap, `Rc>>` makes an extra allocation + = help: consider using just `Rc>` or `Box>` + +error: usage of `Rc>` + --> $DIR/redundant_allocation.rs:54:29 + | +LL | pub fn rc_test9(foo: Rc>) -> Rc>> { + | ^^^^^^^^^^ + | + = note: `Arc` is already on the heap, `Rc>` makes an extra allocation + = help: consider using just `Rc` or `Arc` + +error: usage of `Rc>>` + --> $DIR/redundant_allocation.rs:54:44 + | +LL | pub fn rc_test9(foo: Rc>) -> Rc>> { + | ^^^^^^^^^^^^^^^^ + | + = note: `Arc>` is already on the heap, `Rc>>` makes an extra allocation + = help: consider using just `Rc>` or `Arc>` + +error: usage of `Arc>` + --> $DIR/redundant_allocation.rs:67:25 + | +LL | pub fn arc_test5(a: Arc>) {} + | ^^^^^^^^^^^^^^ + | + = note: `Box` is already on the heap, `Arc>` makes an extra allocation + = help: consider using just `Arc` or `Box` + +error: usage of `Arc>` + --> $DIR/redundant_allocation.rs:69:25 + | +LL | pub fn arc_test6(a: Arc>) {} + | ^^^^^^^^^^^^^ + | + = note: `Rc` is already on the heap, `Arc>` makes an extra allocation + = help: consider using just `Arc` or `Rc` + +error: usage of `Arc>>` + --> $DIR/redundant_allocation.rs:71:27 + | +LL | pub fn arc_test8() -> Arc>> { + | ^^^^^^^^^^^^^^^^^^^^^ + | + = note: `Box>` is already on the heap, `Arc>>` makes an extra allocation + = help: consider using just `Arc>` or `Box>` + +error: usage of `Arc>` + --> $DIR/redundant_allocation.rs:75:30 + | +LL | pub fn arc_test9(foo: Arc>) -> Arc>> { + | ^^^^^^^^^^ + | + = note: `Rc` is already on the heap, `Arc>` makes an extra allocation + = help: consider using just `Arc` or `Rc` + +error: usage of `Arc>>` + --> $DIR/redundant_allocation.rs:75:45 + | +LL | pub fn arc_test9(foo: Arc>) -> Arc>> { + | ^^^^^^^^^^^^^^^^ + | + = note: `Rc>` is already on the heap, `Arc>>` makes an extra allocation + = help: consider using just `Arc>` or `Rc>` + +error: aborting due to 15 previous errors diff --git a/tests/ui/redundant_allocation_fixable.fixed b/tests/ui/redundant_allocation_fixable.fixed new file mode 100644 index 00000000000..ef089b25f47 --- /dev/null +++ b/tests/ui/redundant_allocation_fixable.fixed @@ -0,0 +1,75 @@ +// run-rustfix +#![warn(clippy::all)] +#![allow(clippy::boxed_local, clippy::needless_pass_by_value)] +#![allow(clippy::blacklisted_name, unused_variables, dead_code)] +#![allow(unused_imports)] + +pub struct MyStruct {} + +pub struct SubT { + foo: T, +} + +pub enum MyEnum { + One, + Two, +} + +mod outer_box { + use crate::MyEnum; + use crate::MyStruct; + use crate::SubT; + use std::boxed::Box; + use std::rc::Rc; + use std::sync::Arc; + + pub fn box_test1(foo: &T) {} + + pub fn box_test2(foo: &MyStruct) {} + + pub fn box_test3(foo: &MyEnum) {} + + pub fn box_test4_neg(foo: Box>) {} + + pub fn box_test5(foo: Box) {} +} + +mod outer_rc { + use crate::MyEnum; + use crate::MyStruct; + use crate::SubT; + use std::boxed::Box; + use std::rc::Rc; + use std::sync::Arc; + + pub fn rc_test1(foo: &T) {} + + pub fn rc_test2(foo: &MyStruct) {} + + pub fn rc_test3(foo: &MyEnum) {} + + pub fn rc_test4_neg(foo: Rc>) {} + + pub fn rc_test6(a: Rc) {} +} + +mod outer_arc { + use crate::MyEnum; + use crate::MyStruct; + use crate::SubT; + use std::boxed::Box; + use std::rc::Rc; + use std::sync::Arc; + + pub fn arc_test1(foo: &T) {} + + pub fn arc_test2(foo: &MyStruct) {} + + pub fn arc_test3(foo: &MyEnum) {} + + pub fn arc_test4_neg(foo: Arc>) {} + + pub fn arc_test7(a: Arc) {} +} + +fn main() {} diff --git a/tests/ui/redundant_allocation_fixable.rs b/tests/ui/redundant_allocation_fixable.rs new file mode 100644 index 00000000000..fefa87721d7 --- /dev/null +++ b/tests/ui/redundant_allocation_fixable.rs @@ -0,0 +1,75 @@ +// run-rustfix +#![warn(clippy::all)] +#![allow(clippy::boxed_local, clippy::needless_pass_by_value)] +#![allow(clippy::blacklisted_name, unused_variables, dead_code)] +#![allow(unused_imports)] + +pub struct MyStruct {} + +pub struct SubT { + foo: T, +} + +pub enum MyEnum { + One, + Two, +} + +mod outer_box { + use crate::MyEnum; + use crate::MyStruct; + use crate::SubT; + use std::boxed::Box; + use std::rc::Rc; + use std::sync::Arc; + + pub fn box_test1(foo: Box<&T>) {} + + pub fn box_test2(foo: Box<&MyStruct>) {} + + pub fn box_test3(foo: Box<&MyEnum>) {} + + pub fn box_test4_neg(foo: Box>) {} + + pub fn box_test5(foo: Box>) {} +} + +mod outer_rc { + use crate::MyEnum; + use crate::MyStruct; + use crate::SubT; + use std::boxed::Box; + use std::rc::Rc; + use std::sync::Arc; + + pub fn rc_test1(foo: Rc<&T>) {} + + pub fn rc_test2(foo: Rc<&MyStruct>) {} + + pub fn rc_test3(foo: Rc<&MyEnum>) {} + + pub fn rc_test4_neg(foo: Rc>) {} + + pub fn rc_test6(a: Rc>) {} +} + +mod outer_arc { + use crate::MyEnum; + use crate::MyStruct; + use crate::SubT; + use std::boxed::Box; + use std::rc::Rc; + use std::sync::Arc; + + pub fn arc_test1(foo: Arc<&T>) {} + + pub fn arc_test2(foo: Arc<&MyStruct>) {} + + pub fn arc_test3(foo: Arc<&MyEnum>) {} + + pub fn arc_test4_neg(foo: Arc>) {} + + pub fn arc_test7(a: Arc>) {} +} + +fn main() {} diff --git a/tests/ui/redundant_allocation_fixable.stderr b/tests/ui/redundant_allocation_fixable.stderr new file mode 100644 index 00000000000..fdd76ef17a5 --- /dev/null +++ b/tests/ui/redundant_allocation_fixable.stderr @@ -0,0 +1,99 @@ +error: usage of `Box<&T>` + --> $DIR/redundant_allocation_fixable.rs:26:30 + | +LL | pub fn box_test1(foo: Box<&T>) {} + | ^^^^^^^ help: try: `&T` + | + = note: `-D clippy::redundant-allocation` implied by `-D warnings` + = note: `&T` is already a pointer, `Box<&T>` allocates a pointer on the heap + +error: usage of `Box<&MyStruct>` + --> $DIR/redundant_allocation_fixable.rs:28:27 + | +LL | pub fn box_test2(foo: Box<&MyStruct>) {} + | ^^^^^^^^^^^^^^ help: try: `&MyStruct` + | + = note: `&MyStruct` is already a pointer, `Box<&MyStruct>` allocates a pointer on the heap + +error: usage of `Box<&MyEnum>` + --> $DIR/redundant_allocation_fixable.rs:30:27 + | +LL | pub fn box_test3(foo: Box<&MyEnum>) {} + | ^^^^^^^^^^^^ help: try: `&MyEnum` + | + = note: `&MyEnum` is already a pointer, `Box<&MyEnum>` allocates a pointer on the heap + +error: usage of `Box>` + --> $DIR/redundant_allocation_fixable.rs:34:30 + | +LL | pub fn box_test5(foo: Box>) {} + | ^^^^^^^^^^^ help: try: `Box` + | + = note: `Box` is already on the heap, `Box>` makes an extra allocation + +error: usage of `Rc<&T>` + --> $DIR/redundant_allocation_fixable.rs:45:29 + | +LL | pub fn rc_test1(foo: Rc<&T>) {} + | ^^^^^^ help: try: `&T` + | + = note: `&T` is already a pointer, `Rc<&T>` allocates a pointer on the heap + +error: usage of `Rc<&MyStruct>` + --> $DIR/redundant_allocation_fixable.rs:47:26 + | +LL | pub fn rc_test2(foo: Rc<&MyStruct>) {} + | ^^^^^^^^^^^^^ help: try: `&MyStruct` + | + = note: `&MyStruct` is already a pointer, `Rc<&MyStruct>` allocates a pointer on the heap + +error: usage of `Rc<&MyEnum>` + --> $DIR/redundant_allocation_fixable.rs:49:26 + | +LL | pub fn rc_test3(foo: Rc<&MyEnum>) {} + | ^^^^^^^^^^^ help: try: `&MyEnum` + | + = note: `&MyEnum` is already a pointer, `Rc<&MyEnum>` allocates a pointer on the heap + +error: usage of `Rc>` + --> $DIR/redundant_allocation_fixable.rs:53:24 + | +LL | pub fn rc_test6(a: Rc>) {} + | ^^^^^^^^^^^^ help: try: `Rc` + | + = note: `Rc` is already on the heap, `Rc>` makes an extra allocation + +error: usage of `Arc<&T>` + --> $DIR/redundant_allocation_fixable.rs:64:30 + | +LL | pub fn arc_test1(foo: Arc<&T>) {} + | ^^^^^^^ help: try: `&T` + | + = note: `&T` is already a pointer, `Arc<&T>` allocates a pointer on the heap + +error: usage of `Arc<&MyStruct>` + --> $DIR/redundant_allocation_fixable.rs:66:27 + | +LL | pub fn arc_test2(foo: Arc<&MyStruct>) {} + | ^^^^^^^^^^^^^^ help: try: `&MyStruct` + | + = note: `&MyStruct` is already a pointer, `Arc<&MyStruct>` allocates a pointer on the heap + +error: usage of `Arc<&MyEnum>` + --> $DIR/redundant_allocation_fixable.rs:68:27 + | +LL | pub fn arc_test3(foo: Arc<&MyEnum>) {} + | ^^^^^^^^^^^^ help: try: `&MyEnum` + | + = note: `&MyEnum` is already a pointer, `Arc<&MyEnum>` allocates a pointer on the heap + +error: usage of `Arc>` + --> $DIR/redundant_allocation_fixable.rs:72:25 + | +LL | pub fn arc_test7(a: Arc>) {} + | ^^^^^^^^^^^^^^ help: try: `Arc` + | + = note: `Arc` is already on the heap, `Arc>` makes an extra allocation + +error: aborting due to 12 previous errors +