Repository: bitflags/bitflags
Pull request #235 (2020-12-27 13:35:32)

Allow multiple bitflags structs in one macro invocation
Add support for multiple bitflags structs in one macro invocation, for example:

```rust
bitflags! {
    pub struct Flags1: u32 {
        const A = 0b00000001;
    }

    struct Flags2: u32 {
        const B = 0b00000010;
    }
}
```

I also updated the documentation, replaced mentions of the `flags` keyword (which was used before 0.9) with `struct` and ran `cargo fmt`.


Patch:
diff --git a/build.rs b/build.rs
index 985757a..67abc09 100644
--- a/build.rs
+++ b/build.rs
@@ -2,7 +2,7 @@ use std::env;
 use std::process::Command;
 use std::str::{self, FromStr};
 
-fn main(){
+fn main() {
     let minor = match rustc_minor_version() {
         Some(minor) => minor,
         None => return,
@@ -41,4 +41,4 @@ fn rustc_minor_version() -> Option<u32> {
     };
 
     u32::from_str(next).ok()
-}
\ No newline at end of file
+}
diff --git a/src/lib.rs b/src/lib.rs
index 55daa5e..906ec98 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -11,7 +11,7 @@
 //! A typesafe bitmask flag generator useful for sets of C-style bitmask flags.
 //! It can be used for creating typesafe wrappers around C APIs.
 //!
-//! The `bitflags!` macro generates a `struct` that manages a set of flags. The
+//! The `bitflags!` macro generates `struct`s that manage a set of flags. The
 //! flags should only be defined for integer types, otherwise unexpected type
 //! errors may occur at compile time.
 //!
@@ -84,9 +84,9 @@
 //!
 //! # Visibility
 //!
-//! The generated struct and its associated flag constants are not exported
+//! The generated structs and their associated flag constants are not exported
 //! out of the current module by default. A definition can be exported out of
-//! the current module by adding `pub` before `flags`:
+//! the current module by adding `pub` before `struct`:
 //!
 //! ```
 //! #[macro_use]
@@ -97,8 +97,7 @@
 //!         pub struct Flags1: u32 {
 //!             const A = 0b00000001;
 //!         }
-//!     }
-//!     bitflags! {
+//!
 //! #       pub
 //!         struct Flags2: u32 {
 //!             const B = 0b00000010;
@@ -114,26 +113,26 @@
 //!
 //! # Attributes
 //!
-//! Attributes can be attached to the generated `struct` by placing them
-//! before the `flags` keyword.
+//! Attributes can be attached to the generated `struct`s by placing them
+//! before the `struct` keyword.
 //!
 //! # Trait implementations
 //!
 //! The `Copy`, `Clone`, `PartialEq`, `Eq`, `PartialOrd`, `Ord` and `Hash`
-//! traits automatically derived for the `struct` using the `derive` attribute.
+//! traits are automatically derived for the `struct`s using the `derive` attribute.
 //! Additional traits can be derived by providing an explicit `derive`
-//! attribute on `flags`.
+//! attribute on `struct`.
 //!
-//! The `Extend` and `FromIterator` traits are implemented for the `struct`,
+//! The `Extend` and `FromIterator` traits are implemented for the `struct`s,
 //! too: `Extend` adds the union of the instances of the `struct` iterated over,
 //! while `FromIterator` calculates the union.
 //!
-//! The `Binary`, `Debug`, `LowerHex`, `Octal` and `UpperHex` trait is also
+//! The `Binary`, `Debug`, `LowerHex`, `Octal` and `UpperHex` traits are also
 //! implemented by displaying the bits value of the internal struct.
 //!
 //! ## Operators
 //!
-//! The following operator traits are implemented for the generated `struct`:
+//! The following operator traits are implemented for the generated `struct`s:
 //!
 //! - `BitOr` and `BitOrAssign`: union
 //! - `BitAnd` and `BitAndAssign`: intersection
@@ -143,7 +142,7 @@
 //!
 //! # Methods
 //!
-//! The following methods are defined for the generated `struct`:
+//! The following methods are defined for the generated `struct`s:
 //!
 //! - `empty`: an empty set of flags
 //! - `all`: the set of all defined flags
@@ -168,7 +167,7 @@
 //!
 //! ## Default
 //!
-//! The `Default` trait is not automatically implemented for the generated struct.
+//! The `Default` trait is not automatically implemented for the generated structs.
 //!
 //! If your default value is equal to `0` (which is the same value as calling `empty()`
 //! on the generated struct), you can simply derive `Default`:
@@ -262,7 +261,7 @@ extern crate std;
 #[doc(hidden)]
 pub extern crate core as _core;
 
-/// The macro used to generate the flag structure.
+/// The macro used to generate the flag structures.
 ///
 /// See the [crate level docs](../bitflags/index.html) for complete documentation.
 ///
@@ -339,6 +338,7 @@ macro_rules! bitflags {
                 const $Flag:ident = $value:expr;
             )+
         }
+        $($t:tt)*
     ) => {
         __bitflags! {
             $(#[$outer])*
@@ -349,6 +349,10 @@ macro_rules! bitflags {
                 )+
             }
         }
+
+        bitflags! {
+            $($t)*
+        }
     };
     (
         $(#[$outer:meta])*
@@ -358,6 +362,7 @@ macro_rules! bitflags {
                 const $Flag:ident = $value:expr;
             )+
         }
+        $($t:tt)*
     ) => {
         __bitflags! {
             $(#[$outer])*
@@ -368,6 +373,10 @@ macro_rules! bitflags {
                 )+
             }
         }
+
+        bitflags! {
+            $($t)*
+        }
     };
     (
         $(#[$outer:meta])*
@@ -377,6 +386,7 @@ macro_rules! bitflags {
                 const $Flag:ident = $value:expr;
             )+
         }
+        $($t:tt)*
     ) => {
         __bitflags! {
             $(#[$outer])*
@@ -387,7 +397,12 @@ macro_rules! bitflags {
                 )+
             }
         }
+
+        bitflags! {
+            $($t)*
+        }
     };
