Snap for 11914274 from 303873469e475b87b5c155fc210da4d5db92991d to 24Q3-release

Change-Id: Iaade1dd523dadae02eeb5a7c0ebcdf913481fa52
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index 49de48e..e24ee9b 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,6 +1,6 @@
 {
   "git": {
-    "sha1": "a5f9ce20e9d18444aa9b20c8fea9c00155cbafa3"
+    "sha1": "e5ff0ca84b6aa5c9989c924ebe02527959bb7d02"
   },
   "path_in_vcs": ""
 }
\ No newline at end of file
diff --git a/Android.bp b/Android.bp
index 365685f..20ce3a5 100644
--- a/Android.bp
+++ b/Android.bp
@@ -44,7 +44,7 @@
     host_supported: true,
     crate_name: "bitflags",
     cargo_env_compat: true,
-    cargo_pkg_version: "2.4.2",
+    cargo_pkg_version: "2.5.0",
     crate_root: "src/lib.rs",
     edition: "2021",
     apex_available: [
diff --git a/CHANGELOG.md b/CHANGELOG.md
index fd435d2..5d410fc 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,14 @@
+# 2.5.0
+
+## What's Changed
+* Derive `Debug` for `Flag<B>` by @tgross35 in https://github.com/bitflags/bitflags/pull/398
+* Support truncating or strict-named variants of parsing and formatting by @KodrAus in https://github.com/bitflags/bitflags/pull/400
+
+## New Contributors
+* @tgross35 made their first contribution in https://github.com/bitflags/bitflags/pull/398
+
+**Full Changelog**: https://github.com/bitflags/bitflags/compare/2.4.2...2.5.0
+
 # 2.4.2
 
 ## What's Changed
diff --git a/Cargo.toml b/Cargo.toml
index 43595a5..b274599 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -13,7 +13,7 @@
 edition = "2021"
 rust-version = "1.56.0"
 name = "bitflags"
-version = "2.4.2"
+version = "2.5.0"
 authors = ["The Rust Project Developers"]
 exclude = [
     "/tests",
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index 764bfdc..edc4f02 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -1,7 +1,7 @@
 [package]
 name = "bitflags"
 # NB: When modifying, also modify the number in readme (for breaking changes)
-version = "2.4.2"
+version = "2.5.0"
 edition = "2021"
 rust-version = "1.56.0"
 authors = ["The Rust Project Developers"]
diff --git a/METADATA b/METADATA
index 2863dcb..77080ae 100644
--- a/METADATA
+++ b/METADATA
@@ -8,13 +8,13 @@
   license_type: NOTICE
   last_upgrade_date {
     year: 2024
-    month: 2
-    day: 21
+    month: 5
+    day: 31
   }
   homepage: "https://crates.io/crates/bitflags"
   identifier {
     type: "Archive"
-    value: "https://static.crates.io/crates/bitflags/bitflags-2.4.2.crate"
-    version: "2.4.2"
+    value: "https://static.crates.io/crates/bitflags/bitflags-2.5.0.crate"
+    version: "2.5.0"
   }
 }
diff --git a/README.md b/README.md
index a560bc8..652a880 100644
--- a/README.md
+++ b/README.md
@@ -28,7 +28,7 @@
 
 ```toml
 [dependencies]
-bitflags = "2.4.2"
+bitflags = "2.5.0"
 ```
 
 and this to your source code:
diff --git a/patches/rules.mk.diff b/patches/rules.mk.diff
index 05c3bef..47616d9 100644
--- a/patches/rules.mk.diff
+++ b/patches/rules.mk.diff
@@ -2,12 +2,13 @@
 index ccb9711..8005071 100644
 --- b/rules.mk
 +++ a/rules.mk
-@@ -9,8 +9,6 @@ MODULE_SRCS := \
- 
+@@ -8,4 +8,9 @@ MODULE_SRCS := \
+ $(LOCAL_DIR)/src/lib.rs \
+  
  MODULE_RUST_EDITION := 2021
- MODULE_LIBRARY_DEPS := \
--	external/rust/crates/arbitrary \
--	external/rust/crates/bytemuck \
- 	trusty/user/base/lib/libcompiler_builtins-rust \
- 	trusty/user/base/lib/libcore-rust \
- 	external/rust/crates/serde \
++MODULE_LIBRARY_DEPS := \
++	trusty/user/base/lib/libcompiler_builtins-rust \
++	trusty/user/base/lib/libcore-rust \
++	external/rust/crates/serde \
++
+ include make/library.mk
diff --git a/src/lib.rs b/src/lib.rs
index 18270f7..606b583 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -17,7 +17,7 @@
 
 ```toml
 [dependencies.bitflags]
-version = "2.4.2"
+version = "2.5.0"
 ```
 
 ## Generating flags types
@@ -253,7 +253,8 @@
 
 #[doc(hidden)]
 pub mod __private {
-    #[allow(unused_imports)] // Easier than conditionally checking any optional external dependencies
+    #[allow(unused_imports)]
+    // Easier than conditionally checking any optional external dependencies
     pub use crate::{external::__private::*, traits::__private::*};
 
     pub use core;
diff --git a/src/parser.rs b/src/parser.rs
index 130dc2e..34b432d 100644
--- a/src/parser.rs
+++ b/src/parser.rs
@@ -77,8 +77,10 @@
     fmt::Result::Ok(())
 }
 
+#[cfg(feature = "serde")]
 pub(crate) struct AsDisplay<'a, B>(pub(crate) &'a B);
 
