Auto merge of #7308 - lengyijun:redundant_allocation_arc, r=xFrednet,flip1995
add Arc to `redundant_allocation` fixes #7303 changelog: add Arc to `redundant_allocation`
This commit is contained in:
commit
09f5f15d8b
@ -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<T>>`, `Rc<Box<T>>`, `Box<&T>`
|
||||
/// add an unnecessary level of indirection.
|
||||
/// **Why is this bad?** Expressions such as `Rc<&T>`, `Rc<Rc<T>>`, `Rc<Arc<T>>`, `Rc<Box<T>>`, Arc<&T>`, `Arc<Rc<T>>`,
|
||||
/// `Arc<Arc<T>>`, `Arc<Box<T>>`, `Box<&T>`, `Box<Rc<T>>`, `Box<Arc<T>>`, `Box<Box<T>>`, add an unnecessary level of indirection.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
|
@ -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<Rc<T>>`",
|
||||
"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<Box<T>>`",
|
||||
"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
|
||||
}
|
||||
|
@ -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<T> {
|
||||
foo: T,
|
||||
}
|
||||
|
||||
pub enum MyEnum {
|
||||
One,
|
||||
Two,
|
||||
}
|
||||
|
||||
// Rc<&T>
|
||||
|
||||
pub fn test1<T>(foo: &T) {}
|
||||
|
||||
pub fn test2(foo: &MyStruct) {}
|
||||
|
||||
pub fn test3(foo: &MyEnum) {}
|
||||
|
||||
pub fn test4_neg(foo: Rc<SubT<&usize>>) {}
|
||||
|
||||
// Rc<Rc<T>>
|
||||
|
||||
pub fn test5(a: Rc<bool>) {}
|
||||
|
||||
// Rc<Box<T>>
|
||||
|
||||
pub fn test6(a: Rc<bool>) {}
|
||||
|
||||
// Box<&T>
|
||||
|
||||
pub fn test7<T>(foo: &T) {}
|
||||
|
||||
pub fn test8(foo: &MyStruct) {}
|
||||
|
||||
pub fn test9(foo: &MyEnum) {}
|
||||
|
||||
pub fn test10_neg(foo: Box<SubT<&usize>>) {}
|
||||
|
||||
fn main() {}
|
@ -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<T>(foo: Rc<&T>) {}
|
||||
pub fn box_test6<T>(foo: Box<Rc<T>>) {}
|
||||
|
||||
pub fn test2(foo: Rc<&MyStruct>) {}
|
||||
pub fn box_test7<T>(foo: Box<Arc<T>>) {}
|
||||
|
||||
pub fn test3(foo: Rc<&MyEnum>) {}
|
||||
pub fn box_test8() -> Box<Rc<SubT<usize>>> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
pub fn test4_neg(foo: Rc<SubT<&usize>>) {}
|
||||
pub fn box_test9<T>(foo: Box<Arc<T>>) -> Box<Arc<SubT<T>>> {
|
||||
unimplemented!();
|
||||
}
|
||||
}
|
||||
|
||||
// Rc<Rc<T>>
|
||||
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<Rc<bool>>) {}
|
||||
pub fn rc_test5(a: Rc<Box<bool>>) {}
|
||||
|
||||
// Rc<Box<T>>
|
||||
pub fn rc_test7(a: Rc<Arc<bool>>) {}
|
||||
|
||||
pub fn test6(a: Rc<Box<bool>>) {}
|
||||
pub fn rc_test8() -> Rc<Box<SubT<usize>>> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
// Box<&T>
|
||||
pub fn rc_test9<T>(foo: Rc<Arc<T>>) -> Rc<Arc<SubT<T>>> {
|
||||
unimplemented!();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn test7<T>(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<Box<bool>>) {}
|
||||
|
||||
pub fn test9(foo: Box<&MyEnum>) {}
|
||||
pub fn arc_test6(a: Arc<Rc<bool>>) {}
|
||||
|
||||
pub fn test10_neg(foo: Box<SubT<&usize>>) {}
|
||||
pub fn arc_test8() -> Arc<Box<SubT<usize>>> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
pub fn arc_test9<T>(foo: Arc<Rc<T>>) -> Arc<Rc<SubT<T>>> {
|
||||
unimplemented!();
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,52 +1,138 @@
|
||||
error: usage of `Rc<&T>`
|
||||
--> $DIR/redundant_allocation.rs:22:22
|
||||
error: usage of `Box<Rc<T>>`
|
||||
--> $DIR/redundant_allocation.rs:25:30
|
||||
|
|
||||
LL | pub fn test1<T>(foo: Rc<&T>) {}
|
||||
| ^^^^^^ help: try: `&T`
|
||||
LL | pub fn box_test6<T>(foo: Box<Rc<T>>) {}
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
= note: `-D clippy::redundant-allocation` implied by `-D warnings`
|
||||
= note: `Rc<T>` is already on the heap, `Box<Rc<T>>` makes an extra allocation
|
||||
= help: consider using just `Box<T>` or `Rc<T>`
|
||||
|
||||
error: usage of `Rc<&T>`
|
||||
--> $DIR/redundant_allocation.rs:24:19
|
||||
error: usage of `Box<Arc<T>>`
|
||||
--> $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<T>(foo: Box<Arc<T>>) {}
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
LL | pub fn test3(foo: Rc<&MyEnum>) {}
|
||||
| ^^^^^^^^^^^ help: try: `&MyEnum`
|
||||
= 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 `Rc<Rc<T>>`
|
||||
--> $DIR/redundant_allocation.rs:32:17
|
||||
error: usage of `Box<Rc<SubT<usize>>>`
|
||||
--> $DIR/redundant_allocation.rs:29:27
|
||||
|
|
||||
LL | pub fn test5(a: Rc<Rc<bool>>) {}
|
||||
| ^^^^^^^^^^^^ help: try: `Rc<bool>`
|
||||
|
||||
error: usage of `Rc<Box<T>>`
|
||||
--> $DIR/redundant_allocation.rs:36:17
|
||||
LL | pub fn box_test8() -> Box<Rc<SubT<usize>>> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
LL | pub fn test6(a: Rc<Box<bool>>) {}
|
||||
| ^^^^^^^^^^^^^ help: try: `Rc<bool>`
|
||||
= 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<&T>`
|
||||
--> $DIR/redundant_allocation.rs:40:22
|
||||
error: usage of `Box<Arc<T>>`
|
||||
--> $DIR/redundant_allocation.rs:33:30
|
||||
|
|
||||
LL | pub fn test7<T>(foo: Box<&T>) {}
|
||||
| ^^^^^^^ help: try: `&T`
|
||||
|
||||
error: usage of `Box<&T>`
|
||||
--> $DIR/redundant_allocation.rs:42:19
|
||||
LL | pub fn box_test9<T>(foo: Box<Arc<T>>) -> Box<Arc<SubT<T>>> {
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
LL | pub fn test8(foo: Box<&MyStruct>) {}
|
||||
| ^^^^^^^^^^^^^^ help: try: `&MyStruct`
|
||||
= 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<&T>`
|
||||
--> $DIR/redundant_allocation.rs:44:19
|
||||
error: usage of `Box<Arc<SubT<T>>>`
|
||||
--> $DIR/redundant_allocation.rs:33:46
|
||||
|
|
||||
LL | pub fn test9(foo: Box<&MyEnum>) {}
|
||||
| ^^^^^^^^^^^^ help: try: `&MyEnum`
|
||||
LL | pub fn box_test9<T>(foo: Box<Arc<T>>) -> Box<Arc<SubT<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: aborting due to 8 previous errors
|
||||
error: usage of `Rc<Box<bool>>`
|
||||
--> $DIR/redundant_allocation.rs:46:24
|
||||
|
|
||||
LL | pub fn rc_test5(a: Rc<Box<bool>>) {}
|
||||
| ^^^^^^^^^^^^^
|
||||
|
|
||||
= 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<bool>>`
|
||||
--> $DIR/redundant_allocation.rs:48:24
|
||||
|
|
||||
LL | pub fn rc_test7(a: Rc<Arc<bool>>) {}
|
||||
| ^^^^^^^^^^^^^
|
||||
|
|
||||
= 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<SubT<usize>>>`
|
||||
--> $DIR/redundant_allocation.rs:50:26
|
||||
|
|
||||
LL | pub fn rc_test8() -> Rc<Box<SubT<usize>>> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= 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
|
||||
|
|
||||
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<SubT<T>>>`
|
||||
--> $DIR/redundant_allocation.rs:54:44
|
||||
|
|
||||
LL | pub fn rc_test9<T>(foo: Rc<Arc<T>>) -> Rc<Arc<SubT<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<bool>>`
|
||||
--> $DIR/redundant_allocation.rs:67:25
|
||||
|
|
||||
LL | pub fn arc_test5(a: Arc<Box<bool>>) {}
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
= 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<bool>>`
|
||||
--> $DIR/redundant_allocation.rs:69:25
|
||||
|
|
||||
LL | pub fn arc_test6(a: Arc<Rc<bool>>) {}
|
||||
| ^^^^^^^^^^^^^
|
||||
|
|
||||
= 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<SubT<usize>>>`
|
||||
--> $DIR/redundant_allocation.rs:71:27
|
||||
|
|
||||
LL | pub fn arc_test8() -> Arc<Box<SubT<usize>>> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= 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
|
||||
|
|
||||
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<SubT<T>>>`
|
||||
--> $DIR/redundant_allocation.rs:75:45
|
||||
|
|
||||
LL | pub fn arc_test9<T>(foo: Arc<Rc<T>>) -> Arc<Rc<SubT<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
|
||||
|
||||
|
75
tests/ui/redundant_allocation_fixable.fixed
Normal file
75
tests/ui/redundant_allocation_fixable.fixed
Normal file
@ -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<T> {
|
||||
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<T>(foo: &T) {}
|
||||
|
||||
pub fn box_test2(foo: &MyStruct) {}
|
||||
|
||||
pub fn box_test3(foo: &MyEnum) {}
|
||||
|
||||
pub fn box_test4_neg(foo: Box<SubT<&usize>>) {}
|
||||
|
||||
pub fn box_test5<T>(foo: Box<T>) {}
|
||||
}
|
||||
|
||||
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<T>(foo: &T) {}
|
||||
|
||||
pub fn rc_test2(foo: &MyStruct) {}
|
||||
|
||||
pub fn rc_test3(foo: &MyEnum) {}
|
||||
|
||||
pub fn rc_test4_neg(foo: Rc<SubT<&usize>>) {}
|
||||
|
||||
pub fn rc_test6(a: Rc<bool>) {}
|
||||
}
|
||||
|
||||
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<T>(foo: &T) {}
|
||||
|
||||
pub fn arc_test2(foo: &MyStruct) {}
|
||||
|
||||
pub fn arc_test3(foo: &MyEnum) {}
|
||||
|
||||
pub fn arc_test4_neg(foo: Arc<SubT<&usize>>) {}
|
||||
|
||||
pub fn arc_test7(a: Arc<bool>) {}
|
||||
}
|
||||
|
||||
fn main() {}
|
75
tests/ui/redundant_allocation_fixable.rs
Normal file
75
tests/ui/redundant_allocation_fixable.rs
Normal file
@ -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<T> {
|
||||
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<T>(foo: Box<&T>) {}
|
||||
|
||||
pub fn box_test2(foo: Box<&MyStruct>) {}
|
||||
|
||||
pub fn box_test3(foo: Box<&MyEnum>) {}
|
||||
|
||||
pub fn box_test4_neg(foo: Box<SubT<&usize>>) {}
|
||||
|
||||
pub fn box_test5<T>(foo: Box<Box<T>>) {}
|
||||
}
|
||||
|
||||
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<T>(foo: Rc<&T>) {}
|
||||
|
||||
pub fn rc_test2(foo: Rc<&MyStruct>) {}
|
||||
|
||||
pub fn rc_test3(foo: Rc<&MyEnum>) {}
|
||||
|
||||
pub fn rc_test4_neg(foo: Rc<SubT<&usize>>) {}
|
||||
|
||||
pub fn rc_test6(a: Rc<Rc<bool>>) {}
|
||||
}
|
||||
|
||||
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<T>(foo: Arc<&T>) {}
|
||||
|
||||
pub fn arc_test2(foo: Arc<&MyStruct>) {}
|
||||
|
||||
pub fn arc_test3(foo: Arc<&MyEnum>) {}
|
||||
|
||||
pub fn arc_test4_neg(foo: Arc<SubT<&usize>>) {}
|
||||
|
||||
pub fn arc_test7(a: Arc<Arc<bool>>) {}
|
||||
}
|
||||
|
||||
fn main() {}
|
99
tests/ui/redundant_allocation_fixable.stderr
Normal file
99
tests/ui/redundant_allocation_fixable.stderr
Normal file
@ -0,0 +1,99 @@
|
||||
error: usage of `Box<&T>`
|
||||
--> $DIR/redundant_allocation_fixable.rs:26:30
|
||||
|
|
||||
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>` 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<Box<T>>`
|
||||
--> $DIR/redundant_allocation_fixable.rs:34:30
|
||||
|
|
||||
LL | pub fn box_test5<T>(foo: Box<Box<T>>) {}
|
||||
| ^^^^^^^^^^^ help: try: `Box<T>`
|
||||
|
|
||||
= note: `Box<T>` is already on the heap, `Box<Box<T>>` makes an extra allocation
|
||||
|
||||
error: usage of `Rc<&T>`
|
||||
--> $DIR/redundant_allocation_fixable.rs:45:29
|
||||
|
|
||||
LL | pub fn rc_test1<T>(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<Rc<bool>>`
|
||||
--> $DIR/redundant_allocation_fixable.rs:53:24
|
||||
|
|
||||
LL | pub fn rc_test6(a: Rc<Rc<bool>>) {}
|
||||
| ^^^^^^^^^^^^ help: try: `Rc<bool>`
|
||||
|
|
||||
= 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>` 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<Arc<bool>>`
|
||||
--> $DIR/redundant_allocation_fixable.rs:72:25
|
||||
|
|
||||
LL | pub fn arc_test7(a: Arc<Arc<bool>>) {}
|
||||
| ^^^^^^^^^^^^^^ help: try: `Arc<bool>`
|
||||
|
|
||||
= note: `Arc<bool>` is already on the heap, `Arc<Arc<bool>>` makes an extra allocation
|
||||
|
||||
error: aborting due to 12 previous errors
|
||||
|
Loading…
Reference in New Issue
Block a user