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! {
|
declare_clippy_lint! {
|
||||||
/// **What it does:** Checks for use of redundant allocations anywhere in the code.
|
/// **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>`
|
/// **Why is this bad?** Expressions such as `Rc<&T>`, `Rc<Rc<T>>`, `Rc<Arc<T>>`, `Rc<Box<T>>`, Arc<&T>`, `Arc<Rc<T>>`,
|
||||||
/// add an unnecessary level of indirection.
|
/// `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.
|
/// **Known problems:** None.
|
||||||
///
|
///
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
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 clippy_utils::{get_qpath_generic_tys, is_ty_param_diagnostic_item, is_ty_param_lang_item};
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_hir::{self as hir, def_id::DefId, LangItem, QPath, TyKind};
|
use rustc_hir::{self as hir, def_id::DefId, LangItem, QPath, TyKind};
|
||||||
@ -9,74 +9,99 @@
|
|||||||
use super::{utils, REDUNDANT_ALLOCATION};
|
use super::{utils, REDUNDANT_ALLOCATION};
|
||||||
|
|
||||||
pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_>, def_id: DefId) -> bool {
|
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() {
|
let outer_sym = if Some(def_id) == cx.tcx.lang_items().owned_box() {
|
||||||
if let Some(span) = utils::match_borrows_parameter(cx, qpath) {
|
"Box"
|
||||||
let mut applicability = Applicability::MachineApplicable;
|
} else if cx.tcx.is_diagnostic_item(sym::Rc, def_id) {
|
||||||
span_lint_and_sugg(
|
"Rc"
|
||||||
cx,
|
} else if cx.tcx.is_diagnostic_item(sym::Arc, def_id) {
|
||||||
REDUNDANT_ALLOCATION,
|
"Arc"
|
||||||
hir_ty.span,
|
} else {
|
||||||
"usage of `Box<&T>`",
|
return false;
|
||||||
"try",
|
};
|
||||||
snippet_with_applicability(cx, span, "..", &mut applicability).to_string(),
|
|
||||||
applicability,
|
if let Some(span) = utils::match_borrows_parameter(cx, qpath) {
|
||||||
);
|
let mut applicability = Applicability::MaybeIncorrect;
|
||||||
return true;
|
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) {
|
let (inner_sym, ty) = if let Some(ty) = is_ty_param_lang_item(cx, qpath, LangItem::OwnedBox) {
|
||||||
if let Some(ty) = is_ty_param_diagnostic_item(cx, qpath, sym::Rc) {
|
("Box", ty)
|
||||||
let mut applicability = Applicability::MachineApplicable;
|
} else if let Some(ty) = is_ty_param_diagnostic_item(cx, qpath, sym::Rc) {
|
||||||
span_lint_and_sugg(
|
("Rc", ty)
|
||||||
cx,
|
} else if let Some(ty) = is_ty_param_diagnostic_item(cx, qpath, sym::Arc) {
|
||||||
REDUNDANT_ALLOCATION,
|
("Arc", ty)
|
||||||
hir_ty.span,
|
} else {
|
||||||
"usage of `Rc<Rc<T>>`",
|
return false;
|
||||||
"try",
|
};
|
||||||
snippet_with_applicability(cx, ty.span, "..", &mut applicability).to_string(),
|
|
||||||
applicability,
|
let inner_qpath = match &ty.kind {
|
||||||
);
|
TyKind::Path(inner_qpath) => inner_qpath,
|
||||||
true
|
_ => return false,
|
||||||
} else if let Some(ty) = is_ty_param_lang_item(cx, qpath, LangItem::OwnedBox) {
|
};
|
||||||
let qpath = match &ty.kind {
|
let inner_span = match get_qpath_generic_tys(inner_qpath).next() {
|
||||||
TyKind::Path(qpath) => qpath,
|
Some(ty) => ty.span,
|
||||||
_ => return false,
|
None => return false,
|
||||||
};
|
};
|
||||||
let inner_span = match get_qpath_generic_tys(qpath).next() {
|
if inner_sym == outer_sym {
|
||||||
Some(ty) => ty.span,
|
let mut applicability = Applicability::MaybeIncorrect;
|
||||||
None => return false,
|
let generic_snippet = snippet_with_applicability(cx, inner_span, "..", &mut applicability);
|
||||||
};
|
span_lint_and_then(
|
||||||
let mut applicability = Applicability::MachineApplicable;
|
cx,
|
||||||
span_lint_and_sugg(
|
REDUNDANT_ALLOCATION,
|
||||||
cx,
|
hir_ty.span,
|
||||||
REDUNDANT_ALLOCATION,
|
&format!("usage of `{}<{}<{}>>`", outer_sym, inner_sym, generic_snippet),
|
||||||
hir_ty.span,
|
|diag| {
|
||||||
"usage of `Rc<Box<T>>`",
|
diag.span_suggestion(
|
||||||
"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,
|
|
||||||
hir_ty.span,
|
hir_ty.span,
|
||||||
"usage of `Rc<&T>`",
|
|
||||||
"try",
|
"try",
|
||||||
snippet_with_applicability(cx, span, "..", &mut applicability).to_string(),
|
format!("{}<{}>", outer_sym, generic_snippet),
|
||||||
applicability,
|
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 {
|
} 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)]
|
#![warn(clippy::all)]
|
||||||
#![allow(clippy::boxed_local, clippy::needless_pass_by_value)]
|
#![allow(clippy::boxed_local, clippy::needless_pass_by_value)]
|
||||||
#![allow(clippy::blacklisted_name, unused_variables, dead_code)]
|
#![allow(clippy::blacklisted_name, unused_variables, dead_code)]
|
||||||
|
#![allow(unused_imports)]
|
||||||
use std::boxed::Box;
|
|
||||||
use std::rc::Rc;
|
|
||||||
|
|
||||||
pub struct MyStruct {}
|
pub struct MyStruct {}
|
||||||
|
|
||||||
@ -17,32 +14,67 @@ pub enum MyEnum {
|
|||||||
Two,
|
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() {}
|
fn main() {}
|
||||||
|
@ -1,52 +1,138 @@
|
|||||||
error: usage of `Rc<&T>`
|
error: usage of `Box<Rc<T>>`
|
||||||
--> $DIR/redundant_allocation.rs:22:22
|
--> $DIR/redundant_allocation.rs:25:30
|
||||||
|
|
|
|
||||||
LL | pub fn test1<T>(foo: Rc<&T>) {}
|
LL | pub fn box_test6<T>(foo: Box<Rc<T>>) {}
|
||||||
| ^^^^^^ help: try: `&T`
|
| ^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: `-D clippy::redundant-allocation` implied by `-D warnings`
|
= 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>`
|
error: usage of `Box<Arc<T>>`
|
||||||
--> $DIR/redundant_allocation.rs:24:19
|
--> $DIR/redundant_allocation.rs:27:30
|
||||||
|
|
|
|
||||||
LL | pub fn test2(foo: Rc<&MyStruct>) {}
|
LL | pub fn box_test7<T>(foo: Box<Arc<T>>) {}
|
||||||
| ^^^^^^^^^^^^^ help: try: `&MyStruct`
|
| ^^^^^^^^^^^
|
||||||
|
|
||||||
error: usage of `Rc<&T>`
|
|
||||||
--> $DIR/redundant_allocation.rs:26:19
|
|
||||||
|
|
|
|
||||||
LL | pub fn test3(foo: Rc<&MyEnum>) {}
|
= note: `Arc<T>` is already on the heap, `Box<Arc<T>>` makes an extra allocation
|
||||||
| ^^^^^^^^^^^ help: try: `&MyEnum`
|
= help: consider using just `Box<T>` or `Arc<T>`
|
||||||
|
|
||||||
error: usage of `Rc<Rc<T>>`
|
error: usage of `Box<Rc<SubT<usize>>>`
|
||||||
--> $DIR/redundant_allocation.rs:32:17
|
--> $DIR/redundant_allocation.rs:29:27
|
||||||
|
|
|
|
||||||
LL | pub fn test5(a: Rc<Rc<bool>>) {}
|
LL | pub fn box_test8() -> Box<Rc<SubT<usize>>> {
|
||||||
| ^^^^^^^^^^^^ help: try: `Rc<bool>`
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: usage of `Rc<Box<T>>`
|
|
||||||
--> $DIR/redundant_allocation.rs:36:17
|
|
||||||
|
|
|
|
||||||
LL | pub fn test6(a: Rc<Box<bool>>) {}
|
= note: `Rc<SubT<usize>>` is already on the heap, `Box<Rc<SubT<usize>>>` makes an extra allocation
|
||||||
| ^^^^^^^^^^^^^ help: try: `Rc<bool>`
|
= help: consider using just `Box<SubT<usize>>` or `Rc<SubT<usize>>`
|
||||||
|
|
||||||
error: usage of `Box<&T>`
|
error: usage of `Box<Arc<T>>`
|
||||||
--> $DIR/redundant_allocation.rs:40:22
|
--> $DIR/redundant_allocation.rs:33:30
|
||||||
|
|
|
|
||||||
LL | pub fn test7<T>(foo: Box<&T>) {}
|
LL | pub fn box_test9<T>(foo: Box<Arc<T>>) -> Box<Arc<SubT<T>>> {
|
||||||
| ^^^^^^^ help: try: `&T`
|
| ^^^^^^^^^^^
|
||||||
|
|
||||||
error: usage of `Box<&T>`
|
|
||||||
--> $DIR/redundant_allocation.rs:42:19
|
|
||||||
|
|
|
|
||||||
LL | pub fn test8(foo: Box<&MyStruct>) {}
|
= note: `Arc<T>` is already on the heap, `Box<Arc<T>>` makes an extra allocation
|
||||||
| ^^^^^^^^^^^^^^ help: try: `&MyStruct`
|
= help: consider using just `Box<T>` or `Arc<T>`
|
||||||
|
|
||||||
error: usage of `Box<&T>`
|
error: usage of `Box<Arc<SubT<T>>>`
|
||||||
--> $DIR/redundant_allocation.rs:44:19
|
--> $DIR/redundant_allocation.rs:33:46
|
||||||
|
|
|
|
||||||
LL | pub fn test9(foo: Box<&MyEnum>) {}
|
LL | pub fn box_test9<T>(foo: Box<Arc<T>>) -> Box<Arc<SubT<T>>> {
|
||||||
| ^^^^^^^^^^^^ help: try: `&MyEnum`
|
| ^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= 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