Robbepop / modular-bitfield

Macro to generate bitfields for structs that allow for modular use of enums.
Apache License 2.0
159 stars 41 forks source link

Bitfield Specifier enum cannot have a variant called "In" #18

Closed Qyriad closed 4 years ago

Qyriad commented 4 years ago
// src/lib.rs
use modular_bitfield::prelude::*;

#[derive(BitfieldSpecifier)]
enum Fails {
    Foo = 0,
    Bar = 1,
    In = 2,
    Out = 3
}
$ rustc --version
rustc 1.46.0 (04488afe3 2020-08-24)
$ cargo build
   Compiling example v0.1.0 (/tmp/example)
error: expected pattern, found keyword `in`
 --> src/lib.rs:3:10
  |
3 | #[derive(BitfieldSpecifier)]
  |          ^^^^^^^^^^^^^^^^^ expected pattern
  |
  = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: proc-macro derive produced unparseable tokens
 --> src/lib.rs:3:10
  |
3 | #[derive(BitfieldSpecifier)]
  |          ^^^^^^^^^^^^^^^^^

error: aborting due to 2 previous errors

error: could not compile `example`.
$ rustc --version
rustc 1.48.0-nightly (d006f5734 2020-08-28)
$ RUSTFLAGS='-Z macro-backtrace' cargo build
   Compiling example v0.1.0 (/tmp/example)
error: expected pattern, found keyword `in`
   --> src/lib.rs:3:10
    |
3   |   #[derive(BitfieldSpecifier)]
    |            ^^^^^^^^^^^^^^^^^
    |            |
    |            expected pattern
    |            in this macro invocation
    |
   ::: /home/qyriad/.local/share/cargo/registry/src/github.com-1ecc6299db9ec823/modular-bitfield-impl-0.6.0/src/lib.rs:98:1
    |
98  | / pub fn bitfield_specifier(input: TokenStream) -> TokenStream {
99  | |     bitfield_specifier::generate(input.into()).into()
100 | | }
    | |_- in this expansion of `#[derive(BitfieldSpecifier)]`

error: proc-macro derive produced unparseable tokens
 --> src/lib.rs:3:10
  |
3 | #[derive(BitfieldSpecifier)]
  |          ^^^^^^^^^^^^^^^^^

error: aborting due to 2 previous errors

error: could not compile `example`.

This happens if it's typed as In or IN, but r#in and most curiously iN do work (but r#In and r#IN do not).

Robbepop commented 4 years ago

thank you for the bug report! sounds like the code generation could be a bit more fault tolerant in this case.

Qyriad commented 4 years ago

Okay, so I should have tested this further before submitting, but this error seems to happen with any strict keyword, which is making me think this might be somewhat related to rust-lang/rust#60524, in which case this is an upstream issue. What I don't understand is the effect capitalization has on it. For another example with more characters, Super, r#super, and SUPER do not compile, but SUper, SuPer, sUper, et cetera do.

Robbepop commented 4 years ago

Okay, so I should have tested this further before submitting, but this error seems to happen with any strict keyword, which is making me think this might be somewhat related to rust-lang/rust#60524, in which case this is an upstream issue. What I don't understand is the effect capitalization has on it. For another example with more characters, Super, r#super, and SUPER do not compile, but SUper, SuPer, sUper, et cetera do.

Thanks for the additional research and information. That is actually r#super strange and you might be right that this is in fact an upstream issue to fix.

Qyriad commented 4 years ago

Basing off that upstream issue's example code:

macro_rules! m {
    ($e:expr) => { "expr" };
}
m!(for) // Does not compile
m!(For) // Compiles

Which is making me think that this is related, but still fixable or work-around-able in this repo. I am very Not Familiar with writing procedural macros (or any Rust macros), but given that, I'm wondering if the to_snake_case() here might be the culprit.

Robbepop commented 4 years ago

I have not yet taken a proper look into the codebase but your link to the snake_case method might actually be the key. I will happily accept a PR. However, note that you will probably need to allow some warnings that might be popping up (not sure, just compile and see if there is going to be a warning).