bitflags / bitflags Goto Github PK
View Code? Open in Web Editor NEWA macro to generate structures which behave like bitflags
License: Apache License 2.0
A macro to generate structures which behave like bitflags
License: Apache License 2.0
In nix
we use the bitflags!
macro for grouping the various libc
constants into datatypes for our functions. This provides some nice type safety, but unfortunately the generated documentation is not ideal. There are two problems with how bitflags!
results in generated documentation:
I'm not certain if this is fixable by bitflags
without changes to rustdoc
, but I'd prefer if the documentation for the generated datatypes more closely matched Enum
types, which doesn't have either of the above problems.
Also relevant: nix-rust/nix#593
I work with data that often has a set of bitflags and then also has various masks defined over those bitflags. Unfortunately those masks are not often a valid value for the actual datatype. For example, when working with the termios
API on POSIX systems, you have the constants:
bitflags! {
pub flags ControlFlags: tcflag_t {
...,
CS5,
CS6,
CS7,
CS8,
...,
}
}
This is part of a larger bitfield that contains many other values, so the following flags are defined:
bitflags! {
pub flags ControlFlagsMask: tcflag_t {
...,
CSIZE,
...,
}
}
But if I do this, there's no way to actually do set operations between these two without combining these flags, which creates the problem of a user actually being able to generate an invalid bitfield by using CSIZE directly and passing it into a function.
It'd be great if there was a way to tag certain values as a mask
such that you could use it to select values from an existing bitflags type but couldn't use it directly within that type.
https://gist.github.com/Ms2ger/5dd2268cb37176076856 causes
$ cargo build
Compiling bitflags v0.1.0 (file:///tmp/bitflags)
<bitflags macros>:30:15: 30:60 warning: method is never used: `bits`, #[warn(dead_code)] on by default
<bitflags macros>:30 # [ inline ] pub fn bits ( & self ) -> $ T { self . bits }
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<bitflags macros>:90:1: 92:63 note: in this expansion of bitflags! (defined in <bitflags macros>)
lib.rs:5:1: 10:2 note: in this expansion of bitflags! (defined in <bitflags macros>)
<bitflags macros>:33:15: 37:67 warning: method is never used: `from_bits`, #[warn(dead_code)] on by default
<bitflags macros>:33 # [ inline ] pub fn from_bits ( bits : $ T ) -> :: std:: option:: Option < $
<bitflags macros>:34 BitFlags > {
<bitflags macros>:35 if ( bits & ! $ BitFlags:: all ( ) . bits ( ) ) != 0 {
<bitflags macros>:36 :: std:: option:: Option:: None } else {
<bitflags macros>:37 :: std:: option:: Option:: Some ( $ BitFlags { bits : bits } ) } }
<bitflags macros>:90:1: 92:63 note: in this expansion of bitflags! (defined in <bitflags macros>)
lib.rs:5:1: 10:2 note: in this expansion of bitflags! (defined in <bitflags macros>)
<bitflags macros>:40:15: 41:53 warning: method is never used: `from_bits_truncate`, #[warn(dead_code)] on by default
<bitflags macros>:40 # [ inline ] pub fn from_bits_truncate ( bits : $ T ) -> $ BitFlags {
<bitflags macros>:41 $ BitFlags { bits : bits } & $ BitFlags:: all ( ) }
<bitflags macros>:90:1: 92:63 note: in this expansion of bitflags! (defined in <bitflags macros>)
lib.rs:5:1: 10:2 note: in this expansion of bitflags! (defined in <bitflags macros>)
<bitflags macros>:43:15: 44:36 warning: method is never used: `is_empty`, #[warn(dead_code)] on by default
<bitflags macros>:43 # [ inline ] pub fn is_empty ( & self ) -> bool {
<bitflags macros>:44 * self == $ BitFlags:: empty ( ) }
<bitflags macros>:90:1: 92:63 note: in this expansion of bitflags! (defined in <bitflags macros>)
lib.rs:5:1: 10:2 note: in this expansion of bitflags! (defined in <bitflags macros>)
<bitflags macros>:46:15: 47:34 warning: method is never used: `is_all`, #[warn(dead_code)] on by default
<bitflags macros>:46 # [ inline ] pub fn is_all ( & self ) -> bool {
<bitflags macros>:47 * self == $ BitFlags:: all ( ) }
<bitflags macros>:90:1: 92:63 note: in this expansion of bitflags! (defined in <bitflags macros>)
lib.rs:5:1: 10:2 note: in this expansion of bitflags! (defined in <bitflags macros>)
<bitflags macros>:49:15: 50:39 warning: method is never used: `intersects`, #[warn(dead_code)] on by default
<bitflags macros>:49 # [ inline ] pub fn intersects ( & self , other : $ BitFlags ) -> bool {
<bitflags macros>:50 ! ( * self & other ) . is_empty ( ) }
<bitflags macros>:90:1: 92:63 note: in this expansion of bitflags! (defined in <bitflags macros>)
lib.rs:5:1: 10:2 note: in this expansion of bitflags! (defined in <bitflags macros>)
<bitflags macros>:56:15: 57:34 warning: method is never used: `remove`, #[warn(dead_code)] on by default
<bitflags macros>:56 # [ inline ] pub fn remove ( & mut self , other : $ BitFlags ) {
<bitflags macros>:57 self . bits &= ! other . bits ; } /// Toggles the specified flags in-place.
<bitflags macros>:90:1: 92:63 note: in this expansion of bitflags! (defined in <bitflags macros>)
lib.rs:5:1: 10:2 note: in this expansion of bitflags! (defined in <bitflags macros>)
<bitflags macros>:58:15: 59:32 warning: method is never used: `toggle`, #[warn(dead_code)] on by default
<bitflags macros>:58 # [ inline ] pub fn toggle ( & mut self , other : $ BitFlags ) {
<bitflags macros>:59 self . bits ^= other . bits ; } } impl :: std:: ops:: BitOr for $ BitFlags {
<bitflags macros>:90:1: 92:63 note: in this expansion of bitflags! (defined in <bitflags macros>)
lib.rs:5:1: 10:2 note: in this expansion of bitflags! (defined in <bitflags macros>)
This threw me off when reading the bitflags documentation for the first time.
bitflags! {
flags Flags: u32 {
/* ... */
}
}
I know it is not a keyword because my IDE does not highlight it like one. The casing suggests that it is a variable name or module name. Nope, it is a nugatory token required by the macro.
I think the important relevant thing to communicate to readers is that a type with the given name is being declared by the macro. Either of the following would be far more valuable I think.
bitflags! {
type Flags: u32 {
/* ... */
}
}
bitflags! {
struct Flags: u32 {
/* ... */
}
}
Are there any plans to support Serialize
and Deserialize
for generated types? I'm writing the impls manually in my code, but this falls apart once there's a ton of bitflags
generated types. If others are interested in such a feature, maybe I can find the time to implement it myself and submit a pull request :)
This crate presently has no crate level docs, and that is the most important place for docs to be.
Let's move the current content of the bitflags!
rustdocs up to the crate level, leaving behind copies of the examples, and a hyperlink to the crate level.
0.8.2 contains #[allow(private_in_public)]
for a flavor of private-in-public error that is really going to become an error (public reexport of a private extern crate).
I turned it into an error in rustc and during bootstrapping I discovered that bitflags 0.8.2 used by rustc are still using it.
cargo test
prints the following warnings:
warning: use of deprecated item: use `std::collections::hash_map::DefaultHasher` instead
--> src/lib.rs:519:21
|
519 | use std::hash::{SipHasher, Hash, Hasher};
| ^^^^^^^^^
|
= note: #[warn(deprecated)] on by default
warning: use of deprecated item: use `std::collections::hash_map::DefaultHasher` instead
--> src/lib.rs:775:21
|
775 | let mut s = SipHasher::new_with_keys(0, 0);
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: #[warn(deprecated)] on by default
warning: use of deprecated item: use `std::collections::hash_map::DefaultHasher` instead
--> src/lib.rs:775:21
|
775 | let mut s = SipHasher::new_with_keys(0, 0);
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: #[warn(deprecated)] on by default
The Go equivalent using iota
looks like:
const (
flagA = 1 << iota
flagB
flagC
flagD
)
Is this something you would consider supporting in a better way in bitflags?
I'd be happy to make a PR.
The following code cause a compilation error when compiled not compiled with feature "C".
bitflags! {
flags Flags: u32 {
const FLAG_A = 0b00000001,
const FLAG_B = 0b00000010,
#[cfg(feature = "C")] const FLAG_C = 0b00000100,
}
}
:12:22: 12:28 error: unresolved name
FLAG_C
:12 if self . contains ( $ Flag ) {
^~~~~~
:1:1: 79:67 note: in expansion of bitflags!
:77:1: 79:63 note: expansion site
:1:1: 79:67 note: in expansion of bitflags!
Given the following snippet of code compiled with bitflags 0.8:
#![allow(deprecated)]
#[macro_use]
extern crate bitflags;
bitflags! {
pub flags TestFlags: u32 {
#[deprecated(note = "test note")]
const FLAG_ONE = 1,
}
}
Everything works fine:
Compiling bitflags_breakage_test v0.1.0 (file:///home/cldfire/programming_projects/bitflags_breakage_test)
Finished dev [unoptimized + debuginfo] target(s) in 0.10 secs
And everything looks fine in the docs as well:
However, given the same snippet of code (ignoring syntax changes) compiled with bitflags 0.9:
#![allow(deprecated)]
#[macro_use]
extern crate bitflags;
bitflags! {
pub struct TestFlags: u32 {
#[deprecated(note = "test note")]
const FLAG_ONE = 1;
}
}
It does not compile:
Updating registry `https://github.com/rust-lang/crates.io-index`
Compiling bitflags_breakage_test v0.1.0 (file:///home/cldfire/programming_projects/bitflags_breakage_test)
error: This deprecation annotation is useless
--> src/lib.rs:6:1
|
6 | / bitflags! {
7 | | pub struct TestFlags: u32 {
8 | | #[deprecated(note = "test note")]
9 | | const FLAG_ONE = 1;
10 | | }
11 | | }
| |_^
|
= note: this error originates in a macro outside of the current crate
error: This deprecation annotation is useless
--> src/lib.rs:6:1
|
6 | / bitflags! {
7 | | pub struct TestFlags: u32 {
8 | | #[deprecated(note = "test note")]
9 | | const FLAG_ONE = 1;
10 | | }
11 | | }
| |_^
|
= note: this error originates in a macro outside of the current crate
error: aborting due to 2 previous errors
error: Could not compile `bitflags_breakage_test`.
To learn more, run the command again with --verbose.
I am not sure if this behavior is intended or not, or if use of attributes such as #[deprecated]
was supported in the first place. If this is correct behavior it would be nice to mention it in the release notes (I encountered this issue while bumping bitflags from 0.8 -> 0.9 in my own crate).
#61 adds an unstable_testing
feature that is only considered by tests. It seems unfortunate to leak this into the public API.
Having a separate crate for tests (like in Serde) would avoid this.
The contains
API is implemented as follows:
pub fn contains(&self, other: $BitFlags) -> bool {
(*self & other) == other
}
This means that doing flags.contains(SomeFlag::empty())
is true, which is counterintuitive.
The latest macro implementation causes the following error:
:26:5: 26:74 error: constant item is never used: `WNOHANG`, #[deny(dead_code)] on by default :26 $ ( const $ Flag : super:: $ BitFlags = super:: $ BitFlags { bits : 0 } ; ) + ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ :1:1: 92:67 note: in expansion of bitflags! :90:1: 92:63 note: expansion site :1:1: 92:67 note: in expansion of bitflags! src/sys/wait.rs:13:1: 17:3 note: expansion site
When the bitflags aren't used by name (the following is an example from nix-rust where I noticed the error):
bitflags!(
flags WaitPidFlag: c_int {
const WNOHANG = 0x00000001,
}
);
pub fn waitpid(pid: pid_t, options: Option<WaitPidFlag>) -> Result<WaitStatus> {
use self::WaitStatus::*;
let mut status: i32 = 0;
let option_bits = match options {
Some(bits) => bits.bits(),
None => 0
};
let res = unsafe { ffi::waitpid(pid as pid_t, &mut status as *mut c_int, option_bits) };
if res < 0 {
Err(Error::Sys(Errno::last()))
} else if res == 0 {
Ok(StillAlive)
} else {
Ok(Exited(res))
}
}
The Debug representation is the empty string. This is not very debuggable. I think "(empty)" would be more helpful.
#[macro_use]
extern crate bitflags;
bitflags! {
pub flags Flags: u8 {
const A = 0,
}
}
fn main() {
println!("{:?}", Flags::empty());
}
It makes sense to me why Default is not derived for bitflags - you may want a default value that is different from the empty value. Since Default is such a common trait, it would be helpful to mention explicitly in the "Trait implementations" section of the rustdoc and show an example using #[derive(Default)]
.
It may be too late for such a change to make sense but typically "const" items are followed by a semicolon, not comma.
Semicolon would be more consistent with lazy_static as well.
bitflags! {
flags Flags: u32 {
const A = 0b00000001;
const B = 0b00000010;
}
}
const C: u32 = 0b00000100;
const D: u32 = 0b00001000;
lazy_static! {
static ref E: u32 = 0b00010000;
static ref F: u32 = 0b00100000;
}
351a632 seems to have broken code which uses libc::c_int as the type of the flags. I'm not sure if libc::c_int is supported or not, since it is an integer type, though it is in some sense, user defined...
#[macro_use]
extern crate bitflags;
extern crate libc;
use libc::c_int;
bitflags! {
/// baz
flags Flags: c_int {
const A = 0b00000001,
#[doc = "bar"]
const B = 0b00000010,
const C = 0b00000100,
#[doc = "foo"]
const ABC = A.bits | B.bits | C.bits,
}
}
#[test]
fn smoke() {
assert_eq!(ABC, A | B | C);
}
This worked before this commit, but fails after.
Iterating over each each possible flag value would be a cool feature. I'm currently making an array with each constant value and then iterating over that.
is there any specific reason for that or it's just a "oops forgot to change" ? :)
Looks very strange, sometimes it works, sometimes it doesn't:
Used to be:
Could not document `bitflags`.
Caused by:
Process didn't exit successfully: `rustdoc /home/travis/.cargo/registry/src/github.com-0a35038f75765ae4/bitflags-0.2.1/src/lib.rs --crate-name bitflags -o /home/travis/build/gfx-rs/gfx/target/doc -L dependency=/home/travis/build/gfx-rs/gfx/target/debug/deps -L dependency=/home/travis/build/gfx-rs/gfx/target/debug/deps` (exit code: 101)
But has changed into this in the most recent build:
<bitflags macros>:7:27: 8:19 error: missing documentation for a constant
<bitflags macros>:7 $ ( # [ $ Flag_attr ] ) * pub const $ Flag : $ BitFlags = $ BitFlags {
<bitflags macros>:8 bits : $ value } ; ) + impl :: std:: fmt:: Debug for $ BitFlags {
<bitflags macros>:1:1: 77:67 note: in expansion of bitflags!
/home/travis/.cargo/registry/src/github.com-0a35038f75765ae4/draw_state-0.1.1/src/state.rs:289:1: 299:3 note: expansion site
/home/travis/.cargo/registry/src/github.com-0a35038f75765ae4/draw_state-0.1.1/src/lib.rs:17:9: 17:21 note: lint level defined here
/home/travis/.cargo/registry/src/github.com-0a35038f75765ae4/draw_state-0.1.1/src/lib.rs:17 #![deny(missing_docs, missing_copy_implementations)]
^~~~~~~~~~~~
<bitflags macros>:7:27: 8:19 error: missing documentation for a constant
<bitflags macros>:7 $ ( # [ $ Flag_attr ] ) * pub const $ Flag : $ BitFlags = $ BitFlags {
<bitflags macros>:8 bits : $ value } ; ) + impl :: std:: fmt:: Debug for $ BitFlags {
<bitflags macros>:1:1: 77:67 note: in expansion of bitflags!
/home/travis/.cargo/registry/src/github.com-0a35038f75765ae4/draw_state-0.1.1/src/state.rs:289:1: 299:3 note: expansion site
/home/travis/.cargo/registry/src/github.com-0a35038f75765ae4/draw_state-0.1.1/src/lib.rs:17:9: 17:21 note: lint level defined here
/home/travis/.cargo/registry/src/github.com-0a35038f75765ae4/draw_state-0.1.1/src/lib.rs:17 #![deny(missing_docs, missing_copy_implementations)]
^~~~~~~~~~~~
<bitflags macros>:7:27: 8:19 error: missing documentation for a constant
<bitflags macros>:7 $ ( # [ $ Flag_attr ] ) * pub const $ Flag : $ BitFlags = $ BitFlags {
<bitflags macros>:8 bits : $ value } ; ) + impl :: std:: fmt:: Debug for $ BitFlags {
<bitflags macros>:1:1: 77:67 note: in expansion of bitflags!
/home/travis/.cargo/registry/src/github.com-0a35038f75765ae4/draw_state-0.1.1/src/state.rs:289:1: 299:3 note: expansion site
/home/travis/.cargo/registry/src/github.com-0a35038f75765ae4/draw_state-0.1.1/src/lib.rs:17:9: 17:21 note: lint level defined here
/home/travis/.cargo/registry/src/github.com-0a35038f75765ae4/draw_state-0.1.1/src/lib.rs:17 #![deny(missing_docs, missing_copy_implementations)]
^~~~~~~~~~~~
<bitflags macros>:7:27: 8:19 error: missing documentation for a constant
<bitflags macros>:7 $ ( # [ $ Flag_attr ] ) * pub const $ Flag : $ BitFlags = $ BitFlags {
<bitflags macros>:8 bits : $ value } ; ) + impl :: std:: fmt:: Debug for $ BitFlags {
<bitflags macros>:1:1: 77:67 note: in expansion of bitflags!
/home/travis/.cargo/registry/src/github.com-0a35038f75765ae4/draw_state-0.1.1/src/state.rs:289:1: 299:3 note: expansion site
/home/travis/.cargo/registry/src/github.com-0a35038f75765ae4/draw_state-0.1.1/src/lib.rs:17:9: 17:21 note: lint level defined here
/home/travis/.cargo/registry/src/github.com-0a35038f75765ae4/draw_state-0.1.1/src/lib.rs:17 #![deny(missing_docs, missing_copy_implementations)]
^~~~~~~~~~~~
<bitflags macros>:7:27: 8:19 error: missing documentation for a constant
<bitflags macros>:7 $ ( # [ $ Flag_attr ] ) * pub const $ Flag : $ BitFlags = $ BitFlags {
<bitflags macros>:8 bits : $ value } ; ) + impl :: std:: fmt:: Debug for $ BitFlags {
<bitflags macros>:1:1: 77:67 note: in expansion of bitflags!
/home/travis/.cargo/registry/src/github.com-0a35038f75765ae4/draw_state-0.1.1/src/state.rs:289:1: 299:3 note: expansion site
/home/travis/.cargo/registry/src/github.com-0a35038f75765ae4/draw_state-0.1.1/src/lib.rs:17:9: 17:21 note: lint level defined here
/home/travis/.cargo/registry/src/github.com-0a35038f75765ae4/draw_state-0.1.1/src/lib.rs:17 #![deny(missing_docs, missing_copy_implementations)]
^~~~~~~~~~~~
<bitflags macros>:7:27: 8:19 error: missing documentation for a constant
<bitflags macros>:7 $ ( # [ $ Flag_attr ] ) * pub const $ Flag : $ BitFlags = $ BitFlags {
<bitflags macros>:8 bits : $ value } ; ) + impl :: std:: fmt:: Debug for $ BitFlags {
<bitflags macros>:1:1: 77:67 note: in expansion of bitflags!
/home/travis/.cargo/registry/src/github.com-0a35038f75765ae4/draw_state-0.1.1/src/state.rs:289:1: 299:3 note: expansion site
/home/travis/.cargo/registry/src/github.com-0a35038f75765ae4/draw_state-0.1.1/src/lib.rs:17:9: 17:21 note: lint level defined here
/home/travis/.cargo/registry/src/github.com-0a35038f75765ae4/draw_state-0.1.1/src/lib.rs:17 #![deny(missing_docs, missing_copy_implementations)]
^~~~~~~~~~~~
<bitflags macros>:7:27: 8:19 error: missing documentation for a constant
<bitflags macros>:7 $ ( # [ $ Flag_attr ] ) * pub const $ Flag : $ BitFlags = $ BitFlags {
<bitflags macros>:8 bits : $ value } ; ) + impl :: std:: fmt:: Debug for $ BitFlags {
<bitflags macros>:1:1: 77:67 note: in expansion of bitflags!
/home/travis/.cargo/registry/src/github.com-0a35038f75765ae4/draw_state-0.1.1/src/target.rs:43:1: 54:3 note: expansion site
/home/travis/.cargo/registry/src/github.com-0a35038f75765ae4/draw_state-0.1.1/src/lib.rs:17:9: 17:21 note: lint level defined here
/home/travis/.cargo/registry/src/github.com-0a35038f75765ae4/draw_state-0.1.1/src/lib.rs:17 #![deny(missing_docs, missing_copy_implementations)]
^~~~~~~~~~~~
<bitflags macros>:7:27: 8:19 error: missing documentation for a constant
<bitflags macros>:7 $ ( # [ $ Flag_attr ] ) * pub const $ Flag : $ BitFlags = $ BitFlags {
<bitflags macros>:8 bits : $ value } ; ) + impl :: std:: fmt:: Debug for $ BitFlags {
<bitflags macros>:1:1: 77:67 note: in expansion of bitflags!
/home/travis/.cargo/registry/src/github.com-0a35038f75765ae4/draw_state-0.1.1/src/target.rs:43:1: 54:3 note: expansion site
/home/travis/.cargo/registry/src/github.com-0a35038f75765ae4/draw_state-0.1.1/src/lib.rs:17:9: 17:21 note: lint level defined here
/home/travis/.cargo/registry/src/github.com-0a35038f75765ae4/draw_state-0.1.1/src/lib.rs:17 #![deny(missing_docs, missing_copy_implementations)]
^~~~~~~~~~~~
<bitflags macros>:7:27: 8:19 error: missing documentation for a constant
<bitflags macros>:7 $ ( # [ $ Flag_attr ] ) * pub const $ Flag : $ BitFlags = $ BitFlags {
<bitflags macros>:8 bits : $ value } ; ) + impl :: std:: fmt:: Debug for $ BitFlags {
<bitflags macros>:1:1: 77:67 note: in expansion of bitflags!
/home/travis/.cargo/registry/src/github.com-0a35038f75765ae4/draw_state-0.1.1/src/target.rs:43:1: 54:3 note: expansion site
/home/travis/.cargo/registry/src/github.com-0a35038f75765ae4/draw_state-0.1.1/src/lib.rs:17:9: 17:21 note: lint level defined here
/home/travis/.cargo/registry/src/github.com-0a35038f75765ae4/draw_state-0.1.1/src/lib.rs:17 #![deny(missing_docs, missing_copy_implementations)]
^~~~~~~~~~~~
<bitflags macros>:7:27: 8:19 error: missing documentation for a constant
<bitflags macros>:7 $ ( # [ $ Flag_attr ] ) * pub const $ Flag : $ BitFlags = $ BitFlags {
<bitflags macros>:8 bits : $ value } ; ) + impl :: std:: fmt:: Debug for $ BitFlags {
<bitflags macros>:1:1: 77:67 note: in expansion of bitflags!
/home/travis/.cargo/registry/src/github.com-0a35038f75765ae4/draw_state-0.1.1/src/target.rs:43:1: 54:3 note: expansion site
/home/travis/.cargo/registry/src/github.com-0a35038f75765ae4/draw_state-0.1.1/src/lib.rs:17:9: 17:21 note: lint level defined here
/home/travis/.cargo/registry/src/github.com-0a35038f75765ae4/draw_state-0.1.1/src/lib.rs:17 #![deny(missing_docs, missing_copy_implementations)]
^~~~~~~~~~~~
<bitflags macros>:7:27: 8:19 error: missing documentation for a constant
<bitflags macros>:7 $ ( # [ $ Flag_attr ] ) * pub const $ Flag : $ BitFlags = $ BitFlags {
<bitflags macros>:8 bits : $ value } ; ) + impl :: std:: fmt:: Debug for $ BitFlags {
<bitflags macros>:1:1: 77:67 note: in expansion of bitflags!
/home/travis/.cargo/registry/src/github.com-0a35038f75765ae4/draw_state-0.1.1/src/target.rs:43:1: 54:3 note: expansion site
/home/travis/.cargo/registry/src/github.com-0a35038f75765ae4/draw_state-0.1.1/src/lib.rs:17:9: 17:21 note: lint level defined here
/home/travis/.cargo/registry/src/github.com-0a35038f75765ae4/draw_state-0.1.1/src/lib.rs:17 #![deny(missing_docs, missing_copy_implementations)]
^~~~~~~~~~~~
<bitflags macros>:7:27: 8:19 error: missing documentation for a constant
<bitflags macros>:7 $ ( # [ $ Flag_attr ] ) * pub const $ Flag : $ BitFlags = $ BitFlags {
<bitflags macros>:8 bits : $ value } ; ) + impl :: std:: fmt:: Debug for $ BitFlags {
<bitflags macros>:1:1: 77:67 note: in expansion of bitflags!
/home/travis/.cargo/registry/src/github.com-0a35038f75765ae4/draw_state-0.1.1/src/target.rs:43:1: 54:3 note: expansion site
/home/travis/.cargo/registry/src/github.com-0a35038f75765ae4/draw_state-0.1.1/src/lib.rs:17:9: 17:21 note: lint level defined here
/home/travis/.cargo/registry/src/github.com-0a35038f75765ae4/draw_state-0.1.1/src/lib.rs:17 #![deny(missing_docs, missing_copy_implementations)]
^~~~~~~~~~~~
<bitflags macros>:7:27: 8:19 error: missing documentation for a constant
<bitflags macros>:7 $ ( # [ $ Flag_attr ] ) * pub const $ Flag : $ BitFlags = $ BitFlags {
<bitflags macros>:8 bits : $ value } ; ) + impl :: std:: fmt:: Debug for $ BitFlags {
<bitflags macros>:1:1: 77:67 note: in expansion of bitflags!
/home/travis/.cargo/registry/src/github.com-0a35038f75765ae4/draw_state-0.1.1/src/target.rs:43:1: 54:3 note: expansion site
/home/travis/.cargo/registry/src/github.com-0a35038f75765ae4/draw_state-0.1.1/src/lib.rs:17:9: 17:21 note: lint level defined here
/home/travis/.cargo/registry/src/github.com-0a35038f75765ae4/draw_state-0.1.1/src/lib.rs:17 #![deny(missing_docs, missing_copy_implementations)]
^~~~~~~~~~~~
<bitflags macros>:7:27: 8:19 error: missing documentation for a constant
<bitflags macros>:7 $ ( # [ $ Flag_attr ] ) * pub const $ Flag : $ BitFlags = $ BitFlags {
<bitflags macros>:8 bits : $ value } ; ) + impl :: std:: fmt:: Debug for $ BitFlags {
<bitflags macros>:1:1: 77:67 note: in expansion of bitflags!
<bitflags macros>:75:1: 77:63 note: expansion site
<bitflags macros>:1:1: 77:67 note: in expansion of bitflags!
/home/travis/.cargo/registry/src/github.com-0a35038f75765ae4/draw_state-0.1.1/src/target.rs:56:1: 62:3 note: expansion site
/home/travis/.cargo/registry/src/github.com-0a35038f75765ae4/draw_state-0.1.1/src/lib.rs:17:9: 17:21 note: lint level defined here
/home/travis/.cargo/registry/src/github.com-0a35038f75765ae4/draw_state-0.1.1/src/lib.rs:17 #![deny(missing_docs, missing_copy_implementations)]
^~~~~~~~~~~~
<bitflags macros>:7:27: 8:19 error: missing documentation for a constant
<bitflags macros>:7 $ ( # [ $ Flag_attr ] ) * pub const $ Flag : $ BitFlags = $ BitFlags {
<bitflags macros>:8 bits : $ value } ; ) + impl :: std:: fmt:: Debug for $ BitFlags {
<bitflags macros>:1:1: 77:67 note: in expansion of bitflags!
<bitflags macros>:75:1: 77:63 note: expansion site
<bitflags macros>:1:1: 77:67 note: in expansion of bitflags!
/home/travis/.cargo/registry/src/github.com-0a35038f75765ae4/draw_state-0.1.1/src/target.rs:56:1: 62:3 note: expansion site
/home/travis/.cargo/registry/src/github.com-0a35038f75765ae4/draw_state-0.1.1/src/lib.rs:17:9: 17:21 note: lint level defined here
/home/travis/.cargo/registry/src/github.com-0a35038f75765ae4/draw_state-0.1.1/src/lib.rs:17 #![deny(missing_docs, missing_copy_implementations)]
^~~~~~~~~~~~
error: aborting due to 15 previous errors
Build failed, waiting for other jobs to finish...
Could not compile `draw_state`.
Caused by:
Process didn't exit successfully: `rustc /home/travis/.cargo/registry/src/github.com-0a35038f75765ae4/draw_state-0.1.1/src/lib.rs --crate-name draw_state --crate-type lib -g -C metadata=db41f6c0c53c3a65 -C extra-filename=-db41f6c0c53c3a65 --out-dir /home/travis/build/gfx-rs/gfx/target/debug/deps --emit=dep-info,link -L dependency=/home/travis/build/gfx-rs/gfx/target/debug/deps -L dependency=/home/travis/build/gfx-rs/gfx/target/debug/deps --extern bitflags=/home/travis/build/gfx-rs/gfx/target/debug/deps/libbitflags-425420435a0b4460.rlib -Awarnings` (exit code: 101)
It would be nice to have FlagType::FlagName
be the pattern rather than dumping the flag values into the top-level namespace. Is this possible?
What do you think about adding feature gated 128-bit based bitflags? While trying u128 in nightly, I noticed that bitflags silently degrades to u64.
I can work on a PR if interested.
bitflags 0.3 builds fine but 0.5 gives me this error when building libucl-sys (latest: https://github.com/hauleth/libucl-sys). Not sure where the problem is..
<bitflags macros>:17:24: 19:63 note: in this expansion of bitflags! (defined in <bitflags macros>)
lib.rs:89:1: 99:2 note: in this expansion of bitflags! (defined in <bitflags macros>)
lib.rs:91:31: 91:36 help: run `rustc --explain E0412` to see a detailed explanation
lib.rs:91:31: 91:36 help: you can import several candidates into scope (`use ...;`):
lib.rs:91:31: 91:36 help: `bitflags::__core::os::raw::c_int`
lib.rs:91:31: 91:36 help: `libc::c_int`
lib.rs:91:31: 91:36 help: `std::os::raw::c_int`
lib.rs:91:31: 91:36 error: type name `c_int` is undefined or not in scope [E0412]
lib.rs:91 flags ucl_object_flags_t: c_int {
The rustdoc currently shows this distracting internal rule:
(@_impl flags $BitFlags:ident: $T:ty {
$($(#[$Flag_attr:meta])* const $Flag:ident = $value:expr),+
}) => { ... };
See: imgui-rs/imgui-rs#42 (comment)
In particular, it looks like 67e4485 introduced a new set
method that can break consumers if they had defined their own set
method.
Perhaps we can yank 0.7.1
and release 0.8
?
These formatting options should be available.
bitflags really wants to be used in OS-kernel-related code, but since it isn't no_std it can't be.
When using this lib as a dep, and running clippy across the project, this dependency fails a few trivial lints, this prevents things like causing clippy to fail a CI build. The lints in question are:
if_not_else
(Needless !
which can be removed by swapping if
and else
branches)used_underscore_binding
I haven't looked at the source for this project at all, but if it's just a trivial change, and doesn't affect the underlying methodology I'd be happy to submit a PR fixing these.
Thanks for this lib too!
glfw v0.0.8 has a dependancy on bitflags. Version 0.1.1 of bitflags is fine, 0.2.1 gives this error in the build:
Compiling glfw v0.0.8
:8:24: 15:4 error: conflicting implementations for trait core::fmt::Debug
[E0119]
:8 bits : $ value } ; ) + impl :: std:: fmt:: Debug for $ BitFlags {
:9 fn fmt ( & self , f : & mut :: std:: fmt:: Formatter ) -> :: std:: fmt::
:10 Result {
:11 let mut first = true ; $ (
:12 if self . contains ( $ Flag ) {
:13 if ! first { try ! ( f . write_str ( " | " ) ) ; } first = false ; try ! (
...
:1:1: 79:67 note: in expansion of bitflags!
/Users/chris/.cargo/registry/src/github.com-1ecc6299db9ec823/glfw-0.0.8/src/lib.rs:1041:1: 1049:2 note: expansion site
/Users/chris/.cargo/registry/src/github.com-1ecc6299db9ec823/glfw-0.0.8/src/lib.rs:1051:1: 1063:2 note: note conflicting implementation here
/Users/chris/.cargo/registry/src/github.com-1ecc6299db9ec823/glfw-0.0.8/src/lib.rs:1051 impl fmt::Debug for Modifiers {
/Users/chris/.cargo/registry/src/github.com-1ecc6299db9ec823/glfw-0.0.8/src/lib.rs:1052 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
/Users/chris/.cargo/registry/src/github.com-1ecc6299db9ec823/glfw-0.0.8/src/lib.rs:1053 for (i, x) in [Shift, Control, Alt, Super].iter().filter(|x| self.contains(**x)).enumerate() {
/Users/chris/.cargo/registry/src/github.com-1ecc6299db9ec823/glfw-0.0.8/src/lib.rs:1054 if i != 0 { try!(write!(f, ", ")) };
/Users/chris/.cargo/registry/src/github.com-1ecc6299db9ec823/glfw-0.0.8/src/lib.rs:1055 if *x == Shift { try!(write!(f, "Shift" )) }
/Users/chris/.cargo/registry/src/github.com-1ecc6299db9ec823/glfw-0.0.8/src/lib.rs:1056 else if *x == Control { try!(write!(f, "Control" )) }
...
error: aborting due to previous error
Compiling anything with glfw should produce this error. Pulling up the previous version with
cargo update -p bitflags --precise 0.1.1
has everything running again. This conflict with bitflags only occurs in an OSX build, not Linux.
Bitflags should match the semantics of structs, which are private by default unless explicitly exported using pub
.
Since this is a compat-breaking change, it would make sense to do it at the same time as the switch to associated constants and namespaced flags (#24).
Example:
bitflags! {
pub flags Flags: u32 {
const FLAG_A = 0b00000001,
const FLAG_B = 0b00000010,
}
}
With #47 bitflags no longer builds on various older versions (at least 1.7 and older). Is this intentional?
Are structs created using the bitflags
macro recommended to be used in raw FFI bindings, i.e. within function signatures (this involves giving the attribute repr(C)
to the struct, but seems to work) – or only using them in higher-level bindings?
This is the tracking issue for the evaluation performed by the libs team last week.
cc rust-lang/rust#32409 - maybe no action is warranted until this feature is stable.
bitflags! {
pub(super) flags Flags: u8 {
const A = 1
}
}
I notice that some freestanding folk are borrowing this code, doing a quick s#::std#::core#
and going on their merry way.
core
isn't stable, so I can't suggest you do that, but… I wonder if there's a solution on the horizon for this explicit module dependency problem. I imagine it's going to pop up more and more often as people do fun things with Rust.
Thoughts?
In short, the following should be possible:
extern crate libc;
use libc::c_uint;
mod constants;
bitflags! {
pub flags EnvFlags: c_uint {
const EnvNoSync = constants::MDB_NOSYNC,
// ...
}
}
As of #38, the above example will not compile. As a workaround, one can reference the imported types/modules within the bitflags definition using absolute paths, e.g. using ::libc::c_uint
instead of c_uint
or ::constants::MDB_NOSYNC
instead of constants::MDB_NOSYNC
. This is, at least, surprising.
This crate really wants to use associated constants (see rust-lang/rust#24921) but the tricks introduced in #14 are incompatible with associated constants (because associated constants can't be use
d to shadow locally scoped constants).
What do?
Also change the Cargo.toml 'documentation' key to "https://docs.rs/bitflags".
Would there be any objection to putting all generated consts in a module named after the type? This way, they could behave more like how enums do with variants globbing. It would also prevent documentation clutter in rustdoc, where all the constants are currently listed indiscriminately in the parent module.
Should we allow non-caps in constants so that they're stylistically closer to enums?
The syntax seems to work: http://is.gd/hGgTe7
This crate has a documentation problem in that it generates a bunch of methods, and they are hard to document. I believe the way we want to address this is by creating another module, containing a hand-coded API that looks like the bitflags produced API, and treat that entire module as documentation, sort of like error-chain does.
Will take some experimentation.
The latest nightly yields warnings:
note: in expansion of #[derive]
<bitflags macros>:5:1: 5:73 note: expansion site
<bitflags macros>:1:1: 72:67 note: in expansion of bitflags!
<bitflags macros>:70:1: 72:63 note: expansion site
<bitflags macros>:1:1: 72:67 note: in expansion of bitflags!
src/lib.rs:39:1: 52:2 note: expansion site
<bitflags macros>:5:65: 5:69 help: add #![feature(hash)] to the crate attributes to silence this warning
<bitflags macros>:5 # [ derive ( Copy , PartialEq , Eq , Clone , PartialOrd , Ord , Hash ) ] $ (
Hello!
Any hope to have a tiny example on how to use the macro in the documentation? :)
Thanks in advance! :)
Is there any hope of supporting usage like this? The error here is inconsistent with being able to declare structs and other types of items local to a function.
#[macro_use]
extern crate bitflags;
fn main() {
bitflags! {
flags Flags: u8 {
const A = 1,
const B = 2,
}
}
println!("{:?}", A);
}
error[E0425]: cannot find value `A` in module `super::super`
--> src/main.rs:5:5
|
5 | bitflags! {
| _____^ starting here...
6 | | flags Flags: u8 {
7 | | const A = 1,
8 | | const B = 2,
9 | | }
10 | | }
| |_____^ ...ending here: not found in `super::super`
|
= note: this error originates in a macro outside of the current crate
I noticed that bitflags has a no_std
feature now. It would be great if the crates.io version could be updated to include it.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.