Skip to content

Stable ordering when generating StructMeta code #1

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

Merged
merged 1 commit into from
Oct 18, 2021

Conversation

Fuuzetsu
Copy link
Contributor

@Fuuzetsu Fuuzetsu commented Oct 18, 2021

Currently, when user specifies derive(StructMeta), this crate
generates a branch of code for each of the attributes.

These attributes however have so far been stored inside a HashMap
which means the ordering of the branches is more or less random. This
has no real impact on the runtime: the order of the branches doesn't
change the semantics of the code. It does matter however for compile
time: rustc will calculate a different crate hash (effectively a sort
of ABI signature) if code is re-ordered.

This means that any time we recompile code with derive(StructMeta)
somewhere, we're breaking the ABI even if there were no changes at all
to any code. Basically, we're throwing a die at compile time as to what
order the code will be laid out in.

This is very bad for reproducability and plays very poorly with any sort
of binary caching.

I initially thought that the reproducability issue was coming from
rustc itself but the more I was debugging, I made my way back to this
crate.

You can see the original rustc issue for context
here.

I think this change should be basically invisible to anyone that's been
using the crate so far.

Currently, when user specifies `derive(StructMeta)`, this crate
generates a branch of code for each of the attributes.

These attributes however have so far been stored inside a `HashMap`
which means the ordering of the branches is more or less random. This
has no real impact on the runtime: the order of the branches doesn't
change the semantics of the code. It does matter however for compile
time: `rustc` will calculate a different crate hash (effectively a sort
of ABI signature) if code is re-ordered.

This means that any time we recompile code with `derive(StructMeta)`
somewhere, we're breaking the ABI even if there were _no_ changes at all
to any code. Basically, we're throwing a dice at compile time as to what
order the code will be laid out in.

This is very bad for reproducability and plays very poorly with any sort
of binary caching.

I initially thought that the reproducability issue was coming from
`rustc` itself but the more I was debugging, I made my way back to this
crate.

You can see the original rustc issue for context
[here](rust-lang/rust#89904).

I think this change should be basically invisible to anyone that's been
using the crate so far.
@Fuuzetsu
Copy link
Contributor Author

I have verified that with this patch if I now, in parse-display, do cargo clean followed by cargo build multiple times, I even get the same binary which is great. Previously, it was always giving different hashes.

If at all possible, a release to crates.io would be amazing, along with update to parse-display to use it as that's how we originally found the issue to start with.

@frozenlib
Copy link
Owner

Thanks for the excellent pull request.

I have now released structmeta 0.1.4 and parse-display 0.5.3 which contain this fix.

@Fuuzetsu
Copy link
Contributor Author

Thanks for the excellent pull request.

I have now released structmeta 0.1.4 and parse-display 0.5.3 which contain this fix.

Thank you for being so quick! We'll switch over to it ASAP, we've been using my branch temporarily.

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.

2 participants