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

Cannot derive Deserialize for a type that contains a type which contains a static reference #1712

Closed
shepmaster opened this issue Jan 10, 2020 · 3 comments

Comments

@shepmaster
Copy link
Contributor

use serde::Deserialize; // 1.0.104

#[derive(Deserialize)]
pub struct Foo(&'static str);

#[derive(Deserialize)]
pub struct Bar(Foo);
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'de` due to conflicting requirements
 --> src/lib.rs:7:16
  |
7 | pub struct Bar(Foo);
  |                ^^^
  |
note: first, the lifetime cannot outlive the lifetime `'de` as defined on the impl at 6:10...
 --> src/lib.rs:6:10
  |
6 | #[derive(Deserialize)]
  |          ^^^^^^^^^^^
  = note: ...so that the types are compatible:
          expected _IMPL_DESERIALIZE_FOR_Foo::_serde::Deserializer<'_>
             found _IMPL_DESERIALIZE_FOR_Foo::_serde::Deserializer<'de>
  = note: but, the lifetime must be valid for the static lifetime...
  = note: ...so that the types are compatible:
          expected _IMPL_DESERIALIZE_FOR_Foo::_serde::Deserialize<'_>
             found _IMPL_DESERIALIZE_FOR_Foo::_serde::Deserialize<'static>

error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'de` due to conflicting requirements
 --> src/lib.rs:7:16
  |
7 | pub struct Bar(Foo);
  |                ^^^
  |
note: first, the lifetime cannot outlive the lifetime `'de` as defined on the impl at 6:10...
 --> src/lib.rs:6:10
  |
6 | #[derive(Deserialize)]
  |          ^^^^^^^^^^^
  = note: ...so that the types are compatible:
          expected _IMPL_DESERIALIZE_FOR_Foo::_serde::de::SeqAccess<'_>
             found _IMPL_DESERIALIZE_FOR_Foo::_serde::de::SeqAccess<'de>
  = note: but, the lifetime must be valid for the static lifetime...
  = note: ...so that the types are compatible:
          expected _IMPL_DESERIALIZE_FOR_Foo::_serde::Deserialize<'_>
             found _IMPL_DESERIALIZE_FOR_Foo::_serde::Deserialize<'static>

Notably, #[serde(borrow)], as suggested by #1417, doesn't work:

use serde::Deserialize; // 1.0.104

#[derive(Deserialize)]
pub struct Foo(&'static str);

#[derive(Deserialize)]
pub struct Bar(#[serde(borrow = "'static")] Foo);
error: field `0` has no lifetimes to borrow
 --> src/lib.rs:7:16
  |
7 | pub struct Bar(#[serde(borrow = "'static")] Foo);
  |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Related, but seemingly different:

@dtolnay
Copy link
Member

dtolnay commented Jul 5, 2020

Foo's Deserialize impl looks like:

impl<'de> Deserialize<'de> for Foo
where
    'de: 'static

so that additional constraint would need to be provided on Bar's impl by a serde bound attribute.

use serde::Deserialize;

#[derive(Deserialize)]
pub struct Foo(&'static str);

#[derive(Deserialize)]
#[serde(bound(deserialize = "'de: 'static"))]
pub struct Bar(Foo);

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=c99fa29f3b2539cbba570eea4979d809

@dtolnay dtolnay closed this as completed Jul 5, 2020
@bblum
Copy link

bblum commented Aug 8, 2022

Sorry for thread necro, but I find that solution emits the warning "unnecessary lifetime parameter 'de ... you can use the 'static lifetime directly, in place of 'de".

Worse, due to rust-lang/rust#96956, the warning un-silenceable. Even #[allow(warnings)] doesn't work. Is there a way around this?

@LLFourn
Copy link

LLFourn commented Aug 16, 2022

@bblum if you are desperate for a quick fix you can do:

#[derive(Deserialize, Debug)]
pub struct Bar(
    #[serde(bound(deserialize = "Foo: Deserialize<'de>"))]
    Foo
);

toxeus pushed a commit to 21Analytics/lei that referenced this issue Jun 19, 2023
As mentioned in the code comment, the list of valid
registration authorities must be sorted, which
allows us to look for the index with binary search.
We ensure this with a unit-test.

An alternative that was explored was to have a
`&'static str` field. However, this leads to
problems for deserializer lifetimes, and the
workaround from [1] would need to be applied
to numerous types.

[1] serde-rs/serde#1712
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

4 participants