I can't get the following code to work (playground: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=4379c2006dcf3d32f59b0e44626ca667).
use serde::{Serialize, Deserialize};
trait InnerStruct<'delife>: Deserialize<'delife> + Serialize {}
#[derive(Serialize, Deserialize)]
struct InnerStructA{
a: i32
}
impl InnerStruct<'_> for InnerStructA {}
#[derive(Serialize, Deserialize)]
struct InnerStructB{
a: i32,
b: i32
}
impl InnerStruct<'_> for InnerStructB {}
#[derive(Serialize, Deserialize)]
struct OuterStruct<T: InnerStruct>{ // Remove the word "InnerStruct" and this works
c: f64,
inner: T
}
fn print_json<T: for<'a> InnerStruct<'a>>(obj: T) {
println!("Serde JSON: {:?}", serde_json::to_string(&obj).unwrap());
}
fn main() {
let inner_a = InnerStructA{a: 123};
let inner_b = InnerStructB{a: 234, b: 567};
println!("Serde JSON: {:?}", serde_json::to_string(&inner_a).unwrap());
println!("Serde JSON: {:?}", serde_json::to_string(&inner_b).unwrap());
print_json(inner_a);
print_json(inner_b);
}
I have a collection of structs that are serializable (InnerStructA, InnerStructA), and they all implement a trait. Some functions are generic across a trait that unified them (InnerStruct). Some of these functions require that they are serializable and deserializable, so I've added Deserialize and Serialize supertraits to the trait definition. Deserialize required adding a named lifetime.
I now want an OuterStruct that is a generic container that could hold any type of inner struct. It works fine if I don't apply any trait bounds, but when I try to apply a trait bound to say this struct is only valid for T being InnerStruct everything breaks. The compiler messages talk about lifetimes, but none of the suggestions work.
A concrete example: For
struct OuterStruct<T: InnerStruct> {
the compiler suggests to
help: consider introducing a named lifetime parameter
|
23 | struct OuterStruct<'a, T: InnerStruct<'a>> {
but doing so leads to another error
error[E0392]: parameter `'a` is never used
--> src/main.rs:23:20
|
23 | struct OuterStruct<'a, T: InnerStruct<'a>> {
| ^^ unused parameter
What am I doing wrong?
Edit: DeserializeOwned If the trait is changed to DeserializedOwned then the lifetime issues go away, but the problem remains. It appears to be something to do with applying the derive(Deserialize) to the OuterStruct which already contains something that has had derive(Deserialize) applied to it. The error message is:
note: multiple `impl`s or `where` clauses satisfying `T: Deserialize<'_>` found