bincode icon indicating copy to clipboard operation
bincode copied to clipboard

Lifetime bound error when deriving `Encode` and `Decode` with `v2.0.0-rc.3`

Open niklaslong opened this issue 1 year ago • 4 comments

Minified example:

use bincode::{Decode, Encode};

#[derive(Encode, Decode)]
struct Foo<B: Bar> {
    bar: Vec<B>,
}

trait Bar: Encode + Decode {}

Throws:

error[E0310]: the parameter type `B` may not live long enough
 --> src/main.rs:5:10
  |
5 | #[derive(Encode, Decode)]
  |          ^^^^^^ ...so that the type `B` will meet its required lifetime bounds
  |
  = note: this error originates in the derive macro `Encode` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider adding an explicit lifetime bound...
  |
6 | struct Foo<B: Bar + 'static> {
  |                   +++++++++

error[E0310]: the parameter type `B` may not live long enough
 --> src/main.rs:5:18
  |
5 | #[derive(Encode, Decode)]
  |                  ^^^^^^ ...so that the type `B` will meet its required lifetime bounds
  |
  = note: this error originates in the derive macro `Decode` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider adding an explicit lifetime bound...
  |
6 | struct Foo<B: Bar + 'static> {
  |                   +++++++++

For more information about this error, try `rustc --explain E0310`.
error: could not compile `pad` (bin "pad") due to 2 previous errors

I've managed to reproduce the same error when replacing Vec<B> with e.g. [B; 1], though the error is only thrown for Decode.

I don't yet know the codebase but could this be related to https://github.com/bincode-org/bincode/pull/635?

Thanks!

Edit: I've done a little further digging and it would seem that there is a 'static bound introduced by the use of TypeId for both [T; N] and Vec<T> (amongst a few others). Although it likely won't be an issue in a lot of cases, this might end up being impractical for types that might want to carry references?

niklaslong avatar Jun 09 '23 11:06 niklaslong

I have the same issue, specifically when deriving Encode on a struct that has a Vec with &'a str items.

Minimal reproducible example that does not compile using RC-3:

use bincode::Encode;

#[derive(Encode)]
struct MyStruct<'a> {
    vec_of_str: Vec<&'a str>,
}

Compilation error:

error[E0521]: borrowed data escapes outside of method
 --> src/lib.rs:3:10
  |
3 | #[derive(Encode)]
  |          ^^^^^^
  |          |
  |          `self` is a reference that is only valid in the method body
  |          `self` escapes the method body here
  |          lifetime `'a` defined here
  |          argument requires that `'a` must outlive `'static`
  |
  = note: this error originates in the derive macro `Encode` (in Nightly builds, run with -Z macro-backtrace for more info)

For more information about this error, try `rustc --explain E0521`.
error: could not compile `untitled8` (lib) due to previous error

stevenliebregt avatar Jun 22 '23 07:06 stevenliebregt

I am encountering the same problem. I tried a good bit of types, and I got that any simple slice is going to fail:

  • Vec<T<'a>>
  • Box<[T<'a>]>,Rc<[T<'a>]>,Arc<[T<'a>]>
  • &'s [T<'a>]

where T is covariant over 's all fails. This is not insolvable, given that both BTreeSet<T<'s>> and BTreeMap<T<'s>,_> works with no problem (and they contains a slice under the hood)

zannabianca1997 avatar Oct 28 '23 10:10 zannabianca1997

Have something similar: we have a newtype wrapping over a heapless::Vec<T, N> to be able to derive bincode on stucts containing it. I'm pretty sure that this used to work previously (version = "2.0.0-rc.2"), but now fails to compile: 😿

Update: does compile with the version from current trunk (73258a773595d9c0b8367f8a63968a1e8a528849). Issue seems to be fixed (in my case) from 08556caaa527ada2ae32cc847e2cafbeab9b30cb onwards.

code

#[derive(Clone, Debug, Default)]
#[repr(transparent)]
pub struct BincodeVec<T, const N: usize>(pub Vec<T, N>);
impl<T: Encode, const N: usize> Encode for BincodeVec<T, N> {
    fn encode<E: bincode::enc::Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
        self.0.as_slice().encode(encoder)
    }
}

compilation output

error[E0310]: the parameter type `T` may not live long enough
  --> src/appcfg/heapless_bincode.rs:53:9
   |
53 |         self.0.as_slice().encode(encoder)
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
   |
help: consider adding an explicit lifetime bound...
   |
51 | impl<T: Encode + 'static, const N: usize> Encode for BincodeVec<T, N> {
   |                +++++++++

eflukx avatar Nov 02 '23 09:11 eflukx

Update: does compile with the version from current trunk (https://github.com/bincode-org/bincode/commit/73258a773595d9c0b8367f8a63968a1e8a528849). Issue seems to be fixed (in my case) from https://github.com/bincode-org/bincode/commit/08556caaa527ada2ae32cc847e2cafbeab9b30cb onwards.

Very good, we're planning to do a new release candidate soon:tm: :+1:

VictorKoenders avatar Nov 03 '23 06:11 VictorKoenders