blob: ede9d171517e7531b3781b4494d26a96cca6b012 [file] [log] [blame] [edit]
#![warn(clippy::clone_on_ref_ptr)]
use std::rc::{Rc, Weak as RcWeak};
use std::sync::{Arc, Weak as ArcWeak};
fn main() {}
fn clone_on_ref_ptr(rc: Rc<str>, rc_weak: RcWeak<str>, arc: Arc<str>, arc_weak: ArcWeak<str>) {
std::rc::Rc::<str>::clone(&rc);
//~^ clone_on_ref_ptr
std::rc::Weak::<str>::clone(&rc_weak);
//~^ clone_on_ref_ptr
std::sync::Arc::<str>::clone(&arc);
//~^ clone_on_ref_ptr
std::sync::Weak::<str>::clone(&arc_weak);
//~^ clone_on_ref_ptr
Rc::clone(&rc);
Arc::clone(&arc);
RcWeak::clone(&rc_weak);
ArcWeak::clone(&arc_weak);
}
trait SomeTrait {}
struct SomeImpl;
impl SomeTrait for SomeImpl {}
fn trait_object() {
let x = Arc::new(SomeImpl);
let _: Arc<dyn SomeTrait> = std::sync::Arc::<SomeImpl>::clone(&x);
//~^ clone_on_ref_ptr
}
mod issue2076 {
use std::rc::Rc;
macro_rules! try_opt {
($expr: expr) => {
match $expr {
Some(value) => value,
None => return None,
}
};
}
fn func() -> Option<Rc<u8>> {
let rc = Rc::new(42);
Some(std::rc::Rc::<u8>::clone(&try_opt!(Some(rc))))
//~^ clone_on_ref_ptr
}
}
#[allow(
clippy::needless_borrow,
reason = "the suggestion creates `Weak::clone(&rec)`, but `rec` is already a reference"
)]
mod issue15009 {
use std::rc::{Rc, Weak};
use std::sync::atomic::{AtomicU32, Ordering};
fn main() {
let counter = AtomicU32::new(0);
let counter_ref = &counter;
let factorial = Rc::new_cyclic(move |rec| {
let rec = std::rc::Weak::</* generic */>::clone(&rec) as Weak<dyn Fn(u32) -> u32>;
//~^ clone_on_ref_ptr
move |x| {
// can capture env
counter_ref.fetch_add(1, Ordering::Relaxed);
match x {
0 => 1,
x => x * rec.upgrade().unwrap()(x - 1),
}
}
});
println!("{}", factorial(5)); // 120
println!("{}", counter.load(Ordering::Relaxed)); // 6
println!("{}", factorial(7)); // 5040
println!("{}", counter.load(Ordering::Relaxed)); // 14
}
}