-
Notifications
You must be signed in to change notification settings - Fork 38
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
Issue with lifetimes and Vec (lifetime may not live long enough requires that 'bar
must outlive 'static
)
#298
Comments
Thanks for your report! This lifetime issue exists within the generated |
@csnover The binrw/binrw/src/binwrite/impls.rs Lines 123 to 148 in 22d9a4d
which is a direct result of implementing fake-specialization for In order to remove the @lowlevl you can work around this by defining a different struct SlowVec<T>(pub Vec<T>);
impl<T> BinRead for SlowVec<T>
where
T: BinRead,
for<'a> T::Args<'a>: Clone,
{
type Args<'a> = binrw::binread::VecArgs<T::Args<'a>>;
fn read_options<R: Read + Seek>(
reader: &mut R,
endian: Endian,
args: Self::Args<'_>,
) -> BinResult<Self> {
Ok(SlowVec(core::iter::repeat_with(|| T::read_options(reader, endian, args.clone()))
.take(n)
.collect()?))
}
}
impl<T> BinWrite for SlowVec<T>
where
T: BinWrite,
for<'a> T::Args<'a>: Clone,
{
type Args<'a> = T::Args<'a>;
fn write_options<W: Write + Seek>(
&self,
writer: &mut W,
endian: Endian,
args: Self::Args<'_>,
) -> BinResult<()> {
for item in self.0 {
T::write_options(item, writer, endian, args.clone())?;
}
Ok(())
}
} and then using SlowVec instead of Vec where appropriate. |
In terms of moving away from this 'static requirement, https://users.rust-lang.org/t/emulate-specialization-in-stable-rust-with-macro-rules/74338/4 describes a way we could make this work. Essentially, we'd add a new marker trait (bikeshed name) |
Oh, I’ll look into that. Initially when you said that, I just thought about autoref specialisation. If there is no sign of stable specialisation on the horizon at some point I wonder if just changing to always require helpers for optimisations is a way to go, since these workarounds for missing language features are clever but they also seem to end up like evergreen footguns, and the workarounds for the workarounds get less cute. |
we could also avoid specialization by adding another method that reads/writes multiple items at once, which defaults to the naive method. Then, the Vec impl would forward to the read/write multiple method, which could be overridden on a per-type basis. on the other hand, if we go the route of removing the specialization-like optimization entirely, we should re-evaluate how we push people towards the helpers and/or bufreader. |
Hi there,
Upon rewriting some of my
binrw
-using code with lifetimes, I stumbled upon some interesting issue with what the macro generates aboutVec
and lifetimes, mainly that they seem incompatible, while the same struct without theVec
seems to compile fine.I managed to make a minimal reproduction of the issue.
So considering a struct
Zoo<'bar>
, defined as such:This snippet compiles fine, even with the
'bar
lifetime.But this one fails.
Here is the compiling error:
I started investigating the macro expansion, but unfortunately was unable to pinpoint an exact cause for this.
Let me know if you need any more context or help !
Thanks =)
The text was updated successfully, but these errors were encountered: