Open
Description
I tried this code (playground):
pub trait Ctx: Clone + Eq + Debug {
type Loc: Loc;
}
pub trait Accessible {
type Context<'a>: Ctx;
fn can_access<'a>(&self, ctx: &Self::Context<'a>) -> bool;
}
pub trait Id: Copy + Clone + Debug + Eq + Hash + Ord + PartialOrd {}
pub trait Loc: Accessible {
type LocId: Id;
}
// error
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub enum History<T>
where T: Ctx
{
Visit(<<T as Ctx>::Loc as Loc>::LocId),
Action(<<T as Ctx>::Loc as Loc>::LocId),
}
#[derive(Copy, Clone, Default, Eq, PartialEq)]
pub struct HSlice<'a, T>
where T: Ctx {
slice: &'a [History<T>],
}
impl<'a, T> Hash for HSlice<'a, T> where T: Ctx {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
(*self.slice).hash(state);
}
}
I expected either:
- code compiles (because
History<T>
implementsHash
and thus[History<T>]
implementsHash
) - a useful error message tells me to require
T: Hash
- some other useful suggestion
Instead, this happened:
rust suggests deriving Hash on History<T>
which has already done so.
error[E0599]: the method `hash` exists for slice `[History<T>]`, but its trait bounds were not satisfied
--> src/lib.rs:37:23
|
23 | pub enum History<T>
| ------------------- doesn't satisfy `History<T>: Hash`
...
37 | (*self.slice).hash(state);
| ^^^^ method cannot be called on `[History<T>]` due to unsatisfied trait bounds
|
= note: the following trait bounds were not satisfied:
`History<T>: Hash`
which is required by `[History<T>]: Hash`
help: consider annotating `History<T>` with `#[derive(Hash)]`
|
23 | #[derive(Hash)]
I've included in the playground link an alternate derivation of Hash
with the useful version of the error:
// Variant
#[derive(Copy, Clone, Default, Eq, PartialEq)]
pub struct VSlice<'a, T>
where T: Ctx {
slice: &'a [History<T>],
}
impl<'a, T> Hash for VSlice<'a, T> where T: Ctx {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.slice.iter().for_each(|v| v.hash(state));
}
}
error:
error[E0599]: the method `hash` exists for reference `&History<T>`, but its trait bounds were not satisfied
--> src/lib.rs:49:42
|
23 | pub enum History<T>
| ------------------- doesn't satisfy `History<T>: Hash`
...
49 | self.slice.iter().for_each(|v| v.hash(state));
| ^^^^ method cannot be called on `&History<T>` due to unsatisfied trait bounds
|
note: trait bound `T: Hash` was not satisfied
--> src/lib.rs:22:45
|
22 | #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
| ^^^^ unsatisfied trait bound introduced in this `derive` macro
= note: the following trait bounds were not satisfied:
`History<T>: Hash`
which is required by `&History<T>: Hash`
help: consider restricting the type parameter to satisfy the trait bound
|
24 | where T: Ctx, T: Hash
| +++++++++
help: consider annotating `History<T>` with `#[derive(Hash)]`
|
23 | #[derive(Hash)]
|
Metadata
Metadata
Assignees
Labels
Area: Messages for errors, warnings, and lintsArea: Suggestions generated by the compiler applied by `cargo fix`Category: This is a bug.Diagnostics: A diagnostic that is giving misleading or incorrect information.Diagnostics: A structured suggestion resulting in incorrect code.Relevant to the compiler team, which will review and decide on the PR/issue.