Upgrade bytes to 1.5.0 am: 59606a0308

Original change: https://android-review.googlesource.com/c/platform/external/rust/crates/bytes/+/2941305

Change-Id: I28d56a25567426ba40f2431995632bd12475a522
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index b4c4c4e..ebd71a0 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,6 +1,6 @@
 {
   "git": {
-    "sha1": "21ed3328364716fa30a4bf7502c913bbf0a90f45"
+    "sha1": "74e6e200fd671340d4d4a874f83776def04f6c7b"
   },
   "path_in_vcs": ""
 }
\ No newline at end of file
diff --git a/Android.bp b/Android.bp
index ee61c32..d605d03 100644
--- a/Android.bp
+++ b/Android.bp
@@ -23,7 +23,7 @@
     host_supported: true,
     crate_name: "test_buf",
     cargo_env_compat: true,
-    cargo_pkg_version: "1.4.0",
+    cargo_pkg_version: "1.5.0",
     srcs: ["tests/test_buf.rs"],
     test_suites: ["general-tests"],
     auto_gen_config: true,
@@ -48,7 +48,7 @@
     host_supported: true,
     crate_name: "test_buf_mut",
     cargo_env_compat: true,
-    cargo_pkg_version: "1.4.0",
+    cargo_pkg_version: "1.5.0",
     srcs: ["tests/test_buf_mut.rs"],
     test_suites: ["general-tests"],
     auto_gen_config: true,
@@ -73,7 +73,7 @@
     host_supported: true,
     crate_name: "test_bytes",
     cargo_env_compat: true,
-    cargo_pkg_version: "1.4.0",
+    cargo_pkg_version: "1.5.0",
     srcs: ["tests/test_bytes.rs"],
     test_suites: ["general-tests"],
     auto_gen_config: true,
@@ -98,7 +98,7 @@
     host_supported: true,
     crate_name: "test_bytes_odd_alloc",
     cargo_env_compat: true,
-    cargo_pkg_version: "1.4.0",
+    cargo_pkg_version: "1.5.0",
     srcs: ["tests/test_bytes_odd_alloc.rs"],
     test_suites: ["general-tests"],
     auto_gen_config: true,
@@ -123,7 +123,7 @@
     host_supported: true,
     crate_name: "test_bytes_vec_alloc",
     cargo_env_compat: true,
-    cargo_pkg_version: "1.4.0",
+    cargo_pkg_version: "1.5.0",
     srcs: ["tests/test_bytes_vec_alloc.rs"],
     test_suites: ["general-tests"],
     auto_gen_config: true,
@@ -148,7 +148,7 @@
     host_supported: true,
     crate_name: "test_chain",
     cargo_env_compat: true,
-    cargo_pkg_version: "1.4.0",
+    cargo_pkg_version: "1.5.0",
     srcs: ["tests/test_chain.rs"],
     test_suites: ["general-tests"],
     auto_gen_config: true,
@@ -173,7 +173,7 @@
     host_supported: true,
     crate_name: "test_debug",
     cargo_env_compat: true,
-    cargo_pkg_version: "1.4.0",
+    cargo_pkg_version: "1.5.0",
     srcs: ["tests/test_debug.rs"],
     test_suites: ["general-tests"],
     auto_gen_config: true,
@@ -198,7 +198,7 @@
     host_supported: true,
     crate_name: "test_iter",
     cargo_env_compat: true,
-    cargo_pkg_version: "1.4.0",
+    cargo_pkg_version: "1.5.0",
     srcs: ["tests/test_iter.rs"],
     test_suites: ["general-tests"],
     auto_gen_config: true,
@@ -223,7 +223,7 @@
     host_supported: true,
     crate_name: "test_reader",
     cargo_env_compat: true,
-    cargo_pkg_version: "1.4.0",
+    cargo_pkg_version: "1.5.0",
     srcs: ["tests/test_reader.rs"],
     test_suites: ["general-tests"],
     auto_gen_config: true,
