Open
Description
Using the following flags
--force-warn clippy::clone-on-ref-ptr
this code:
use std::rc::{Rc, Weak};
use std::sync::atomic::AtomicU32;
use std::sync::atomic::Ordering;
fn main() {
let counter = AtomicU32::new(0);
let counter_ref = &counter;
let factorial = Rc::new_cyclic(move |rec| {
let rec = rec.clone() as Weak<dyn Fn(u32) -> u32>;
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
}
caused the following diagnostics:
Checking _snippet_204 v0.1.0 (/tmp/icemaker_global_tempdir.VQhomPU3g4RT/icemaker_clippyfix_tempdir.DOZq6ewCFF7h/_snippet_204)
warning: using `.clone()` on a ref-counted pointer
--> src/main.rs:9:19
|
9 | let rec = rec.clone() as Weak<dyn Fn(u32) -> u32>;
| ^^^^^^^^^^^ help: try: `Weak::<{closure@src/main.rs:10:9: 10:17}>::clone(&rec)`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#clone_on_ref_ptr
= note: requested on the command line with `--force-warn clippy::clone-on-ref-ptr`
warning: `_snippet_204` (bin "_snippet_204") generated 1 warning
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.13s
However after applying these diagnostics, the resulting code:
use std::rc::{Rc, Weak};
use std::sync::atomic::AtomicU32;
use std::sync::atomic::Ordering;
fn main() {
let counter = AtomicU32::new(0);
let counter_ref = &counter;
let factorial = Rc::new_cyclic(move |rec| {
let rec = Weak::<{closure@src/main.rs:10:9: 10:17}>::clone(&rec) as Weak<dyn Fn(u32) -> u32>;
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
}
no longer compiled:
Checking _snippet_204 v0.1.0 (/tmp/icemaker_global_tempdir.VQhomPU3g4RT/icemaker_clippyfix_tempdir.DOZq6ewCFF7h/_snippet_204)
error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `@`
--> src/main.rs:9:34
|
9 | let rec = Weak::<{closure@src/main.rs:10:9: 10:17}>::clone(&rec) as Weak<dyn Fn(u32) -> u32>;
| ^ expected one of 8 possible tokens
error[E0747]: constant provided when a type was expected
--> src/main.rs:9:26
|
9 | let rec = Weak::<{closure@src/main.rs:10:9: 10:17}>::clone(&rec) as Weak<dyn Fn(u32) -> u32>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
For more information about this error, try `rustc --explain E0747`.
error: could not compile `_snippet_204` (bin "_snippet_204") due to 2 previous errors
warning: build failed, waiting for other jobs to finish...
error: could not compile `_snippet_204` (bin "_snippet_204" test) due to 2 previous errors
Version:
rustc 1.89.0-nightly (44f415c1d 2025-06-06)
binary: rustc
commit-hash: 44f415c1d617ebc7b931a243b7b321ef8a6ca47c
commit-date: 2025-06-06
host: x86_64-unknown-linux-gnu
release: 1.89.0-nightly
LLVM version: 20.1.5