Open
Description
Summary
This just triggered in the Rust repo and I think that's a false positive.
As I think this is significant, I moved this lint to nursery
in the Clippy->Rust sync.
Added in #14812
cc @Ralith @llogiq
Lint Name
coerce_container_to_any
Reproducer
I tried this code:
let stepcache: &mut HashMap<S, <S as Step>::Output> = cache // RefMut<'_, HashMap<TypeId, …>>
.entry(key: type_id) // Entry<'_, TypeId, Box<dyn Any + 'static>>
.or_insert_with(default: || Box::<HashMap<S, S::Output>>::default()) // &mut Box<dyn Any + 'static>
.downcast_mut::<HashMap<S, S::Output>>() // Option<&mut HashMap<S, <S as Step>::Output>>
.expect(msg: "invalid type mapped");
I saw this happen:
warning: coercing `&mut std::boxed::Box<dyn std::any::Any>` to `&dyn Any`
--> src/bootstrap/src/utils/cache.rs:231:25
|
231 | let stepcache = cache
| _________________________^
232 | | .entry(type_id)
233 | | .or_insert_with(|| Box::<HashMap<S, S::Output>>::default())
| |_______________________________________________________________________^
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#coerce_container_to_any
= note: `-D clippy::coerce-container-to-any` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::coerce_container_to_any)]`
help: consider dereferencing
|
231 | let stepcache = &**cache
| +++
I expected to see this happen: no lint. In a method chain the actual type is &mut Box<dyn Any>
. Calling downcast_mut
on that type will go through the Deref
implementations and then call downcast_mut
on the actual dyn Any
. The Box
is not converted into a &dyn Any
reference.
Also the suggestion is wrong, as adding the derefs like shown in the suggestion, it would apply to the whole method chain, not to the offending code only. This is the correct "fix":
let stepcache: &mut HashMap<S, <S as Step>::Output> =
(**cache.entry(key: type_id).or_insert_with(default: || Box::<HashMap<S, S::Output>>::default())) // dyn Any + 'static
.downcast_mut::<HashMap<S, S::Output>>() // Option<&mut HashMap<S, <S as Step>::Output>>
.expect(msg: "invalid type mapped");
Version
Current master: 4ef75291b5dd6739212f1f61666d19d4e086690d
Additional Labels
No response