-
Notifications
You must be signed in to change notification settings - Fork 71
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
chore: optimize BorshSerialize
derive for enums with unit variants
#262
Merged
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Fuuzetsu
force-pushed
the
no-useless-enum-variants
branch
from
December 6, 2023 02:21
ed840a1
to
577506f
Compare
Given enums like these: ```rust enum Foo { A(u16), B, C(i32, i32), } enum Bar { A, B, C, } ``` serialise derive produces something like these: ```rust // Recursive expansion of borsh::BorshSerialize macro // =================================================== impl borsh::ser::BorshSerialize for Foo { fn serialize<W: borsh::io::Write>( &self, writer: &mut W, ) -> ::core::result::Result<(), borsh::io::Error> { let variant_idx: u8 = match self { Foo::A(..) => 0u8, Foo::B => 1u8, Foo::C(..) => 2u8, }; writer.write_all(&variant_idx.to_le_bytes())?; match self { Foo::A(id0) => { borsh::BorshSerialize::serialize(id0, writer)?; } Foo::B => {} Foo::C(id0, id1) => { borsh::BorshSerialize::serialize(id0, writer)?; borsh::BorshSerialize::serialize(id1, writer)?; } } Ok(()) } } // Recursive expansion of borsh::BorshSerialize macro // =================================================== impl borsh::ser::BorshSerialize for Bar { fn serialize<W: borsh::io::Write>( &self, writer: &mut W, ) -> ::core::result::Result<(), borsh::io::Error> { let variant_idx: u8 = match self { Bar::A => 0u8, Bar::B => 1u8, Bar::C => 2u8, }; writer.write_all(&variant_idx.to_le_bytes())?; match self { Bar::A => {} Bar::B => {} Bar::C => {} } Ok(()) } } ``` Notably in `Bar` case, the whole `match self` is useless because there's nothing left to serialise. With this patch, the derives now look like this: ```rust // Recursive expansion of borsh::BorshSerialize macro // =================================================== impl borsh::ser::BorshSerialize for Foo { fn serialize<W: borsh::io::Write>( &self, writer: &mut W, ) -> ::core::result::Result<(), borsh::io::Error> { let variant_idx: u8 = match self { Foo::A(..) => 0u8, Foo::B => 1u8, Foo::C(..) => 2u8, }; writer.write_all(&variant_idx.to_le_bytes())?; match self { Foo::A(id0) => { borsh::BorshSerialize::serialize(id0, writer)?; } Foo::C(id0, id1) => { borsh::BorshSerialize::serialize(id0, writer)?; borsh::BorshSerialize::serialize(id1, writer)?; } _ => {} } Ok(()) } } // Recursive expansion of borsh::BorshSerialize macro // =================================================== impl borsh::ser::BorshSerialize for Bar { fn serialize<W: borsh::io::Write>( &self, writer: &mut W, ) -> ::core::result::Result<(), borsh::io::Error> { let variant_idx: u8 = match self { Bar::A => 0u8, Bar::B => 1u8, Bar::C => 2u8, }; writer.write_all(&variant_idx.to_le_bytes())?; Ok(()) } } ``` Notably, the whole `match self` is gone for `Bar`. For `Foo`, any unit field cases are now inside a `_ => {}` catch-all. What's the point? Well, it's just nice to produce less for compiler to deal with, reducing upstream build times. Further, it makes it much nicer for anyone reading/copying the expanded macros. However patch this does add some amount of code complexity so it's up to the maintainers to decide if it's worth taking.
dj8yfo
changed the title
Do not produce useless match cases unit enums
chore: optimize Dec 6, 2023
BorshSerialize
derive for enums with unit variants
dj8yfo
force-pushed
the
no-useless-enum-variants
branch
from
December 6, 2023 17:57
577506f
to
0b7ecb0
Compare
dj8yfo
approved these changes
Dec 6, 2023
Merged
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Given enums like these:
serialise derive produces something like these:
Notably in
bar
case, the wholematch self
is useless because there's nothing left to serialise.With this patch, the derives now look like this:
Notably, the whole
match self
is gone forBar
. ForFoo
, any unit field cases are now inside a_ => {}
catch-all.What's the point? Well, it's just nice to produce less for compiler to deal with, reducing upstream build times. Further, it makes it much nicer for anyone reading/copying the expanded macros.
However patch this does add some amount of code complexity so it's up to the maintainers to decide if it's worth taking.