serde icon indicating copy to clipboard operation
serde copied to clipboard

Relax trait bounds for #[serde((try_)from/into = "..")]

Open whfuyn opened this issue 3 years ago • 3 comments

If the type has #[serde((try_)from/into = "..")] attributes, we don't need to add T: Serialize/T: Deserialize for the generics.

The following code will now compile. playground

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

use serde::Deserialize;
use serde::Serialize;

#[derive(Clone, Serialize, Deserialize)]
#[serde(from = "B")]
#[serde(into = "B")]
struct A<T: Clone> {
    value: T,
}

#[derive(Serialize, Deserialize)]
struct B;

impl<T: Clone> From<B> for A<T> {
    fn from(_: B) -> Self {
        todo!()
    }
}

impl<T: Clone> Into<B> for A<T> {
    fn into(self) -> B {
        todo!()
    }
}

fn has_serialize<U: Serialize>(_: U) {}
fn has_deserialize<'de, U: Deserialize<'de>>(_: U) {}

fn f<T: Clone>(s: A<T>) {
    has_serialize(s.clone());
    has_deserialize(s);
}

fn main() {}

This also makes the combination of #[serde(from = "..")] and #[serde(default)] compile, but that combination would be meaningless.

Fixes https://github.com/serde-rs/serde/issues/2178.

whfuyn avatar Jun 30 '22 15:06 whfuyn

Hi @whfuyn, thank you for writing the patch! I'm looking forward this to be merged. Is there any update?

algon-320 avatar Sep 04 '23 05:09 algon-320

Until this is merged, a quick fix is to create some dummy serialize_with and deserialize_with functions (playground link). The struct is still serialized/deserialized with the Into/From structs (which you can see in the macro expansion of the playground link), but the dummy serialize_with/desrialize_with functions make serde ignore the needless trait bounds.

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

use serde::{Deserialize, Deserializer};
use serde::{Serialize, Serializer};

#[derive(Clone, Serialize, Deserialize)]
#[serde(from = "B")]
#[serde(into = "B")]
struct A<T: Clone> {
    #[serde(serialize_with = "_dummy_ser", deserialize_with = "_dummy_de")]
    value: T,
}

fn _dummy_ser<T: Clone, S: Serializer>(_a: &A<T>, _s: S) -> Result<S::Ok, S::Error> {
    unreachable!()
}

fn _dummy_de<'de, T: Clone, D: Deserializer<'de>>(_d: D) -> Result<A<T>, D::Error> {
    unreachable!()
}

#[derive(Serialize, Deserialize)]
struct B;

impl<T: Clone> From<B> for A<T> {
    fn from(_: B) -> Self {
        todo!()
    }
}

impl<T: Clone> Into<B> for A<T> {
    fn into(self) -> B {
        todo!()
    }
}

fn has_serialize<U: Serialize>(_: U) {}
fn has_deserialize<'de, U: Deserialize<'de>>(_: U) {}

fn f<T: Clone>(s: A<T>) {
    has_serialize(s.clone());
    has_deserialize(s);
}

fn main() {}

wvietor avatar Mar 26 '24 16:03 wvietor

Hi @whfuyn, thank you for writing the patch! I'm looking forward this to be merged. Is there any update?

Sorry, I didn't see your reply until the new notification showed up. That's all the patch. I'm waiting for maintainers to review. Hi, @dtolnay , do you have time to review this PR?

whfuyn avatar Mar 27 '24 07:03 whfuyn