+#[cfg(feature = "serde")]
 impl<'a, B: Flags> fmt::Display for AsDisplay<'a, B>
 where
     B::Bits: WriteHex,
@@ -135,6 +137,89 @@
 }
 
 /**
+Write a flags value as text, ignoring any unknown bits.
+*/
+pub fn to_writer_truncate<B: Flags>(flags: &B, writer: impl Write) -> Result<(), fmt::Error>
+where
+    B::Bits: WriteHex,
+{
+    to_writer(&B::from_bits_truncate(flags.bits()), writer)
+}
+
+/**
+Parse a flags value from text.
+
+This function will fail on any names that don't correspond to defined flags.
+Unknown bits will be ignored.
+*/
+pub fn from_str_truncate<B: Flags>(input: &str) -> Result<B, ParseError>
+where
+    B::Bits: ParseHex,
+{
+    Ok(B::from_bits_truncate(from_str::<B>(input)?.bits()))
+}
+
+/**
+Write only the contained, defined, named flags in a flags value as text.
+*/
+pub fn to_writer_strict<B: Flags>(flags: &B, mut writer: impl Write) -> Result<(), fmt::Error> {
+    // This is a simplified version of `to_writer` that ignores
+    // any bits not corresponding to a named flag
+
+    let mut first = true;
+    let mut iter = flags.iter_names();
+    for (name, _) in &mut iter {
+        if !first {
+            writer.write_str(" | ")?;
+        }
+
+        first = false;
+        writer.write_str(name)?;
+    }
+
+    fmt::Result::Ok(())
+}
+
+/**
+Parse a flags value from text.
+
+This function will fail on any names that don't correspond to defined flags.
+This function will fail to parse hex values.
+*/
+pub fn from_str_strict<B: Flags>(input: &str) -> Result<B, ParseError> {
+    // This is a simplified version of `from_str` that ignores
+    // any bits not corresponding to a named flag
+
+    let mut parsed_flags = B::empty();
+
+    // If the input is empty then return an empty set of flags
+    if input.trim().is_empty() {
+        return Ok(parsed_flags);
+    }
+
+    for flag in input.split('|') {
+        let flag = flag.trim();
+
+        // If the flag is empty then we've got missing input
+        if flag.is_empty() {
+            return Err(ParseError::empty_flag());
+        }
+
+        // If the flag starts with `0x` then it's a hex number
+        // These aren't supported in the strict parser
+        if flag.starts_with("0x") {
+            return Err(ParseError::invalid_hex_flag("unsupported hex flag value"));
+        }
+
+        let parsed_flag = B::from_name(flag).ok_or_else(|| ParseError::invalid_named_flag(flag))?;
+
+        parsed_flags.insert(parsed_flag);
+    }
+
+    Ok(parsed_flags)
+}
+
+/**
 Encode a value as a hex string.
 
 Implementors of this trait should not write the `0x` prefix.
diff --git a/src/tests/parser.rs b/src/tests/parser.rs
index b370785..fb27225 100644
--- a/src/tests/parser.rs
+++ b/src/tests/parser.rs
@@ -1,9 +1,6 @@
 use super::*;
 
-use crate::{
-    parser::{from_str, to_writer},
-    Flags,
-};
+use crate::{parser::*, Flags};
 
 #[test]
 #[cfg(not(miri))] // Very slow in miri
@@ -22,6 +19,51 @@
     }
 }
 
+#[test]
+#[cfg(not(miri))] // Very slow in miri
+fn roundtrip_truncate() {
+    let mut s = String::new();
+
+    for a in 0u8..=255 {
+        for b in 0u8..=255 {
+            let f = TestFlags::from_bits_retain(a | b);
+
+            s.clear();
+            to_writer_truncate(&f, &mut s).unwrap();
+
+            assert_eq!(
+                TestFlags::from_bits_truncate(f.bits()),
+                from_str_truncate::<TestFlags>(&s).unwrap()
+            );
+        }
+    }
+}
+
+#[test]
+#[cfg(not(miri))] // Very slow in miri
+fn roundtrip_strict() {
+    let mut s = String::new();
+
+    for a in 0u8..=255 {
+        for b in 0u8..=255 {
+            let f = TestFlags::from_bits_retain(a | b);
+
+            s.clear();
+            to_writer_strict(&f, &mut s).unwrap();
+
+            let mut strict = TestFlags::empty();
+            for (_, flag) in f.iter_names() {
+                strict |= flag;
+            }
+            let f = strict;
+
+            if let Ok(s) = from_str_strict::<TestFlags>(&s) {
+                assert_eq!(f, s);
+            }
+        }
+    }
+}
+
 mod from_str {
     use super::*;
 
@@ -97,6 +139,8 @@
 
         assert_eq!("ABC", write(TestFlagsInvert::all()));
 
+        assert_eq!("0x1", write(TestOverlapping::from_bits_retain(1)));
+
         assert_eq!("A", write(TestOverlappingFull::C));
         assert_eq!(
             "A | D",
@@ -114,3 +158,175 @@
         s
     }
 }
+
+mod from_str_truncate {
+    use super::*;
+
+    #[test]
+    fn valid() {
+        assert_eq!(0, from_str_truncate::<TestFlags>("").unwrap().bits());
+
+        assert_eq!(1, from_str_truncate::<TestFlags>("A").unwrap().bits());
+        assert_eq!(1, from_str_truncate::<TestFlags>(" A ").unwrap().bits());
+        assert_eq!(
+            1 | 1 << 1 | 1 << 2,
+            from_str_truncate::<TestFlags>("A | B | C").unwrap().bits()
+        );
+        assert_eq!(
+            1 | 1 << 1 | 1 << 2,
+            from_str_truncate::<TestFlags>("A\n|\tB\r\n|   C ")
+                .unwrap()
+                .bits()
+        );
+        assert_eq!(
+            1 | 1 << 1 | 1 << 2,
+            from_str_truncate::<TestFlags>("A|B|C").unwrap().bits()
+        );
+
+        assert_eq!(0, from_str_truncate::<TestFlags>("0x8").unwrap().bits());
+        assert_eq!(1, from_str_truncate::<TestFlags>("A | 0x8").unwrap().bits());
+        assert_eq!(
+            1 | 1 << 1,
+            from_str_truncate::<TestFlags>("0x1 | 0x8 | B")
+                .unwrap()
+                .bits()
+        );
+
+        assert_eq!(
+            1 | 1 << 1,
+            from_str_truncate::<TestUnicode>("一 | 二").unwrap().bits()
+        );
+    }
+}
+
+mod to_writer_truncate {
+    use super::*;
+
+    #[test]
+    fn cases() {
+        assert_eq!("", write(TestFlags::empty()));
+        assert_eq!("A", write(TestFlags::A));
+        assert_eq!("A | B | C", write(TestFlags::all()));
+        assert_eq!("", write(TestFlags::from_bits_retain(1 << 3)));
+        assert_eq!(
+            "A",
+            write(TestFlags::A | TestFlags::from_bits_retain(1 << 3))
+        );
+
+        assert_eq!("", write(TestZero::ZERO));
+
+        assert_eq!("ABC", write(TestFlagsInvert::all()));
+
+        assert_eq!("0x1", write(TestOverlapping::from_bits_retain(1)));
+
+        assert_eq!("A", write(TestOverlappingFull::C));
+        assert_eq!(
+            "A | D",
+            write(TestOverlappingFull::C | TestOverlappingFull::D)
+        );
+    }
+
+    fn write<F: Flags>(value: F) -> String
+    where
+        F::Bits: crate::parser::WriteHex,
+    {
+        let mut s = String::new();
+
+        to_writer_truncate(&value, &mut s).unwrap();
+        s
+    }
+}
+
+mod from_str_strict {
+    use super::*;
+
+    #[test]
+    fn valid() {
+        assert_eq!(0, from_str_strict::<TestFlags>("").unwrap().bits());
+
+        assert_eq!(1, from_str_strict::<TestFlags>("A").unwrap().bits());
+        assert_eq!(1, from_str_strict::<TestFlags>(" A ").unwrap().bits());
+        assert_eq!(
+            1 | 1 << 1 | 1 << 2,
+            from_str_strict::<TestFlags>("A | B | C").unwrap().bits()
+        );
+        assert_eq!(
+            1 | 1 << 1 | 1 << 2,
+            from_str_strict::<TestFlags>("A\n|\tB\r\n|   C ")
+                .unwrap()
+                .bits()
+        );
+        assert_eq!(
+            1 | 1 << 1 | 1 << 2,
+            from_str_strict::<TestFlags>("A|B|C").unwrap().bits()
+        );
+
+        assert_eq!(
+            1 | 1 << 1,
+            from_str_strict::<TestUnicode>("一 | 二").unwrap().bits()
+        );
+    }
+
+    #[test]
+    fn invalid() {
+        assert!(from_str_strict::<TestFlags>("a")
+            .unwrap_err()
+            .to_string()
+            .starts_with("unrecognized named flag"));
+        assert!(from_str_strict::<TestFlags>("A & B")
+            .unwrap_err()
+            .to_string()
+            .starts_with("unrecognized named flag"));
+
+        assert!(from_str_strict::<TestFlags>("0x1")
+            .unwrap_err()
+            .to_string()
+            .starts_with("invalid hex flag"));
+        assert!(from_str_strict::<TestFlags>("0xg")
+            .unwrap_err()
+            .to_string()
+            .starts_with("invalid hex flag"));
+        assert!(from_str_strict::<TestFlags>("0xffffffffffff")
+            .unwrap_err()
+            .to_string()
+            .starts_with("invalid hex flag"));
+    }
+}
+
+mod to_writer_strict {
+    use super::*;
+
+    #[test]
+    fn cases() {
+        assert_eq!("", write(TestFlags::empty()));
+        assert_eq!("A", write(TestFlags::A));
+        assert_eq!("A | B | C", write(TestFlags::all()));
+        assert_eq!("", write(TestFlags::from_bits_retain(1 << 3)));
+        assert_eq!(
+            "A",
+            write(TestFlags::A | TestFlags::from_bits_retain(1 << 3))
+        );
+
+        assert_eq!("", write(TestZero::ZERO));
+
+        assert_eq!("ABC", write(TestFlagsInvert::all()));
+
+        assert_eq!("", write(TestOverlapping::from_bits_retain(1)));
+
+        assert_eq!("A", write(TestOverlappingFull::C));
+        assert_eq!(
+            "A | D",
+            write(TestOverlappingFull::C | TestOverlappingFull::D)
+        );
+    }
+
+    fn write<F: Flags>(value: F) -> String
+    where
+        F::Bits: crate::parser::WriteHex,
+    {
+        let mut s = String::new();
+
+        to_writer_strict(&value, &mut s).unwrap();
+        s
+    }
+}
diff --git a/src/traits.rs b/src/traits.rs
index 2823514..3905d7d 100644
--- a/src/traits.rs
+++ b/src/traits.rs
@@ -11,6 +11,7 @@
 /**
 A defined flags value that may be named or unnamed.
 */
+#[derive(Debug)]
 pub struct Flag<B> {
     name: &'static str,
     value: B,