Broken diagnostic `trivial_casts` from Rust?
⚓ Rust 📅 2025-10-28 👤 surdeus 👁️ 2Apparently trivial_casts is not on by default, but it was turned on in the project I'm working on. However I'm wondering if it is broken:
use std::any::{Any, TypeId};
use std::hash::{DefaultHasher, Hash, Hasher};
trait DynKey: Any {
fn eq(&self, other: &dyn DynKey) -> bool;
fn hash(&self) -> u64;
fn type_name(&self) -> &'static str;
}
impl<T: Eq + Hash + 'static> DynKey for T {
#[warn(trivial_casts)]
fn eq(&self, other: &dyn DynKey) -> bool {
if let Some(other) = (other as &dyn Any).downcast_ref::<T>() {
return self == other;
}
false
}
fn hash(&self) -> u64 {
let mut h = DefaultHasher::new();
// mix the typeid of T into the hash to make distinct types
// provide distinct hashes
Hash::hash(&(TypeId::of::<T>(), self), &mut h);
h.finish()
}
fn type_name(&self) -> &'static str {
std::any::type_name::<T>()
}
}
(playground: Rust Playground)
gives the warning:
warning: trivial cast: `&(dyn DynKey + 'static)` as `&(dyn Any + 'static)`
--> src/lib.rs:13:30
|
13 | if let Some(other) = (other as &dyn Any).downcast_ref::<T>() {
| ^^^^^^^^^^^^^^^^^^^
|
= help: cast can be replaced by coercion; this might require a temporary variable
note: the lint level is defined here
Removing the cast doesn't work, as downcast_ref is then not found.
let other_any = other as &dyn Any;
if let Some(other) = other_any.downcast_ref::<T>() {
return self == other;
}
Just moves the warning to another line. And I don't really see how
let other_any: &dyn Any = other;
(which does work) is any cleaner to begin with. So it seems there is no reasonable way to solve this apart from allow? In general I do like this lint, it just seems to be rather incorrect in this case.
Is it worth filing an issue over this?
7 posts - 4 participants
🏷️ Rust_feed