Skip to content

Commit

Permalink
Merge pull request #249 from konsumlamm/self
Browse files Browse the repository at this point in the history
Use `Self` & fix bug when overriding `stringify!`
  • Loading branch information
KodrAus committed Aug 5, 2021
2 parents ec0fa76 + bef10f1 commit 9defa89
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 73 deletions.
116 changes: 52 additions & 64 deletions src/lib.rs
Expand Up @@ -362,6 +362,7 @@ macro_rules! bitflags {
() => {};
}

// A helper macro to implement the `all` function.
#[macro_export(local_inner_macros)]
#[doc(hidden)]
macro_rules! __impl_all_bitflags {
Expand Down Expand Up @@ -389,12 +390,12 @@ macro_rules! __impl_all_bitflags {
}
)+
}
$BitFlags { bits: $(<$BitFlags as __BitFlags>::$Flag)|+ }
Self { bits: $(<Self as __BitFlags>::$Flag)|+ }
};
(
$BitFlags:ident: $T:ty { }
) => {
$BitFlags { bits: 0 }
Self { bits: 0 }
};
}

Expand Down Expand Up @@ -448,15 +449,15 @@ macro_rules! __impl_bitflags {

let mut first = true;
$(
if <$BitFlags as __BitFlags>::$Flag(self) {
if <Self as __BitFlags>::$Flag(self) {
if !first {
f.write_str(" | ")?;
}
first = false;
f.write_str(__bitflags_stringify!($Flag))?;
f.write_str($crate::_core::stringify!($Flag))?;
}
)*
let extra_bits = self.bits & !$BitFlags::all().bits();
let extra_bits = self.bits & !Self::all().bits();
if extra_bits != 0 {
if !first {
f.write_str(" | ")?;
Expand Down Expand Up @@ -496,18 +497,18 @@ macro_rules! __impl_bitflags {
impl $BitFlags {
$(
$(#[$attr $($args)*])*
pub const $Flag: $BitFlags = $BitFlags { bits: $value };
pub const $Flag: Self = Self { bits: $value };
)*

/// Returns an empty set of flags.
#[inline]
pub const fn empty() -> $BitFlags {
$BitFlags { bits: 0 }
pub const fn empty() -> Self {
Self { bits: 0 }
}

/// Returns the set containing all flags.
#[inline]
pub const fn all() -> $BitFlags {
pub const fn all() -> Self {
__impl_all_bitflags! {
$BitFlags: $T {
$(
Expand All @@ -527,9 +528,9 @@ macro_rules! __impl_bitflags {
/// Convert from underlying bit representation, unless that
/// representation contains bits that do not correspond to a flag.
#[inline]
pub const fn from_bits(bits: $T) -> $crate::_core::option::Option<$BitFlags> {
if (bits & !$BitFlags::all().bits()) == 0 {
$crate::_core::option::Option::Some($BitFlags { bits })
pub const fn from_bits(bits: $T) -> $crate::_core::option::Option<Self> {
if (bits & !Self::all().bits()) == 0 {
$crate::_core::option::Option::Some(Self { bits })
} else {
$crate::_core::option::Option::None
}
Expand All @@ -538,8 +539,8 @@ macro_rules! __impl_bitflags {
/// Convert from underlying bit representation, dropping any bits
/// that do not correspond to flags.
#[inline]
pub const fn from_bits_truncate(bits: $T) -> $BitFlags {
$BitFlags { bits: bits & $BitFlags::all().bits }
pub const fn from_bits_truncate(bits: $T) -> Self {
Self { bits: bits & Self::all().bits }
}

/// Convert from underlying bit representation, preserving all
Expand All @@ -554,54 +555,55 @@ macro_rules! __impl_bitflags {
/// all bits correspond to a defined flag or that extra bits
/// are valid for this bitflags type.
#[inline]
pub const unsafe fn from_bits_unchecked(bits: $T) -> $BitFlags {
$BitFlags { bits }
pub const unsafe fn from_bits_unchecked(bits: $T) -> Self {
Self { bits }
}

/// Returns `true` if no flags are currently stored.
#[inline]
pub const fn is_empty(&self) -> bool {
self.bits() == $BitFlags::empty().bits()
self.bits() == Self::empty().bits()
}

/// Returns `true` if all flags are currently set.
#[inline]
pub const fn is_all(&self) -> bool {
$BitFlags::all().bits | self.bits == self.bits
Self::all().bits | self.bits == self.bits
}

/// Returns `true` if there are flags common to both `self` and `other`.
#[inline]
pub const fn intersects(&self, other: $BitFlags) -> bool {
!$BitFlags{ bits: self.bits & other.bits}.is_empty()
pub const fn intersects(&self, other: Self) -> bool {
!(Self { bits: self.bits & other.bits}).is_empty()
}

/// Returns `true` if all of the flags in `other` are contained within `self`.
#[inline]
pub const fn contains(&self, other: $BitFlags) -> bool {
pub const fn contains(&self, other: Self) -> bool {
(self.bits & other.bits) == other.bits
}

/// Inserts the specified flags in-place.
#[inline]
pub fn insert(&mut self, other: $BitFlags) {
pub fn insert(&mut self, other: Self) {
self.bits |= other.bits;
}

/// Removes the specified flags in-place.
#[inline]
pub fn remove(&mut self, other: $BitFlags) {
pub fn remove(&mut self, other: Self) {
self.bits &= !other.bits;
}

/// Toggles the specified flags in-place.
#[inline]
pub fn toggle(&mut self, other: $BitFlags) {
pub fn toggle(&mut self, other: Self) {
self.bits ^= other.bits;
}

/// Inserts or removes the specified flags depending on the passed value.
#[inline]
pub fn set(&mut self, other: $BitFlags, value: bool) {
pub fn set(&mut self, other: Self, value: bool) {
if value {
self.insert(other);
} else {
Expand All @@ -621,7 +623,7 @@ macro_rules! __impl_bitflags {
/// [`ops::BitAnd`]: https://doc.rust-lang.org/std/ops/trait.BitAnd.html
#[inline]
#[must_use]
pub const fn intersection(self, other: $BitFlags) -> Self {
pub const fn intersection(self, other: Self) -> Self {
Self { bits: self.bits & other.bits }
}

Expand All @@ -638,7 +640,7 @@ macro_rules! __impl_bitflags {
/// [`ops::BitOr`]: https://doc.rust-lang.org/std/ops/trait.BitOr.html
#[inline]
#[must_use]
pub const fn union(self, other: $BitFlags) -> Self {
pub const fn union(self, other: Self) -> Self {
Self { bits: self.bits | other.bits }
}

Expand All @@ -656,7 +658,7 @@ macro_rules! __impl_bitflags {
/// [`ops::Sub`]: https://doc.rust-lang.org/std/ops/trait.Sub.html
#[inline]
#[must_use]
pub const fn difference(self, other: $BitFlags) -> Self {
pub const fn difference(self, other: Self) -> Self {
Self { bits: self.bits & !other.bits }
}

Expand All @@ -675,7 +677,7 @@ macro_rules! __impl_bitflags {
/// [`ops::BitXor`]: https://doc.rust-lang.org/std/ops/trait.BitXor.html
#[inline]
#[must_use]
pub const fn symmetric_difference(self, other: $BitFlags) -> Self {
pub const fn symmetric_difference(self, other: Self) -> Self {
Self { bits: self.bits ^ other.bits }
}

Expand All @@ -701,101 +703,97 @@ macro_rules! __impl_bitflags {
}

impl $crate::_core::ops::BitOr for $BitFlags {
type Output = $BitFlags;
type Output = Self;

/// Returns the union of the two sets of flags.
#[inline]
fn bitor(self, other: $BitFlags) -> $BitFlags {
$BitFlags { bits: self.bits | other.bits }
fn bitor(self, other: $BitFlags) -> Self {
Self { bits: self.bits | other.bits }
}
}

impl $crate::_core::ops::BitOrAssign for $BitFlags {

/// Adds the set of flags.
#[inline]
fn bitor_assign(&mut self, other: $BitFlags) {
fn bitor_assign(&mut self, other: Self) {
self.bits |= other.bits;
}
}

impl $crate::_core::ops::BitXor for $BitFlags {
type Output = $BitFlags;
type Output = Self;

/// Returns the left flags, but with all the right flags toggled.
#[inline]
fn bitxor(self, other: $BitFlags) -> $BitFlags {
$BitFlags { bits: self.bits ^ other.bits }
fn bitxor(self, other: Self) -> Self {
Self { bits: self.bits ^ other.bits }
}
}

impl $crate::_core::ops::BitXorAssign for $BitFlags {

/// Toggles the set of flags.
#[inline]
fn bitxor_assign(&mut self, other: $BitFlags) {
fn bitxor_assign(&mut self, other: Self) {
self.bits ^= other.bits;
}
}

impl $crate::_core::ops::BitAnd for $BitFlags {
type Output = $BitFlags;
type Output = Self;

/// Returns the intersection between the two sets of flags.
#[inline]
fn bitand(self, other: $BitFlags) -> $BitFlags {
$BitFlags { bits: self.bits & other.bits }
fn bitand(self, other: Self) -> Self {
Self { bits: self.bits & other.bits }
}
}

impl $crate::_core::ops::BitAndAssign for $BitFlags {

/// Disables all flags disabled in the set.
#[inline]
fn bitand_assign(&mut self, other: $BitFlags) {
fn bitand_assign(&mut self, other: Self) {
self.bits &= other.bits;
}
}

impl $crate::_core::ops::Sub for $BitFlags {
type Output = $BitFlags;
type Output = Self;

/// Returns the set difference of the two sets of flags.
#[inline]
fn sub(self, other: $BitFlags) -> $BitFlags {
$BitFlags { bits: self.bits & !other.bits }
fn sub(self, other: Self) -> Self {
Self { bits: self.bits & !other.bits }
}
}

impl $crate::_core::ops::SubAssign for $BitFlags {

/// Disables all flags enabled in the set.
#[inline]
fn sub_assign(&mut self, other: $BitFlags) {
fn sub_assign(&mut self, other: Self) {
self.bits &= !other.bits;
}
}

impl $crate::_core::ops::Not for $BitFlags {
type Output = $BitFlags;
type Output = Self;

/// Returns the complement of this set of flags.
#[inline]
fn not(self) -> $BitFlags {
$BitFlags { bits: !self.bits } & $BitFlags::all()
fn not(self) -> Self {
Self { bits: !self.bits } & Self::all()
}
}

impl $crate::_core::iter::Extend<$BitFlags> for $BitFlags {
fn extend<T: $crate::_core::iter::IntoIterator<Item=$BitFlags>>(&mut self, iterator: T) {
fn extend<T: $crate::_core::iter::IntoIterator<Item=Self>>(&mut self, iterator: T) {
for item in iterator {
self.insert(item)
}
}
}

impl $crate::_core::iter::FromIterator<$BitFlags> for $BitFlags {
fn from_iter<T: $crate::_core::iter::IntoIterator<Item=$BitFlags>>(iterator: T) -> $BitFlags {
fn from_iter<T: $crate::_core::iter::IntoIterator<Item=Self>>(iterator: T) -> Self {
let mut result = Self::empty();
result.extend(iterator);
result
Expand Down Expand Up @@ -912,16 +910,6 @@ macro_rules! __impl_bitflags {
};
}

// Same as std::stringify but callable from __impl_bitflags, which needs to use
// local_inner_macros so can only directly call macros from this crate.
#[macro_export]
#[doc(hidden)]
macro_rules! __bitflags_stringify {
($s:ident) => {
stringify!($s)
};
}

#[cfg(feature = "example_generated")]
pub mod example_generated;

Expand Down
9 changes: 0 additions & 9 deletions tests/redefine_core.rs

This file was deleted.

22 changes: 22 additions & 0 deletions tests/redefinition.rs
@@ -0,0 +1,22 @@
use bitflags::bitflags;

// Checks for possible errors caused by overriding names used by `bitflags!` internally.

mod core {}
mod _core {}

#[allow(unused_macros)]
macro_rules! stringify {
($($t:tt)*) => { "..." };
}

bitflags! {
struct Test: u8 {
const A = 1;
}
}

#[test]
fn stringify() {
assert_eq!(format!("{:?}", Test::A), "A");
}

0 comments on commit 9defa89

Please sign in to comment.