Repository: bitflags/bitflags (rust)

Issue:
from_bits accepts non existing flags
```rs
    #[test]
    fn test_from_bits_edge_cases() {
        bitflags! {
            struct Flags: u8 {
                const A = 0b00000001;
                const BC = 0b00000110;
            }
        }


        let flags = Flags::from_bits(0b00000100);
        assert!(flags.is_none());
    }
```

Unless I'm missing something this test should pass but it fails cause from_bits accepts flags that are not declared. 

https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=6fd4adbddc8b8740cbd35af2306073ca

This is related to this issue in the implementation of iterators in this PR https://github.com/bitflags/bitflags/pull/204#issuecomment-950304444 Using `from_bits` instead of `from_bits_unchecked` should allow to produce any valid flags that are not a combination of other flags but at the moment `from_bits` seems to accept any flag that is included in a combination even if it's not declared. I can try to send a PR. 

Pull request:
from_bits_(truncate) fail with composite flags
When a bitflags type contains composite flags like:

```rs
bitflags! {
    struct Flags: u8 {
            const A = 0b00000001;
            const BC = 0b00000110;
    }
}
```

from_bits and from_bits_truncate would not work as expected allowing flags that are not declared.

Fixes #275

Patch:
diff --git a/src/lib.rs b/src/lib.rs
index ab7656e..b9d77f7 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -559,10 +559,11 @@ macro_rules! __impl_bitflags {
             /// representation contains bits that do not correspond to a flag.
             #[inline]
             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 })
+                let truncated = Self::from_bits_truncate(bits).bits;
+                if truncated == bits {
+                    Some(Self{ bits })
                 } else {
-                    $crate::_core::option::Option::None
+                    None
                 }
             }
 
@@ -570,7 +571,22 @@ macro_rules! __impl_bitflags {
             /// that do not correspond to flags.
             #[inline]
             pub const fn from_bits_truncate(bits: $T) -> Self {
-                Self { bits: bits & Self::all().bits }
+                if bits == 0 {
+                    return Self{ bits }
+                }
+
+                #[allow(unused_mut)]
+                let mut truncated = 0;
+
+                $(
+                    #[allow(unused_doc_comments, unused_attributes)]
+                    $(#[$attr $($args)*])*
+                    if bits & Self::$Flag.bits == Self::$Flag.bits {
+                        truncated |= Self::$Flag.bits
+                    }
+                )*
+
+                Self { bits: truncated }
             }
 
             /// Convert from underlying bit representation, preserving all
@@ -1891,6 +1907,37 @@ mod tests {
         }
     }
 
+    #[test]
+    fn test_from_bits_edge_cases() {
+        bitflags! {
+            struct Flags: u8 {
+                const A = 0b00000001;
+                const BC = 0b00000110;
+            }
+        }
+
+
+        let flags = Flags::from_bits(0b00000100);
+        assert_eq!(flags, None);
+        let flags = Flags::from_bits(0b00000101);
+        assert_eq!(flags, None);
+    }
+
+    #[test]
+    fn test_from_bits_truncate_edge_cases() {
+        bitflags! {
+            struct Flags: u8 {
+                const A = 0b00000001;
+                const BC = 0b00000110;
+            }
+        }
+
+        let flags = Flags::from_bits_truncate(0b00000100);
+        assert_eq!(flags, Flags::empty());
+        let flags = Flags::from_bits_truncate(0b00000101);
+        assert_eq!(flags, Flags::A);
+    }
+  
     #[test]
     fn test_iter() {
         bitflags! {
@@ -1924,22 +1971,4 @@ mod tests {
         assert_eq!(iter.next().unwrap(), Flags::THREE);
         assert_eq!(iter.next(), None);
     }
-
-    #[test]
-    fn test_iter_edge_cases() {
-        bitflags! {
-            struct Flags: u8 {
-                const A = 0b00000001;
-                const BC = 0b00000110;
-            }
-        }
-
-
-        let flags = Flags::all();
-        assert_eq!(flags.iter().count(), 2);
-        let mut iter = flags.iter();
-        assert_eq!(iter.next().unwrap(), Flags::A);
-        assert_eq!(iter.next().unwrap(), Flags::BC);
-        assert_eq!(iter.next(), None);
-    }
 }


Test patch:
diff --git a/tests/compile-fail/non_integer_base/all_defined.stderr.beta b/tests/compile-fail/non_integer_base/all_defined.stderr.beta
index 6fada42..0607f23 100644
--- a/tests/compile-fail/non_integer_base/all_defined.stderr.beta
+++ b/tests/compile-fail/non_integer_base/all_defined.stderr.beta
@@ -49,8 +49,41 @@ error[E0308]: mismatched types
     = note: this error originates in the macro `__impl_bitflags` (in Nightly builds, run with -Z macro-backtrace for more info)
 help: try wrapping the expression in `MyInt`
     |
-562 |                 if (bits & !Self::all().bits()) == MyInt(0) {
-    |                                                    ++++++ +
+574 |                 if bits == MyInt(0) {
+    |                            ++++++ +
+
+error[E0277]: no implementation for `{integer} |= MyInt`
+   --> $DIR/all_defined.rs:115:1
+    |
+115 | / bitflags! {
+116 | |     struct Flags128: MyInt {
+117 | |         const A = MyInt(0b0000_0001u8);
+118 | |         const B = MyInt(0b0000_0010u8);
+119 | |         const C = MyInt(0b0000_0100u8);
+120 | |     }
+121 | | }
+    | |_^ no implementation for `{integer} |= MyInt`
+    |
+    = help: the trait `BitOrAssign<MyInt>` is not implemented for `{integer}`
+    = note: this error originates in the macro `__impl_bitflags` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0308]: mismatched types
+   --> $DIR/all_defined.rs:115:1
+    |
+115 | / bitflags! {
+116 | |     struct Flags128: MyInt {
+117 | |         const A = MyInt(0b0000_0001u8);
+118 | |         const B = MyInt(0b0000_0010u8);
+119 | |         const C = MyInt(0b0000_0100u8);
+120 | |     }
+121 | | }
+    | |_^ expected struct `MyInt`, found integer
+    |
+    = note: this error originates in the macro `__impl_bitflags` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: try wrapping the expression in `MyInt`
+    |
+589 |                 Self { bits: MyInt(truncated) }
+    |                              ++++++         +
 
 error[E0308]: mismatched types
    --> $DIR/all_defined.rs:115:1