diff --git a/.gitignore b/.gitignore index fbd9642b..61c33314 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +wip target Cargo.lock diff --git a/CHANGELOG.md b/CHANGELOG.md index 0d491015..91fd4bdf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,48 @@ +# 1.3.0 + +- Add `#[repr(transparent)]` ([#187]) + +- End `empty` doc comment with full stop ([#202]) + +- Fix typo in crate root docs ([#206]) + +- Document from_bits_unchecked unsafety ([#207]) + +- Let `is_all` ignore extra bits ([#211]) + +- Allows empty flag definition ([#225]) + +- Making crate accessible from std ([#227]) + +- Make `from_bits` a const fn ([#229]) + +- Allow multiple bitflags structs in one macro invocation ([#235]) + +- Add named functions to perform set operations ([#244]) + +- Fix typos in method docs ([#245]) + +- Modernization of the `bitflags` macro to take advantage of newer features and 2018 idioms ([#246]) + +- Fix regression (in an unreleased feature) and simplify tests ([#247]) + +- Use `Self` and fix bug when overriding `stringify!` ([#249]) + +[#187]: https://github.com/bitflags/bitflags/pull/187 +[#202]: https://github.com/bitflags/bitflags/pull/202 +[#206]: https://github.com/bitflags/bitflags/pull/206 +[#207]: https://github.com/bitflags/bitflags/pull/207 +[#211]: https://github.com/bitflags/bitflags/pull/211 +[#225]: https://github.com/bitflags/bitflags/pull/225 +[#227]: https://github.com/bitflags/bitflags/pull/227 +[#229]: https://github.com/bitflags/bitflags/pull/229 +[#235]: https://github.com/bitflags/bitflags/pull/235 +[#244]: https://github.com/bitflags/bitflags/pull/244 +[#245]: https://github.com/bitflags/bitflags/pull/245 +[#246]: https://github.com/bitflags/bitflags/pull/246 +[#247]: https://github.com/bitflags/bitflags/pull/247 +[#249]: https://github.com/bitflags/bitflags/pull/249 + # 1.2.1 - Remove extraneous `#[inline]` attributes ([#194]) diff --git a/Cargo.toml b/Cargo.toml index 44d0f193..45914ef6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ name = "bitflags" # NB: When modifying, also modify: # 1. html_root_url in lib.rs # 2. number in readme (for breaking changes) -version = "1.2.1" +version = "1.3.0" edition = "2018" authors = ["The Rust Project Developers"] license = "MIT/Apache-2.0" @@ -24,6 +24,7 @@ compiler_builtins = { version = '0.1.2', optional = true } [dev-dependencies] trybuild = "1.0" +rustversion = "1.0" serde = "1.0" serde_derive = "1.0" serde_json = "1.0" diff --git a/README.md b/README.md index 005a0a4e..0da0f853 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ Add this to your `Cargo.toml`: ```toml [dependencies] -bitflags = "1.2" +bitflags = "1.3" ``` and this to your source code: diff --git a/src/lib.rs b/src/lib.rs index 6f58a42f..f54b7127 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -254,9 +254,11 @@ //! assert!(none.is_empty()); //! } //! ``` +//! +//! Users should generally avoid defining a flag with a value of zero. #![cfg_attr(not(test), no_std)] -#![doc(html_root_url = "https://docs.rs/bitflags/1.2.1")] +#![doc(html_root_url = "https://docs.rs/bitflags/1.3.0")] #[doc(hidden)] pub extern crate core as _core; @@ -1203,7 +1205,7 @@ mod tests { #[test] fn test_set_ops_const() { // These just test that these compile and don't cause use-site panics - // (would be possible if we had some sort of UB), which is enoug + // (would be possible if we had some sort of UB) const INTERSECT: Flags = Flags::all().intersection(Flags::C); const UNION: Flags = Flags::A.union(Flags::C); const DIFFERENCE: Flags = Flags::all().difference(Flags::A); diff --git a/tests/compile-fail/.gitignore b/tests/compile-fail/.gitignore new file mode 100644 index 00000000..4dd9abc8 --- /dev/null +++ b/tests/compile-fail/.gitignore @@ -0,0 +1 @@ +*.stderr diff --git a/tests/compile-fail/private_flags.stderr.beta b/tests/compile-fail/private_flags.stderr.beta new file mode 100644 index 00000000..d23f8320 --- /dev/null +++ b/tests/compile-fail/private_flags.stderr.beta @@ -0,0 +1,18 @@ +error[E0603]: struct `Flags2` is private + --> $DIR/private_flags.rs:17:26 + | +17 | let flag2 = example::Flags2::FLAG_B; + | ^^^^^^ private struct + | +note: the struct `Flags2` is defined here + --> $DIR/private_flags.rs:4:5 + | +4 | / bitflags! { +5 | | pub struct Flags1: u32 { +6 | | const FLAG_A = 0b00000001; +7 | | } +... | +11 | | } +12 | | } + | |_____^ + = note: this error originates in the macro `bitflags` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/compiletest.rs b/tests/compiletest.rs index db50dfda..ae0c9df2 100644 --- a/tests/compiletest.rs +++ b/tests/compiletest.rs @@ -1,5 +1,55 @@ +use std::{ + fs, + ffi::OsStr, + io, + path::Path, +}; + #[test] fn compile_fail() { + prepare_stderr_files("tests/compile-fail").unwrap(); + let t = trybuild::TestCases::new(); t.compile_fail("tests/compile-fail/*.rs"); } + +// Compiler messages may change between versions +// We don't want to have to track these too closely for `bitflags`, but +// having some message to check makes sure user-facing errors are sensical. +// +// The approach we use is to run the test on all compilers, but only check stderr +// output on beta (which is the next stable release). We do this by default ignoring +// any `.stderr` files in the `compile-fail` directory, and copying `.stderr.beta` files +// when we happen to be running on a beta compiler. +fn prepare_stderr_files(path: impl AsRef) -> io::Result<()> { + for entry in fs::read_dir(path)? { + let entry = entry?; + + if entry.path().extension().and_then(OsStr::to_str) == Some("beta") { + let renamed = entry.path().with_extension(""); + + // Unconditionally remove a corresponding `.stderr` file for a `.stderr.beta` + // file if it exists. On `beta` compilers, we'll recreate it. On other compilers, + // we don't want to end up checking it anyways. + if renamed.exists() { + fs::remove_file(&renamed)?; + } + + rename_beta_stderr(entry.path(), renamed)?; + } + } + + Ok(()) +} + +#[rustversion::beta] +fn rename_beta_stderr(from: impl AsRef, to: impl AsRef) -> io::Result<()> { + fs::copy(from, to)?; + + Ok(()) +} + +#[rustversion::not(beta)] +fn rename_beta_stderr(_: impl AsRef, _: impl AsRef) -> io::Result<()> { + Ok(()) +}