mirror of
https://github.com/rust-lang/rust.git
synced 2024-12-11 16:15:03 +00:00
Ignore not really redundant clones of ManuallyDrop
"Redundant" clones of `ManuallyDrop` are sometimes used for the side effect of invoking the clone, without running the drop implementation of the inner type. In other words, they aren't really redundant. For example, futures-rs crate: ```rust #[allow(clippy::redundant_clone)] // The clone here isn't actually redundant. unsafe fn increase_refcount<T: ArcWake>(data: *const ()) { // Retain Arc, but don't touch refcount by wrapping in ManuallyDrop let arc = mem::ManuallyDrop::new(Arc::<T>::from_raw(data as *const T)); // Now increase refcount, but don't drop new refcount either let _arc_clone: mem::ManuallyDrop<_> = arc.clone(); } ``` Ignore redundant clone lint for ManuallyDrop.
This commit is contained in:
parent
8cf4219c16
commit
a5cdd4aeb1
@ -124,6 +124,12 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClone {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let ty::Adt(ref def, _) = arg_ty.kind {
|
||||||
|
if match_def_path(cx, def.did, &paths::MEM_MANUALLY_DROP) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// `{ cloned = &arg; clone(move cloned); }` or `{ cloned = &arg; to_path_buf(cloned); }`
|
// `{ cloned = &arg; clone(move cloned); }` or `{ cloned = &arg; to_path_buf(cloned); }`
|
||||||
let (cloned, cannot_move_out) = unwrap_or_continue!(find_stmt_assigns_to(cx, mir, arg, from_borrow, bb));
|
let (cloned, cannot_move_out) = unwrap_or_continue!(find_stmt_assigns_to(cx, mir, arg, from_borrow, bb));
|
||||||
|
|
||||||
|
@ -59,6 +59,7 @@ pub const LINKED_LIST: [&str; 4] = ["alloc", "collections", "linked_list", "Link
|
|||||||
pub const LINT: [&str; 3] = ["rustc_session", "lint", "Lint"];
|
pub const LINT: [&str; 3] = ["rustc_session", "lint", "Lint"];
|
||||||
pub const MEM_DISCRIMINANT: [&str; 3] = ["core", "mem", "discriminant"];
|
pub const MEM_DISCRIMINANT: [&str; 3] = ["core", "mem", "discriminant"];
|
||||||
pub const MEM_FORGET: [&str; 3] = ["core", "mem", "forget"];
|
pub const MEM_FORGET: [&str; 3] = ["core", "mem", "forget"];
|
||||||
|
pub const MEM_MANUALLY_DROP: [&str; 4] = ["core", "mem", "manually_drop", "ManuallyDrop"];
|
||||||
pub const MEM_MAYBEUNINIT: [&str; 4] = ["core", "mem", "maybe_uninit", "MaybeUninit"];
|
pub const MEM_MAYBEUNINIT: [&str; 4] = ["core", "mem", "maybe_uninit", "MaybeUninit"];
|
||||||
pub const MEM_MAYBEUNINIT_UNINIT: [&str; 5] = ["core", "mem", "maybe_uninit", "MaybeUninit", "uninit"];
|
pub const MEM_MAYBEUNINIT_UNINIT: [&str; 5] = ["core", "mem", "maybe_uninit", "MaybeUninit", "uninit"];
|
||||||
pub const MEM_REPLACE: [&str; 3] = ["core", "mem", "replace"];
|
pub const MEM_REPLACE: [&str; 3] = ["core", "mem", "replace"];
|
||||||
|
@ -52,6 +52,7 @@ fn main() {
|
|||||||
borrower_propagation();
|
borrower_propagation();
|
||||||
not_consumed();
|
not_consumed();
|
||||||
issue_5405();
|
issue_5405();
|
||||||
|
manually_drop();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@ -170,3 +171,17 @@ fn issue_5405() {
|
|||||||
let c: [usize; 2] = [2, 3];
|
let c: [usize; 2] = [2, 3];
|
||||||
let _d: usize = c[1].clone();
|
let _d: usize = c[1].clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn manually_drop() {
|
||||||
|
use std::mem::ManuallyDrop;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
let a = ManuallyDrop::new(Arc::new("Hello!".to_owned()));
|
||||||
|
let _ = a.clone(); // OK
|
||||||
|
|
||||||
|
let p: *const String = Arc::into_raw(ManuallyDrop::into_inner(a));
|
||||||
|
unsafe {
|
||||||
|
Arc::from_raw(p);
|
||||||
|
Arc::from_raw(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -52,6 +52,7 @@ fn main() {
|
|||||||
borrower_propagation();
|
borrower_propagation();
|
||||||
not_consumed();
|
not_consumed();
|
||||||
issue_5405();
|
issue_5405();
|
||||||
|
manually_drop();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@ -170,3 +171,17 @@ fn issue_5405() {
|
|||||||
let c: [usize; 2] = [2, 3];
|
let c: [usize; 2] = [2, 3];
|
||||||
let _d: usize = c[1].clone();
|
let _d: usize = c[1].clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn manually_drop() {
|
||||||
|
use std::mem::ManuallyDrop;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
let a = ManuallyDrop::new(Arc::new("Hello!".to_owned()));
|
||||||
|
let _ = a.clone(); // OK
|
||||||
|
|
||||||
|
let p: *const String = Arc::into_raw(ManuallyDrop::into_inner(a));
|
||||||
|
unsafe {
|
||||||
|
Arc::from_raw(p);
|
||||||
|
Arc::from_raw(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -108,61 +108,61 @@ LL | let _t = tup.0.clone();
|
|||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
|
||||||
error: redundant clone
|
error: redundant clone
|
||||||
--> $DIR/redundant_clone.rs:61:22
|
--> $DIR/redundant_clone.rs:62:22
|
||||||
|
|
|
|
||||||
LL | (a.clone(), a.clone())
|
LL | (a.clone(), a.clone())
|
||||||
| ^^^^^^^^ help: remove this
|
| ^^^^^^^^ help: remove this
|
||||||
|
|
|
|
||||||
note: this value is dropped without further use
|
note: this value is dropped without further use
|
||||||
--> $DIR/redundant_clone.rs:61:21
|
--> $DIR/redundant_clone.rs:62:21
|
||||||
|
|
|
|
||||||
LL | (a.clone(), a.clone())
|
LL | (a.clone(), a.clone())
|
||||||
| ^
|
| ^
|
||||||
|
|
||||||
error: redundant clone
|
|
||||||
--> $DIR/redundant_clone.rs:121:15
|
|
||||||
|
|
|
||||||
LL | let _s = s.clone();
|
|
||||||
| ^^^^^^^^ help: remove this
|
|
||||||
|
|
|
||||||
note: this value is dropped without further use
|
|
||||||
--> $DIR/redundant_clone.rs:121:14
|
|
||||||
|
|
|
||||||
LL | let _s = s.clone();
|
|
||||||
| ^
|
|
||||||
|
|
||||||
error: redundant clone
|
error: redundant clone
|
||||||
--> $DIR/redundant_clone.rs:122:15
|
--> $DIR/redundant_clone.rs:122:15
|
||||||
|
|
|
|
||||||
LL | let _t = t.clone();
|
LL | let _s = s.clone();
|
||||||
| ^^^^^^^^ help: remove this
|
| ^^^^^^^^ help: remove this
|
||||||
|
|
|
|
||||||
note: this value is dropped without further use
|
note: this value is dropped without further use
|
||||||
--> $DIR/redundant_clone.rs:122:14
|
--> $DIR/redundant_clone.rs:122:14
|
||||||
|
|
|
|
||||||
|
LL | let _s = s.clone();
|
||||||
|
| ^
|
||||||
|
|
||||||
|
error: redundant clone
|
||||||
|
--> $DIR/redundant_clone.rs:123:15
|
||||||
|
|
|
||||||
|
LL | let _t = t.clone();
|
||||||
|
| ^^^^^^^^ help: remove this
|
||||||
|
|
|
||||||
|
note: this value is dropped without further use
|
||||||
|
--> $DIR/redundant_clone.rs:123:14
|
||||||
|
|
|
||||||
LL | let _t = t.clone();
|
LL | let _t = t.clone();
|
||||||
| ^
|
| ^
|
||||||
|
|
||||||
error: redundant clone
|
error: redundant clone
|
||||||
--> $DIR/redundant_clone.rs:132:19
|
--> $DIR/redundant_clone.rs:133:19
|
||||||
|
|
|
|
||||||
LL | let _f = f.clone();
|
LL | let _f = f.clone();
|
||||||
| ^^^^^^^^ help: remove this
|
| ^^^^^^^^ help: remove this
|
||||||
|
|
|
|
||||||
note: this value is dropped without further use
|
note: this value is dropped without further use
|
||||||
--> $DIR/redundant_clone.rs:132:18
|
--> $DIR/redundant_clone.rs:133:18
|
||||||
|
|
|
|
||||||
LL | let _f = f.clone();
|
LL | let _f = f.clone();
|
||||||
| ^
|
| ^
|
||||||
|
|
||||||
error: redundant clone
|
error: redundant clone
|
||||||
--> $DIR/redundant_clone.rs:144:14
|
--> $DIR/redundant_clone.rs:145:14
|
||||||
|
|
|
|
||||||
LL | let y = x.clone().join("matthias");
|
LL | let y = x.clone().join("matthias");
|
||||||
| ^^^^^^^^ help: remove this
|
| ^^^^^^^^ help: remove this
|
||||||
|
|
|
|
||||||
note: cloned value is neither consumed nor mutated
|
note: cloned value is neither consumed nor mutated
|
||||||
--> $DIR/redundant_clone.rs:144:13
|
--> $DIR/redundant_clone.rs:145:13
|
||||||
|
|
|
|
||||||
LL | let y = x.clone().join("matthias");
|
LL | let y = x.clone().join("matthias");
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
|
Loading…
Reference in New Issue
Block a user