lazy-static.rs
lazy-static.rs copied to clipboard
Unable to provide a Clippy suppression attribute for a variable's type
Consider the following example:
use http::Uri;
use std::collections::HashSet;
use lazy_static::lazy_static;
fn main() {
// Clippy thinks that `Uri` has interior mutability and yields a warning
let _a: HashSet<Uri> = HashSet::new();
// Warning is suppressed
#[allow(clippy::mutable_key_type)]
let _b: HashSet<Uri> = HashSet::new();
}
lazy_static! {
// Trying to suppress the warning
#[allow(clippy::mutable_key_type)]
static ref _C: HashSet<Uri> = HashSet::new();
}
if I run clippy on it, I get:
Checking playground v0.0.1 (/playground)
warning: mutable key type
--> src/main.rs:7:5
|
7 | let _a: HashSet<Uri> = HashSet::new();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(clippy::mutable_key_type)]` on by default
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#mutable_key_type
warning: mutable key type
--> src/main.rs:16:20
|
16 | static ref _C: HashSet<Uri> = HashSet::new();
| ^^^^^^^^^^^^
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#mutable_key_type
warning: mutable key type
--> src/main.rs:13:1
|
13 | / lazy_static! {
14 | | // Trying to suppress the warning
15 | | #[allow(clippy::mutable_key_type)]
16 | | static ref _C: HashSet<Uri> = HashSet::new();
17 | | }
| |_^
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#mutable_key_type
= note: this warning originates in the macro `__lazy_static_internal` (in Nightly builds, run with -Z macro-backtrace for more info)
warning: `playground` (bin "playground") generated 3 warnings
Finished dev [unoptimized + debuginfo] target(s) in 0.43s
So, the warning is not suppressed on _a
and is suppressed on _b
as expected. However, the attribute on _C
does nothing. Moreover, two warnings are yielded, not just one.
Looking at the expansion (courtesy of IntelliJ's Rust plugin, so may be off):
#[allow(missing_copy_implementations)]
#[allow(non_camel_case_types)]
#[allow(dead_code)]
#[allow(clippy::mutable_key_type)]
struct _C {
__private_field: (),
}
#[doc(hidden)]
static _C: _C = _C { __private_field: () };
impl ::lazy_static::__Deref for _C {
type Target = HashSet<Uri>;
fn deref(&self) -> &HashSet<Uri> {
#[inline(always)]
fn __static_ref_initialize() -> HashSet<Uri> { (HashSet::new()) }
#[inline(always)]
fn __stability() -> &'static HashSet<Uri> {
static LAZY: ::lazy_static::lazy::Lazy<HashSet<Uri>> = ::lazy_static::lazy::Lazy::INIT;
LAZY.get(__static_ref_initialize)
}
__stability()
}
}
impl ::lazy_static::LazyStatic for _C {
fn initialize(lazy: &Self) {
let _ = &**lazy;
}
}
It seems that the attribute is attached to the struct _C
, but warnings are actually emitted by some code in the macro. I'm not really sure what is the proper fix here: I suspect some attribute should really go to the struct _C
, some should go to the static _C
, and some (like allow(clippy::mutable_key_type)
should be scattered in the macro.