Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upSerde generates strange bounds on generics #938
Comments
This comment has been minimized.
This comment has been minimized.
|
We used to have that and it didn't work. IIRC there are two main reasons. Mutually recursive types#[derive(Serialize)]
struct A<T> {
b: Box<B<T>>,
}
// This generates an infinitely complicated bound.
#[derive(Serialize)]
struct B<T> {
a: Box<A<T>>,
}Private types// Not allowed to use private type in public trait bound.
#[derive(Serialize)]
pub struct Public<T> {
private: Private<T>,
}
#[derive(Serialize)]
struct Private<T> {
t: T,
} |
This comment has been minimized.
This comment has been minimized.
|
I would strongly discourage you from generating |
This comment has been minimized.
This comment has been minimized.
|
Thanks for explanation! The recursive case looks like something that can be fixed in the compiler although I'm not an expert. |
kryptan
closed this
May 19, 2017
This comment has been minimized.
This comment has been minimized.
|
Recursive where clauses may be fixed in the future. In that case heuristic in serde might be improved by assigning |
This comment has been minimized.
This comment has been minimized.
|
@kryptan that would have the unfortunate consequence of making it a potential breaking change to make a field public. That would be extremely surprising behavior. In the following code if I change the #[derive(Serialize)]
struct A<T> {
t: T,
#[serde(serialize_with = "f")]
b: B<T>,
}
// This type may be from a different crate.
struct B<T>(T);
fn f<T, S>(b: &B<T>, serializer: S) -> Result<S::Ok, S::Error>
where T: Serialize,
S: Serializer
{
unimplemented!()
} |
kryptan commentedMay 19, 2017
Given the following code:
serde generates the following bound:
where T: _serde::Serializewhile I would expect it to generatewhere B<T>: _serde::Serialize. Generated bound is wrong in some cases, e.g. ifBis implemented as follows:I'm currently writing my own custom-derive plugin for other purposes and I'm just putting the same bound on every field type. Serde, instead, uses some complex code to figure out what bounds to use and I'm curious why is it necessary.