Skip to content

Implement (de)serialization for Box, Arc, and Rc, and serialization for references #48

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

progval
Copy link
Contributor

@progval progval commented Jul 22, 2025

We can't implement deserialization for references because something has to own them.

Unfortunately, we can't have a blanket impl for Deref:

error[E0119]: conflicting implementations of trait `traits::copy_type::CopyType` for type `[_; _]`
  --> epserde/src/impls/deref.rs:19:1
   |
19 | impl<T: Deref<Target: CopyType>> CopyType for T {
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `[_; _]`
   |
  ::: epserde/src/impls/array.rs:19:1
   |
19 | impl<T: CopyType, const N: usize> CopyType for [T; N] {
   | ----------------------------------------------------- first implementation here
   |
   = note: upstream crates may add a new impl of trait `std::ops::Deref` for type `[_; _]` in future versions

and also not for Borrow<_>:

error[E0119]: conflicting implementations of trait `traits::copy_type::CopyType` for type `[_; _]`
  --> epserde/src/impls/deref.rs:19:1
   |
19 | impl<Borrowed: CopyType, T: Borrow<Borrowed>> CopyType for T {
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `[_; _]`
   |
  ::: epserde/src/impls/array.rs:19:1
   |
19 | impl<T: CopyType, const N: usize> CopyType for [T; N] {
   | ----------------------------------------------------- first implementation here

error[E0207]: the type parameter `Borrowed` is not constrained by the impl trait, self type, or predicates
  --> epserde/src/impls/deref.rs:19:6
   |
19 | impl<Borrowed: CopyType, T: Borrow<Borrowed>> CopyType for T {
   |      ^^^^^^^^ unconstrained type parameter

…or references

We can't implement deserialization for references because something has
to own them.

Unfortunately, we can't have a blanket impl for `Deref`:

```
error[E0119]: conflicting implementations of trait `traits::copy_type::CopyType` for type `[_; _]`
  --> epserde/src/impls/deref.rs:19:1
   |
19 | impl<T: Deref<Target: CopyType>> CopyType for T {
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `[_; _]`
   |
  ::: epserde/src/impls/array.rs:19:1
   |
19 | impl<T: CopyType, const N: usize> CopyType for [T; N] {
   | ----------------------------------------------------- first implementation here
   |
   = note: upstream crates may add a new impl of trait `std::ops::Deref` for type `[_; _]` in future versions
```

and also not for `Borrow<_>`:

```
error[E0119]: conflicting implementations of trait `traits::copy_type::CopyType` for type `[_; _]`
  --> epserde/src/impls/deref.rs:19:1
   |
19 | impl<Borrowed: CopyType, T: Borrow<Borrowed>> CopyType for T {
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `[_; _]`
   |
  ::: epserde/src/impls/array.rs:19:1
   |
19 | impl<T: CopyType, const N: usize> CopyType for [T; N] {
   | ----------------------------------------------------- first implementation here

error[E0207]: the type parameter `Borrowed` is not constrained by the impl trait, self type, or predicates
  --> epserde/src/impls/deref.rs:19:6
   |
19 | impl<Borrowed: CopyType, T: Borrow<Borrowed>> CopyType for T {
   |      ^^^^^^^^ unconstrained type parameter
```
@progval
Copy link
Contributor Author

progval commented Jul 29, 2025

This doesn't work as well as I'd like. For example, this code:

use std::borrow::Borrow;
use std::marker::PhantomData;

use epserde::prelude::*;
use epserde::Epserde;

#[derive(Epserde)]
pub struct InnerStruct<T: AsRef<[u64]>> {
    data: T,
}

#[derive(Epserde)]
pub struct OuterStruct<T: AsRef<[u64]>, BorrowInner: Borrow<InnerStruct<T>>> {
    inner: BorrowInner,
    marker: PhantomData<T>,
}

fn main() {
    let original = OuterStruct {
        inner: InnerStruct {
            data: vec![1, 2, 3],
        },
        marker: PhantomData,
    };

    let mut file = std::io::Cursor::new(vec![]);
    original.serialize(&mut file).expect("Could not serialize");
    let data = file.into_inner();
    let deserialized = <OuterStruct<Vec<u64>, InnerStruct<Vec<u64>>>>::deserialize_eps(&data)
        .expect("Could not deserialize");
}

Should make it possible to serialize OuterStruct<Vec<u64>, &InnerStruct<Vec<u64>>>. But when I try to use it (even with the regular OuterStruct<Vec<u64>, InnerStruct<Vec<u64>>>), I get this:

   Compiling epserde v0.8.0 (/home/dev/epserde-rs/epserde)
error[E0599]: the function or associated item `deserialize_eps` exists for struct `OuterStruct<Vec<u64>, InnerStruct<Vec<u64>>>`, but its trait bounds were not satisfied
   --> epserde/examples/borrow.rs:29:72
    |
13  | pub struct OuterStruct<T: AsRef<[u64]>, BorrowInner: Borrow<InnerStruct<T>>> {
    | ---------------------------------------------------------------------------- function or associated item `deserialize_eps` not found for this struct because it doesn't satisfy `_: DeserializeInner` or `_: Deserialize`
...
29  |     let deserialized = <OuterStruct<Vec<u64>, InnerStruct<Vec<u64>>>>::deserialize_eps(&data)
    |                                                                        ^^^^^^^^^^^^^^^ function or associated item cannot be called on `OuterStruct<Vec<u64>, InnerStruct<Vec<u64>>>` due to unsatisfied trait bounds
    |
    = note: the following trait bounds were not satisfied:
            `OuterStruct<Vec<u64>, InnerStruct<Vec<u64>>>: epserde::deser::DeserializeInner`
            which is required by `OuterStruct<Vec<u64>, InnerStruct<Vec<u64>>>: epserde::deser::Deserialize`
            `&OuterStruct<Vec<u64>, InnerStruct<Vec<u64>>>: epserde::deser::DeserializeInner`
            which is required by `&OuterStruct<Vec<u64>, InnerStruct<Vec<u64>>>: epserde::deser::Deserialize`
            `&mut OuterStruct<Vec<u64>, InnerStruct<Vec<u64>>>: epserde::deser::DeserializeInner`
            which is required by `&mut OuterStruct<Vec<u64>, InnerStruct<Vec<u64>>>: epserde::deser::Deserialize`
note: the trait `epserde::deser::DeserializeInner` must be implemented
   --> /home/dev/epserde-rs/epserde/src/deser/mod.rs:264:1
    |
264 | pub trait DeserializeInner: Sized {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = help: items from traits can only be used if the trait is implemented and in scope
    = note: the following trait defines an item `deserialize_eps`, perhaps you need to implement it:
            candidate #1: `epserde::deser::Deserialize`

For more information about this error, try `rustc --explain E0599`.
error: could not compile `epserde` (example "borrow") due to 1 previous error

It's an improvement over what we got before this PR though:

   Compiling epserde v0.8.0 (/home/dev/epserde-rs/epserde)
error[E0599]: the function or associated item `deserialize_eps` exists for struct `OuterStruct<Vec<u64>, InnerStruct<Vec<u64>>>`, but its trait bounds were not satisfied
   --> epserde/examples/borrow.rs:29:72
    |
13  | pub struct OuterStruct<T: AsRef<[u64]>, BorrowInner: Borrow<InnerStruct<T>>> {
    | ---------------------------------------------------------------------------- function or associated item `deserialize_eps` not found for this struct because it doesn't satisfy `_: DeserializeInner` or `_: Deserialize`
...
29  |     let deserialized = <OuterStruct<Vec<u64>, InnerStruct<Vec<u64>>>>::deserialize_eps(&data)
    |                                                                        ^^^^^^^^^^^^^^^ function or associated item cannot be called on `OuterStruct<Vec<u64>, InnerStruct<Vec<u64>>>` due to unsatisfied trait bounds
    |
    = note: the following trait bounds were not satisfied:
            `OuterStruct<Vec<u64>, InnerStruct<Vec<u64>>>: epserde::deser::DeserializeInner`
            which is required by `OuterStruct<Vec<u64>, InnerStruct<Vec<u64>>>: epserde::deser::Deserialize`
            `&OuterStruct<Vec<u64>, InnerStruct<Vec<u64>>>: TypeHash`
            which is required by `&OuterStruct<Vec<u64>, InnerStruct<Vec<u64>>>: epserde::deser::Deserialize`
            `&OuterStruct<Vec<u64>, InnerStruct<Vec<u64>>>: AlignHash`
            which is required by `&OuterStruct<Vec<u64>, InnerStruct<Vec<u64>>>: epserde::deser::Deserialize`
            `&OuterStruct<Vec<u64>, InnerStruct<Vec<u64>>>: epserde::deser::DeserializeInner`
            which is required by `&OuterStruct<Vec<u64>, InnerStruct<Vec<u64>>>: epserde::deser::Deserialize`
            `&mut OuterStruct<Vec<u64>, InnerStruct<Vec<u64>>>: TypeHash`
            which is required by `&mut OuterStruct<Vec<u64>, InnerStruct<Vec<u64>>>: epserde::deser::Deserialize`
            `&mut OuterStruct<Vec<u64>, InnerStruct<Vec<u64>>>: AlignHash`
            which is required by `&mut OuterStruct<Vec<u64>, InnerStruct<Vec<u64>>>: epserde::deser::Deserialize`
            `&mut OuterStruct<Vec<u64>, InnerStruct<Vec<u64>>>: epserde::deser::DeserializeInner`
            which is required by `&mut OuterStruct<Vec<u64>, InnerStruct<Vec<u64>>>: epserde::deser::Deserialize`
note: the trait `epserde::deser::DeserializeInner` must be implemented
   --> /home/dev/epserde-rs/epserde/src/deser/mod.rs:264:1
    |
264 | pub trait DeserializeInner: Sized {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = help: items from traits can only be used if the trait is implemented and in scope
    = note: the following trait defines an item `deserialize_eps`, perhaps you need to implement it:
            candidate #1: `epserde::deser::Deserialize`

For more information about this error, try `rustc --explain E0599`.
error: could not compile `epserde` (example "borrow") due to 1 previous error

but still not enough.

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

Successfully merging this pull request may close these issues.

1 participant