Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to derive deserialize on generic type, where generic parameter is bounded by DeserializeOwned #1296

Closed
rphmeier opened this issue May 31, 2018 · 5 comments

Comments

@rphmeier
Copy link

The problem can be summed up in this code snippet:

extern crate serde;

#[macro_use]
extern crate serde_derive;

use serde::de::DeserializeOwned;

// without `DeserializeOwned`, this compiles. with it, it fails.
trait Foo: DeserializeOwned {}

#[derive(Deserialize)]
struct Bar<F: Foo> {
    inner: F,
}

fn main() {}

http://play.integer32.com/?gist=a0e9f556bdb6f5cbd8c6aedacf1a2e25&version=stable&mode=debug

@dtolnay
Copy link
Member

dtolnay commented May 31, 2018

I believe the error is a compiler bug: rust-lang/rust#41617. The workaround is to write Bar without a trait bound.

#[derive(Deserialize)]
struct Bar<F> {
    inner: F,
}

Also see c-struct-bounds, we typically want to avoid trait bounds on data structures anyway.

@rphmeier
Copy link
Author

rphmeier commented May 31, 2018

yes, generally I try to avoid them, but in my situation there isn't any easy workaround.

trait Foo {
    type A;
    type B;
}

struct Bar<F: Foo> {
    f: F,
    a: F::A,
    b: F::B,
}

The alternative is to use Bar<F, F::A, F::B> where F: Foo absolutely everywhere, which is a lot of unnecessary clutter

@dtolnay
Copy link
Member

dtolnay commented May 31, 2018

This may also work as a workaround:

#[derive(Deserialize)]
struct Bar<F: Foo> {
    #[serde(deserialize_with = "F::deserialize")]
    f: F,
    a: F::A,
    b: F::B,
}

@dtolnay
Copy link
Member

dtolnay commented Jun 2, 2018

Another workaround:

#[derive(Deserialize)]
struct Bar<F: Foo> {
    #[serde(bound = "")]
    f: F,
    a: F::A,
    b: F::B,
}

@dtolnay
Copy link
Member

dtolnay commented Jun 2, 2018

Closing because I don't think this is something we can fix in Serde. It will need to be fixed in the compiler: rust-lang/rust#41617

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

2 participants