The trait `Deserialize<'_>` is not implemented for `&Foo<'_>`

Hello,
I'm trying to use nested struct references in serde.
But I'm struggling with lifetime implementation.
I would like to avoid String, Clone .. or any costly operation as much as possible.

use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize, Debug)]
struct Foo<'a> {
    tst: &'a str    
}

#[derive(Serialize, Deserialize, Debug)]
struct Bar<'a> {
    #[serde(bound(deserialize = "&'a Foo<'a>: Deserialize<'a>"))]
    foo: &'a Foo<'a>
}

fn to_fix<'a, T, Y>(tmp: T) -> Y
    where
    Y: Serialize,
    T: Deserialize<'a>
{
        todo!();
}

fn main() {
    let foo = Foo {
        tst: "hello world",
    };
    let bar = Bar{
        foo: &foo
    };
    let tmp: Bar = to_fix(bar);
}

but I'm getting the following compilation error:

Compiling playground v0.0.1 (/playground)
error[E0277]: the trait bound `&Foo<'_>: Deserialize<'_>` is not satisfied
  --> src/main.rs:29:27
   |
29 |     let tmp: Bar = to_fix(bar);
   |                    ------ ^^^ the trait `Deserialize<'_>` is not implemented for `&Foo<'_>`
   |                    |
   |                    required by a bound introduced by this call
   |
   = help: the trait `Deserialize<'de>` is implemented for `Foo<'a>`
note: required for `Bar<'_>` to implement `Deserialize<'_>`
  --> src/main.rs:8:21
   |
8  | #[derive(Serialize, Deserialize, Debug)]
   |                     ^^^^^^^^^^^
9  | struct Bar<'a> {
   |        ^^^^^^^
10 |     #[serde(bound(deserialize = "&'a Foo<'a>: Deserialize<'a>"))]
   |                                 ------------------------------ unsatisfied trait bound introduced in this `derive` macro
note: required by a bound in `to_fix`
  --> src/main.rs:17:8
   |
14 | fn to_fix<'a, T, Y>(tmp: T) -> Y
   |    ------ required by a bound in this
...
17 |     T: Deserialize<'a>
   |        ^^^^^^^^^^^^^^^ required by this bound in `to_fix`
   = note: this error originates in the derive macro `Deserialize` (in Nightly builds, run with -Z macro-backtrace for more info)

For more information about this error, try `rustc --explain E0277`.
error: could not compile `playground` due to previous error

Could you please help me to identify what's wrong with the to_fix function?

You can't deserialize into a reference (except for some very limited and very special cases). If you think about it, it's only logical – the deserializer has to create the deserialized data somewhere. Data always has to have an owner, it can't be only borrowed.

If you want to deserialize into your type, make it own (and not borrow) its fields.

1 Like

It makes a lot of sense.
thank you very very much for your help

Here's the fixed Playground. For deserializing strings, you can't in general avoid String.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.