@@ -248,7 +248,7 @@
     host_supported: true,
     crate_name: "test_serde",
     cargo_env_compat: true,
-    cargo_pkg_version: "1.4.0",
+    cargo_pkg_version: "1.5.0",
     srcs: ["tests/test_serde.rs"],
     test_suites: ["general-tests"],
     auto_gen_config: true,
@@ -273,7 +273,7 @@
     host_supported: true,
     crate_name: "test_take",
     cargo_env_compat: true,
-    cargo_pkg_version: "1.4.0",
+    cargo_pkg_version: "1.5.0",
     srcs: ["tests/test_take.rs"],
     test_suites: ["general-tests"],
     auto_gen_config: true,
@@ -298,7 +298,7 @@
     host_supported: true,
     crate_name: "bytes",
     cargo_env_compat: true,
-    cargo_pkg_version: "1.4.0",
+    cargo_pkg_version: "1.5.0",
     srcs: ["src/lib.rs"],
     edition: "2018",
     features: [
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a1bad4a..47e4880 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,14 @@
+# 1.5.0 (September 7, 2023)
+
+### Added
+
+- Add `UninitSlice::{new,init}` (#598, #599)
+- Implement `BufMut` for `&mut [MaybeUninit<u8>]` (#597)
+
+### Changed
+
+- Mark `BytesMut::extend_from_slice` as inline (#595)
+
 # 1.4.0 (January 31, 2023)
 
 ### Added
diff --git a/Cargo.toml b/Cargo.toml
index d0acb34..2c163aa 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -12,7 +12,7 @@
 [package]
 edition = "2018"
 name = "bytes"
-version = "1.4.0"
+version = "1.5.0"
 authors = [
     "Carl Lerche <me@carllerche.com>",
     "Sean McArthur <sean@seanmonstar.com>",
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index 4a96ec1..06b19e6 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -4,7 +4,7 @@
 # When releasing to crates.io:
 # - Update CHANGELOG.md.
 # - Create "v1.x.y" git tag.
-version = "1.4.0"
+version = "1.5.0"
 license = "MIT"
 authors = [
     "Carl Lerche <me@carllerche.com>",
diff --git a/METADATA b/METADATA
index 8f9837f..c5c023c 100644
--- a/METADATA
+++ b/METADATA
@@ -1,23 +1,20 @@
 # This project was upgraded with external_updater.
-# Usage: tools/external_updater/updater.sh update rust/crates/bytes
-# For more info, check https://cs.android.com/android/platform/superproject/+/master:tools/external_updater/README.md
+# Usage: tools/external_updater/updater.sh update external/rust/crates/bytes
+# For more info, check https://cs.android.com/android/platform/superproject/+/main:tools/external_updater/README.md
 
 name: "bytes"
 description: "Types and traits for working with bytes"
 third_party {
-  url {
-    type: HOMEPAGE
-    value: "https://crates.io/crates/bytes"
-  }
-  url {
-    type: ARCHIVE
-    value: "https://static.crates.io/crates/bytes/bytes-1.4.0.crate"
-  }
-  version: "1.4.0"
   license_type: NOTICE
   last_upgrade_date {
-    year: 2023
-    month: 2
-    day: 15
+    year: 2024
+    month: 1
+    day: 31
+  }
+  homepage: "https://crates.io/crates/bytes"
+  identifier {
+    type: "Archive"
+    value: "https://static.crates.io/crates/bytes/bytes-1.5.0.crate"
+    version: "1.5.0"
   }
 }
diff --git a/src/buf/buf_mut.rs b/src/buf/buf_mut.rs
index 685fcc7..c2ac39d 100644
--- a/src/buf/buf_mut.rs
+++ b/src/buf/buf_mut.rs
@@ -1419,6 +1419,41 @@
     }
 }
 
+unsafe impl BufMut for &mut [core::mem::MaybeUninit<u8>] {
+    #[inline]
+    fn remaining_mut(&self) -> usize {
+        self.len()
+    }
+
+    #[inline]
+    fn chunk_mut(&mut self) -> &mut UninitSlice {
+        UninitSlice::uninit(self)
+    }
+
+    #[inline]
+    unsafe fn advance_mut(&mut self, cnt: usize) {
+        // Lifetime dance taken from `impl Write for &mut [u8]`.
+        let (_, b) = core::mem::replace(self, &mut []).split_at_mut(cnt);
+        *self = b;
+    }
+
+    #[inline]
+    fn put_slice(&mut self, src: &[u8]) {
+        self.chunk_mut()[..src.len()].copy_from_slice(src);
+        unsafe {
+            self.advance_mut(src.len());
+        }
+    }
+
+    fn put_bytes(&mut self, val: u8, cnt: usize) {
+        assert!(self.remaining_mut() >= cnt);
+        unsafe {
+            ptr::write_bytes(self.as_mut_ptr() as *mut u8, val, cnt);
+            self.advance_mut(cnt);
+        }
+    }
+}
+
 unsafe impl BufMut for Vec<u8> {
     #[inline]
     fn remaining_mut(&self) -> usize {
diff --git a/src/buf/uninit_slice.rs b/src/buf/uninit_slice.rs
index 3161a14..c5d86e8 100644
--- a/src/buf/uninit_slice.rs
+++ b/src/buf/uninit_slice.rs
@@ -22,10 +22,44 @@
 pub struct UninitSlice([MaybeUninit<u8>]);
 
 impl UninitSlice {
-    pub(crate) fn from_slice(slice: &mut [MaybeUninit<u8>]) -> &mut UninitSlice {
+    /// Creates a `&mut UninitSlice` wrapping a slice of initialised memory.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::buf::UninitSlice;
+    ///
+    /// let mut buffer = [0u8; 64];
+    /// let slice = UninitSlice::new(&mut buffer[..]);
+    /// ```
+    #[inline]
+    pub fn new(slice: &mut [u8]) -> &mut UninitSlice {
+        unsafe { &mut *(slice as *mut [u8] as *mut [MaybeUninit<u8>] as *mut UninitSlice) }
+    }
+
+    /// Creates a `&mut UninitSlice` wrapping a slice of uninitialised memory.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::buf::UninitSlice;
+    /// use core::mem::MaybeUninit;
+    ///
+    /// let mut buffer = [MaybeUninit::uninit(); 64];
+    /// let slice = UninitSlice::uninit(&mut buffer[..]);
+    ///
+    /// let mut vec = Vec::with_capacity(1024);
+    /// let spare: &mut UninitSlice = vec.spare_capacity_mut().into();
+    /// ```
+    #[inline]
+    pub fn uninit(slice: &mut [MaybeUninit<u8>]) -> &mut UninitSlice {
         unsafe { &mut *(slice as *mut [MaybeUninit<u8>] as *mut UninitSlice) }
     }
 
+    fn uninit_ref(slice: &[MaybeUninit<u8>]) -> &UninitSlice {
+        unsafe { &*(slice as *const [MaybeUninit<u8>] as *const UninitSlice) }
+    }
+
     /// Create a `&mut UninitSlice` from a pointer and a length.
     ///
     /// # Safety
@@ -48,7 +82,7 @@
     pub unsafe fn from_raw_parts_mut<'a>(ptr: *mut u8, len: usize) -> &'a mut UninitSlice {
         let maybe_init: &mut [MaybeUninit<u8>] =
             core::slice::from_raw_parts_mut(ptr as *mut _, len);
-        Self::from_slice(maybe_init)
+        Self::uninit(maybe_init)
     }
 
     /// Write a single byte at the specified offset.
@@ -179,6 +213,18 @@
     }
 }
 
+impl<'a> From<&'a mut [u8]> for &'a mut UninitSlice {
+    fn from(slice: &'a mut [u8]) -> Self {
+        UninitSlice::new(slice)
+    }
+}
+
+impl<'a> From<&'a mut [MaybeUninit<u8>]> for &'a mut UninitSlice {
+    fn from(slice: &'a mut [MaybeUninit<u8>]) -> Self {
+        UninitSlice::uninit(slice)
+    }
+}
+
 macro_rules! impl_index {
     ($($t:ty),*) => {
         $(
@@ -187,16 +233,14 @@
 
                 #[inline]
                 fn index(&self, index: $t) -> &UninitSlice {
-                    let maybe_uninit: &[MaybeUninit<u8>] = &self.0[index];
-                    unsafe { &*(maybe_uninit as *const [MaybeUninit<u8>] as *const UninitSlice) }
+                    UninitSlice::uninit_ref(&self.0[index])
                 }
             }
 
             impl IndexMut<$t> for UninitSlice {
                 #[inline]
                 fn index_mut(&mut self, index: $t) -> &mut UninitSlice {
-                    let maybe_uninit: &mut [MaybeUninit<u8>] = &mut self.0[index];
-                    unsafe { &mut *(maybe_uninit as *mut [MaybeUninit<u8>] as *mut UninitSlice) }
+                    UninitSlice::uninit(&mut self.0[index])
                 }
             }
         )*
diff --git a/src/bytes_mut.rs b/src/bytes_mut.rs
index 70613b2..c5c2e52 100644
--- a/src/bytes_mut.rs
+++ b/src/bytes_mut.rs
@@ -761,6 +761,7 @@
     ///
     /// assert_eq!(b"aaabbbcccddd", &buf[..]);
     /// ```
+    #[inline]
     pub fn extend_from_slice(&mut self, extend: &[u8]) {
         let cnt = extend.len();
         self.reserve(cnt);
@@ -1101,7 +1102,7 @@
         if self.capacity() == self.len() {
             self.reserve(64);
         }
-        UninitSlice::from_slice(self.spare_capacity_mut())
+        self.spare_capacity_mut().into()
     }
 
     // Specialize these methods so they can skip checking `remaining_mut`
diff --git a/tests/test_buf.rs b/tests/test_buf.rs
index fbad003..3940f92 100644
--- a/tests/test_buf.rs
+++ b/tests/test_buf.rs
@@ -72,6 +72,7 @@
     assert_eq!(b"world piece", &out[..]);
 }
 
+#[allow(unused_allocation)] // This is intentional.
 #[test]
 fn test_deref_buf_forwards() {
     struct Special;
diff --git a/tests/test_buf_mut.rs b/tests/test_buf_mut.rs
index 53f4e86..33aa680 100644
--- a/tests/test_buf_mut.rs
+++ b/tests/test_buf_mut.rs
@@ -3,6 +3,7 @@
 use bytes::buf::UninitSlice;
 use bytes::{BufMut, BytesMut};
 use core::fmt::Write;
+use core::mem::MaybeUninit;
 use core::usize;
 
 #[test]
@@ -101,27 +102,124 @@
     assert!(buf != buf2);
 }
 
-#[test]
-fn test_mut_slice() {
-    let mut v = vec![0, 0, 0, 0];
-    let mut s = &mut v[..];
-    s.put_u32(42);
+fn do_test_slice_small<T: ?Sized>(make: impl Fn(&mut [u8]) -> &mut T)
+where
+    for<'r> &'r mut T: BufMut,
+{
+    let mut buf = [b'X'; 8];
 
-    assert_eq!(s.len(), 0);
-    assert_eq!(&v, &[0, 0, 0, 42]);
+    let mut slice = make(&mut buf[..]);
+    slice.put_bytes(b'A', 2);
+    slice.put_u8(b'B');
+    slice.put_slice(b"BCC");
+    assert_eq!(2, slice.remaining_mut());
+    assert_eq!(b"AABBCCXX", &buf[..]);
+
+    let mut slice = make(&mut buf[..]);
+    slice.put_u32(0x61626364);
+    assert_eq!(4, slice.remaining_mut());
+    assert_eq!(b"abcdCCXX", &buf[..]);
+
+    let mut slice = make(&mut buf[..]);
+    slice.put_u32_le(0x30313233);
+    assert_eq!(4, slice.remaining_mut());
+    assert_eq!(b"3210CCXX", &buf[..]);
+}
+
+fn do_test_slice_large<T: ?Sized>(make: impl Fn(&mut [u8]) -> &mut T)
+where
+    for<'r> &'r mut T: BufMut,
+{
+    const LEN: usize = 100;
+    const FILL: [u8; LEN] = [b'Y'; LEN];
+
+    let test = |fill: &dyn Fn(&mut &mut T, usize)| {
+        for buf_len in 0..LEN {
+            let mut buf = [b'X'; LEN];
+            for fill_len in 0..=buf_len {
+                let mut slice = make(&mut buf[..buf_len]);
+                fill(&mut slice, fill_len);
+                assert_eq!(buf_len - fill_len, slice.remaining_mut());
+                let (head, tail) = buf.split_at(fill_len);
+                assert_eq!(&FILL[..fill_len], head);
+                assert!(tail.iter().all(|b| *b == b'X'));
+            }
+        }
+    };
+
+    test(&|slice, fill_len| slice.put_slice(&FILL[..fill_len]));
+    test(&|slice, fill_len| slice.put_bytes(FILL[0], fill_len));
+}
+
+fn do_test_slice_put_slice_panics<T: ?Sized>(make: impl Fn(&mut [u8]) -> &mut T)
+where
+    for<'r> &'r mut T: BufMut,
+{
+    let mut buf = [b'X'; 4];
+    let mut slice = make(&mut buf[..]);
+    slice.put_slice(b"12345");
+}
+
+fn do_test_slice_put_bytes_panics<T: ?Sized>(make: impl Fn(&mut [u8]) -> &mut T)
+where
+    for<'r> &'r mut T: BufMut,
+{
+    let mut buf = [b'X'; 4];
+    let mut slice = make(&mut buf[..]);
+    slice.put_bytes(b'1', 5);
 }
 
 #[test]
-fn test_slice_put_bytes() {
-    let mut v = [0, 0, 0, 0];
-    let mut s = &mut v[..];
-    s.put_u8(17);
-    s.put_bytes(19, 2);
-    assert_eq!(1, s.remaining_mut());
-    assert_eq!(&[17, 19, 19, 0], &v[..]);
+fn test_slice_buf_mut_small() {
+    do_test_slice_small(|x| x);
 }
 
 #[test]
+fn test_slice_buf_mut_large() {
+    do_test_slice_large(|x| x);
+}
+
+#[test]
+#[should_panic]
+fn test_slice_buf_mut_put_slice_overflow() {
+    do_test_slice_put_slice_panics(|x| x);
+}
+
+#[test]
+#[should_panic]
+fn test_slice_buf_mut_put_bytes_overflow() {
+    do_test_slice_put_bytes_panics(|x| x);
+}
+
+fn make_maybe_uninit_slice(slice: &mut [u8]) -> &mut [MaybeUninit<u8>] {
+    // SAFETY: [u8] has the same layout as [MaybeUninit<u8>].
+    unsafe { core::mem::transmute(slice) }
+}
+
+#[test]
+fn test_maybe_uninit_buf_mut_small() {
+    do_test_slice_small(make_maybe_uninit_slice);
+}
+
+#[test]
+fn test_maybe_uninit_buf_mut_large() {
+    do_test_slice_large(make_maybe_uninit_slice);
+}
+
+#[test]
+#[should_panic]
+fn test_maybe_uninit_buf_mut_put_slice_overflow() {
+    do_test_slice_put_slice_panics(make_maybe_uninit_slice);
+}
+
+#[test]
+#[should_panic]
+fn test_maybe_uninit_buf_mut_put_bytes_overflow() {
+    do_test_slice_put_bytes_panics(make_maybe_uninit_slice);
+}
+
+#[allow(unused_allocation)] // This is intentional.
+#[test]
 fn test_deref_bufmut_forwards() {
     struct Special;