serde icon indicating copy to clipboard operation
serde copied to clipboard

`#[serde(try_from = "..")]` doesn't work with generic field

Open whfuyn opened this issue 3 years ago • 0 comments

The following code doesn't compile. Playground

extern crate serde; // 1.0.136
extern crate serde_derive; // 1.0.136

use serde::Deserialize;


#[derive(Deserialize)]
#[serde(try_from = "SS")]
struct S<T> {
    value: T,
}

#[derive(Deserialize)]
struct SS;

impl<T> TryFrom<SS> for S<T> {
    type Error = String;
    fn try_from(_: SS) -> Result<Self, Self::Error> {
        todo!()
    }
}

fn has_deserialize<'de, T: Deserialize<'de>>(_: T) {}

fn f<T>(s: S<T>) {
    has_deserialize(s);
}
Compiling playground v0.0.1 (/playground)
error[[E0277]](https://doc.rust-lang.org/stable/error-index.html#E0277): the trait bound `T: Deserialize<'_>` is not satisfied
  [--> src/lib.rs:26:21
](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=b18092dc590b23aef26f009db6e015e7#)   |
26 |     has_deserialize(s);
   |     --------------- ^ the trait `Deserialize<'_>` is not implemented for `T`
   |     |
   |     required by a bound introduced by this call
   |
note: required because of the requirements on the impl of `Deserialize<'_>` for `S<T>`
  [--> src/lib.rs:7:10
](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=b18092dc590b23aef26f009db6e015e7#)   |
7  | #[derive(Deserialize)]
   |          ^^^^^^^^^^^
8  | #[serde(try_from = "SS")]
9  | struct S<T> {
   |        ^^^^
note: required by a bound in `has_deserialize`
  [--> src/lib.rs:23:28
](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=b18092dc590b23aef26f009db6e015e7#)   |
23 | fn has_deserialize<'de, T: Deserialize<'de>>(_: T) {}
   |                            ^^^^^^^^^^^^^^^^ required by this bound in `has_deserialize`
   = note: this error originates in the derive macro `Deserialize` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider restricting type parameter `T`
   |
25 | fn f<T: serde::Deserialize<'_>>(s: S<T>) {
   |       ++++++++++++++++++++++++

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

It compiles when replaced with some !Deserialize concrete type. Playground

extern crate serde; // 1.0.136
extern crate serde_derive; // 1.0.136

use serde::Deserialize;

struct NoDeserialize;

#[derive(Deserialize)]
#[serde(try_from = "SS")]
struct S {
    value: NoDeserialize,
}

#[derive(Deserialize)]
struct SS;

impl TryFrom<SS> for S {
    type Error = String;
    fn try_from(_: SS) -> Result<Self, Self::Error> {
        todo!()
    }
}

fn has_deserialize<'de, T: Deserialize<'de>>(_: T) {}

fn f() {
    has_deserialize(S { value: NoDeserialize });
}

whfuyn avatar Feb 23 '22 07:02 whfuyn