rust-clippy icon indicating copy to clipboard operation
rust-clippy copied to clipboard

`clone_double_ref` erroneously triggered when using `once_cell`'s `Lazy`

Open ndd7xv opened this issue 2 years ago • 2 comments

Summary

The code below triggers clone_double_ref, which makes Clippy state it can not compile. The compiler, however does not complain and successfully builds the program - some of Clippy's suggestions actually prevent the compiler from sucessfully building. Could it potentially have something to do with Lazy implementing Deref? Hovering over STRS when its highlighted in the code below presents:

Type:       Lazy<&str, fn() -> &str>
Coerced to:                    &&str

Lint Name

clone_double_ref

Reproducer

I tried this code:

use once_cell::sync::Lazy;

pub static STRS: Lazy<&str> = Lazy::new(|| "First");

fn main() {
    let str = STRS.clone();
    println!("{str}")
}

I saw this happen:

error: using `clone` on a double-reference; this will copy the reference of type `&str` instead of cloning the inner type
 --> src/main.rs:6:20
  |
6 |     println!("{}", STRS.clone());
  |                    ^^^^^^^^^^^^
  |
  = note: `#[deny(clippy::clone_double_ref)]` on by default
  = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#clone_double_ref
help: try dereferencing it
  |
6 |     println!("{}", &(*STRS).clone());
  |                    ~~~~~~~~~~~~~~~~
help: or try being explicit if you are sure, that you want to clone a reference
  |
6 |     println!("{}", <&str>::clone(STRS));
  |                    ~~~~~~~~~~~~~~~~~~~

error: could not compile `clippy-error` due to previous error

I expected to see this happen: Clippy shouldn't fail to compile, nor suggest alternatives that cause compiler errors. In the example above, <&str>::clone(STRS) would throw an error (though the compiler suggests a correct fix of borrowing STRS). In the case that Lazy contains an array, like

pub static STRS: Lazy<[&str; 2]> = Lazy::new(|| ["First", "Second"]);
...
let str = STRS[0].clone();

Clippy would fail to compile, and both suggestions would prevent cargo build from succeeding.

Version

rustc 1.62.0 (a8314ef7d 2022-06-27)
binary: rustc
commit-hash: a8314ef7d0ec7b75c336af2c9857bfaf43002bfc
commit-date: 2022-06-27
host: x86_64-unknown-linux-gnu
release: 1.62.0
LLVM version: 14.0.5

Additional Labels

@rustbot label +I-suggestion-causes-error

ndd7xv avatar Aug 01 '22 04:08 ndd7xv

The fix is not easy. In this case the suggestion should be to remove the .clone() call, but had Lazy implemented the Display trait this would have changed the code behaviour!

kraktus avatar Sep 17 '22 08:09 kraktus

A solution might be to ignore any cases where the Adjustments of the receiver contains a Deref

Alexendoo avatar Sep 17 '22 10:09 Alexendoo