Suggest derive(Trait)
or T: Trait
from transitive obligation in some cases by estebank · Pull Request #127997 · rust-lang/rust (original) (raw)
With code like the following
#[derive(Clone)] struct Ctx { a_map: HashMap<String, B>, }
#[derive(Clone)] struct B { a: A, }
the derived trait will have an implicit restriction on A: Clone
for both types.
When referenced as follows:
fn foo(ctx: &mut Ctx) { let a_map = ctx.a_map.clone(); //~ ERROR E0599 }
suggest constraining Z
:
error[E0599]: the method `clone` exists for struct `HashMap<String, B<Z>>`, but its trait bounds were not satisfied
--> $DIR/type-or-type-param-missing-transitive-trait-contraint.rs:16:27
|
LL | struct B<A> {
| ----------- doesn't satisfy `B<Z>: Clone`
...
LL | let a_map = ctx.a_map.clone();
| ^^^^^ method cannot be called on `HashMap<String, B<Z>>` due to unsatisfied trait bounds
|
= note: the following trait bounds were not satisfied:
`B<Z>: Clone`
which is required by `HashMap<String, B<Z>>: Clone`
help: consider restricting type parameter `Z`
|
LL | fn foo<Z: std::clone::Clone>(ctx: &mut Ctx<Z>) {
| +++++++++++++++++++
When referenced as follows, with a specific type S
:
struct S;
fn bar(ctx: &mut Ctx) {
let a_map = ctx.a_map.clone(); //~ ERROR E0599
}
suggest derive
ing the appropriate trait on the local type:
error[E0599]: the method `clone` exists for struct `HashMap<String, B<S>>`, but its trait bounds were not satisfied
--> $DIR/type-or-type-param-missing-transitive-trait-contraint.rs:21:27
|
LL | struct B<A> {
| ----------- doesn't satisfy `B<S>: Clone`
...
LL | let a_map = ctx.a_map.clone();
| ^^^^^ method cannot be called on `HashMap<String, B<S>>` due to unsatisfied trait bounds
|
= note: the following trait bounds were not satisfied:
`B<S>: Clone`
which is required by `HashMap<String, B<S>>: Clone`
help: consider annotating `S` with `#[derive(Clone)]`
|
LL + #[derive(Clone)]
LL | struct S;
|
Given
use std::fmt::Debug; use std::hash::Hash; 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 where T: Ctx { Visit(<::Loc as Loc>::LocId), Action(<::Loc as Loc>::LocId), }
#[derive(Copy, Clone, Default, Eq, PartialEq)] pub struct HSlice<'a, T> where T: Ctx { slice: &'a [History], } 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); } }
we emit
error[E0599]: the method `hash` exists for slice `[History<T>]`, but its trait bounds were not satisfied
--> f1000.rs:34:23
|
20 | pub enum History<T>
| ------------------- doesn't satisfy `History<T>: Hash`
...
34 | (*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 further restricting this bound
|
32 | impl<'a, T> Hash for HSlice<'a, T> where T: Ctx + std::hash::Hash {
| +++++++++++++++++