virtue icon indicating copy to clipboard operation
virtue copied to clipboard

EnumVariant parsing can fail with empty delimiters

Open benluelo opened this issue 1 year ago • 0 comments

https://github.com/bincode-org/virtue/blob/1ecc01325a038c4f28aa8de25caae7c6eb91c66f/src/parse/body.rs#L210-L239

if a derive macro using virtue is applied to code generated by a macro_rules! macro, token trees are wrapped in an empty delimiter and this code fails:

macro_rules! wrapper_enum {
    (
        $(#[$meta:meta])*
        pub enum $Enum:ident {
            $(
                $(#[$inner_meta:meta])*
                $Variant:ident = $discriminant:literal,
            )+
        }
    ) => {
        $(#[$meta])*
        pub enum $Enum {
            $(
                $(#[$inner_meta])*
                $Variant = $discriminant,
            )+
        }
    };
}

wrapper_enum! {
    #[cfg_attr(feature = "bincode", derive(bincode::Encode, bincode::Decode))]
    pub enum HashOp {
        #[default]
        NoHash = 0,
        Sha256 = 1,
        Sha512 = 2,
        Keccak256 = 3,
        Ripemd160 = 4,
        Bitcoin = 5,
        Sha512256 = 6,
        Blake2b512 = 7,
        Blake2s256 = 8,
        Blake3 = 9,
    }
}
error: Invalid rust syntax, expected literal, got Some(Group { delimiter: None, stream: TokenStream [Literal { kind: Integer, symbol: "0", suffix: None, span: #0 bytes(129261..129262) }], span: #1458 bytes(276324..276337) })
   --> lib/unionlabs/src/macros.rs:282:28
    |
282 |                   $Variant = $discriminant,
    |                              ^^^^^^^^^^^^^
    |
   ::: lib/unionlabs/src/cosmos/ics23/hash_op.rs:3:1
    |
3   | / wrapper_enum! {
4   | |     #[model(proto(protos::cosmos::ics23::v1::HashOp))]
5   | |     #[derive(Default)]
6   | |     #[cfg_attr(feature = "bincode", derive(bincode::Encode, bincode::Decode))]
...   |
19  | |     }
20  | | }
    | |_- in this macro invocation
    |
    = note: this error originates in the macro `wrapper_enum` (in Nightly builds, run with -Z macro-backtrace for more info)

this can be solved in this case by changing $discriminant:literal to $discriminant:tt, but this may not always be possible.

benluelo avatar Jan 05 '25 15:01 benluelo