+    () => {};
 }
 
 #[macro_export(local_inner_macros)]
@@ -958,9 +973,7 @@ mod tests {
             #[doc = "<strcat> wait what?"]
             const ABC = Self::A.bits | Self::B.bits | Self::C.bits;
         }
-    }
 
-    bitflags! {
         struct _CfgFlags: u32 {
             #[cfg(unix)]
             const _CFG_A = 0b01;
@@ -969,15 +982,11 @@ mod tests {
             #[cfg(unix)]
             const _CFG_C = Self::_CFG_A.bits | 0b10;
         }
-    }
 
-    bitflags! {
         struct AnotherSetOfFlags: i8 {
             const ANOTHER_FLAG = -1_i8;
         }
-    }
 
-    bitflags! {
         struct LongFlags: u32 {
             const LONG_A = 0b1111111111111111;
         }
@@ -1028,9 +1037,18 @@ mod tests {
         assert_eq!(unsafe { Flags::from_bits_unchecked(0) }, Flags::empty());
         assert_eq!(unsafe { Flags::from_bits_unchecked(0b1) }, Flags::A);
         assert_eq!(unsafe { Flags::from_bits_unchecked(0b10) }, Flags::B);
-        assert_eq!(unsafe { Flags::from_bits_unchecked(0b11) }, (Flags::A | Flags::B));
-        assert_eq!(unsafe { Flags::from_bits_unchecked(0b1000) }, (extra | Flags::empty()));
-        assert_eq!(unsafe { Flags::from_bits_unchecked(0b1001) }, (extra | Flags::A));
+        assert_eq!(
+            unsafe { Flags::from_bits_unchecked(0b11) },
+            (Flags::A | Flags::B)
+        );
+        assert_eq!(
+            unsafe { Flags::from_bits_unchecked(0b1000) },
+            (extra | Flags::empty())
+        );
+        assert_eq!(
+            unsafe { Flags::from_bits_unchecked(0b1001) },
+            (extra | Flags::A)
+        );
     }
 
     #[test]
@@ -1177,7 +1195,6 @@ mod tests {
         assert_eq!(m1, e1);
     }
 
-
     #[cfg(bitflags_const_fn)]
     #[test]
     fn test_const_fn() {
@@ -1276,7 +1293,10 @@ mod tests {
         let extra = unsafe { Flags::from_bits_unchecked(0xb8) };
         assert_eq!(format!("{:?}", extra), "0xb8");
         assert_eq!(format!("{:?}", Flags::A | extra), "A | 0xb8");
-        assert_eq!(format!("{:?}", Flags::ABC | extra), "A | B | C | ABC | 0xb8");
+        assert_eq!(
+            format!("{:?}", Flags::ABC | extra),
+            "A | B | C | ABC | 0xb8"
+        );
     }
 
     #[test]
@@ -1320,8 +1340,7 @@ mod tests {
             pub struct PublicFlags: i8 {
                 const X = 0;
             }
-        }
-        bitflags! {
+
             struct PrivateFlags: i8 {
                 const Y = 0;
             }
@@ -1436,4 +1455,9 @@ mod tests {
         assert_eq!(format!("{:?}", Flags::empty()), "NONE");
         assert_eq!(format!("{:?}", Flags::SOME), "SOME");
     }
+
+    #[test]
+    fn test_empty_bitflags() {
+        bitflags! {}
+    }
 }


Test patch:
diff --git a/test_suite/tests/compile-fail/private_flags.rs b/test_suite/tests/compile-fail/private_flags.rs
index 35089bc..0532246 100644
--- a/test_suite/tests/compile-fail/private_flags.rs
+++ b/test_suite/tests/compile-fail/private_flags.rs
@@ -6,8 +6,7 @@ mod example {
         pub struct Flags1: u32 {
             const FLAG_A = 0b00000001;
         }
-    }
-    bitflags! {
+
         struct Flags2: u32 {
             const FLAG_B = 0b00000010;
         }
diff --git a/test_suite/tests/compile-fail/private_flags.stderr b/test_suite/tests/compile-fail/private_flags.stderr
index c72b6ff..2bdf1ac 100644
--- a/test_suite/tests/compile-fail/private_flags.stderr
+++ b/test_suite/tests/compile-fail/private_flags.stderr
@@ -1,16 +1,18 @@
 error[E0603]: struct `Flags2` is private
-  --> $DIR/private_flags.rs:19:26
+  --> $DIR/private_flags.rs:18:26
    |
-19 |     let flag2 = example::Flags2::FLAG_B;
+18 |     let flag2 = example::Flags2::FLAG_B;
    |                          ^^^^^^ private struct
    |
 note: the struct `Flags2` is defined here
-  --> $DIR/private_flags.rs:10:5
+  --> $DIR/private_flags.rs:5:5
    |
-10 | /     bitflags! {
-11 | |         struct Flags2: u32 {
-12 | |             const FLAG_B = 0b00000010;
-13 | |         }
-14 | |     }
+5  | /     bitflags! {
+6  | |         pub struct Flags1: u32 {
+7  | |             const FLAG_A = 0b00000001;
+8  | |         }
+...  |
+12 | |         }
+13 | |     }
    | |_____^
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)