Skip to content

clone-on-ref-ptr type suggestion in case of closure is not applicable #15009

Open
@matthiaskrgr

Description

@matthiaskrgr

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    I-suggestion-causes-errorIssue: The suggestions provided by this Lint cause an ICE/error when applied

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions