Snap for 11426397 from 91f77422ca8a68a659e8dd174483fb1653d5447f to 24Q2-release

Change-Id: I611707a45db6db07416050825bb7a4541afa368b
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index f1fdee4..eeba460 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,6 +1,6 @@
 {
   "git": {
-    "sha1": "1b162e8dd2283a62380c30b04cf8444c9c194d5c"
+    "sha1": "f9cc2df9415c880bd3610c2cdb6785ac7cad31ea"
   },
   "path_in_vcs": ""
 }
\ No newline at end of file
diff --git a/.clippy.toml b/.clippy.toml
deleted file mode 100644
index 3d30690..0000000
--- a/.clippy.toml
+++ /dev/null
@@ -1 +0,0 @@
-msrv = "1.31.0"
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 8acd5fc..cb1fad5 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -27,7 +27,7 @@
         rust: [nightly, beta, stable, 1.52.0, 1.46.0, 1.40.0, 1.39.0, 1.36.0, 1.33.0, 1.32.0, 1.31.0]
     timeout-minutes: 45
     steps:
-      - uses: actions/checkout@v3
+      - uses: actions/checkout@v4
       - uses: dtolnay/rust-toolchain@master
         with:
           toolchain: ${{matrix.rust}}
@@ -46,20 +46,46 @@
     runs-on: ubuntu-latest
     timeout-minutes: 45
     steps:
-      - uses: actions/checkout@v3
+      - uses: actions/checkout@v4
       - uses: dtolnay/rust-toolchain@stable
       - run: npm install semver
       - run: cargo test
         env:
           RUSTFLAGS: --cfg test_node_semver ${{env.RUSTFLAGS}}
 
+  minimal:
+    name: Minimal versions
+    needs: pre_ci
+    if: needs.pre_ci.outputs.continue
+    runs-on: ubuntu-latest
+    timeout-minutes: 45
+    steps:
+      - uses: actions/checkout@v4
+      - uses: dtolnay/rust-toolchain@nightly
+      - run: cargo generate-lockfile -Z minimal-versions
+      - run: cargo check --locked --features serde
+
+  doc:
+    name: Documentation
+    needs: pre_ci
+    if: needs.pre_ci.outputs.continue
+    runs-on: ubuntu-latest
+    timeout-minutes: 45
+    env:
+      RUSTDOCFLAGS: -Dwarnings
+    steps:
+      - uses: actions/checkout@v4
+      - uses: dtolnay/rust-toolchain@nightly
+      - uses: dtolnay/install@cargo-docs-rs
+      - run: cargo docs-rs
+
   clippy:
     name: Clippy
     runs-on: ubuntu-latest
     if: github.event_name != 'pull_request'
     timeout-minutes: 45
     steps:
-      - uses: actions/checkout@v3
+      - uses: actions/checkout@v4
       - uses: dtolnay/rust-toolchain@clippy
       - run: cargo clippy --tests --benches -- -Dclippy::all -Dclippy::pedantic
 
@@ -72,7 +98,7 @@
       MIRIFLAGS: -Zmiri-strict-provenance
     timeout-minutes: 45
     steps:
-      - uses: actions/checkout@v3
+      - uses: actions/checkout@v4
       - uses: dtolnay/rust-toolchain@miri
       - name: Run cargo miri test (64-bit little endian)
         run: cargo miri test --target x86_64-unknown-linux-gnu
@@ -90,7 +116,7 @@
     runs-on: ubuntu-latest
     timeout-minutes: 45
     steps:
-      - uses: actions/checkout@v3
+      - uses: actions/checkout@v4
       - uses: dtolnay/rust-toolchain@nightly
       - uses: dtolnay/install@cargo-fuzz
       - run: cargo fuzz check
@@ -101,7 +127,7 @@
     if: github.event_name != 'pull_request'
     timeout-minutes: 45
     steps:
-      - uses: actions/checkout@v3
+      - uses: actions/checkout@v4
       - uses: dtolnay/install@cargo-outdated
       - run: cargo outdated --workspace --exit-code 1
       - run: cargo outdated --manifest-path fuzz/Cargo.toml --exit-code 1
diff --git a/Android.bp b/Android.bp
index b5e9625..ba25ab3 100644
--- a/Android.bp
+++ b/Android.bp
@@ -41,7 +41,7 @@
     name: "libsemver",
     crate_name: "semver",
     cargo_env_compat: true,
-    cargo_pkg_version: "1.0.17",
+    cargo_pkg_version: "1.0.21",
     srcs: ["src/lib.rs"],
     edition: "2018",
     features: [
diff --git a/Cargo.toml b/Cargo.toml
index e7fcfb7..931c692 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -13,7 +13,7 @@
 edition = "2018"
 rust-version = "1.31"
 name = "semver"
-version = "1.0.17"
+version = "1.0.21"
 authors = ["David Tolnay <[email protected]>"]
 description = "Parser and evaluator for Cargo's flavor of Semantic Versioning"
 documentation = "https://docs.rs/semver"
@@ -30,6 +30,7 @@
 rustdoc-args = [
     "--cfg",
     "doc_cfg",
+    "--generate-link-to-definition",
 ]
 targets = ["x86_64-unknown-linux-gnu"]
 
@@ -37,7 +38,7 @@
 doc-scrape-examples = false
 
 [dependencies.serde]
-version = "1.0"
+version = "1.0.194"
 optional = true
 default-features = false
 
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index 30ee98e..e637625 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -1,6 +1,6 @@
 [package]
 name = "semver"
-version = "1.0.17"
+version = "1.0.21"
 authors = ["David Tolnay <[email protected]>"]
 categories = ["data-structures", "no-std"]
 description = "Parser and evaluator for Cargo's flavor of Semantic Versioning"
@@ -16,11 +16,11 @@
 std = []
 
 [dependencies]
-serde = { version = "1.0", optional = true, default-features = false }
+serde = { version = "1.0.194", optional = true, default-features = false }
 
 [lib]
 doc-scrape-examples = false
 
 [package.metadata.docs.rs]
 targets = ["x86_64-unknown-linux-gnu"]
-rustdoc-args = ["--cfg", "doc_cfg"]
+rustdoc-args = ["--cfg", "doc_cfg", "--generate-link-to-definition"]
diff --git a/METADATA b/METADATA
index 642e29a..c963f72 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/semver
-# 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/semver
+# For more info, check https://cs.android.com/android/platform/superproject/+/main:tools/external_updater/README.md
 
 name: "semver"
 description: "Parser and evaluator for Cargo\'s flavor of Semantic Versioning"
 third_party {
-  url {
-    type: HOMEPAGE
-    value: "https://crates.io/crates/semver"
-  }
-  url {
-    type: ARCHIVE
-    value: "https://static.crates.io/crates/semver/semver-1.0.17.crate"
-  }
-  version: "1.0.17"
   license_type: NOTICE
   last_upgrade_date {
-    year: 2023
-    month: 4
-    day: 3
+    year: 2024
+    month: 2
+    day: 7
+  }
+  homepage: "https://crates.io/crates/semver"
+  identifier {
+    type: "Archive"
+    value: "https://static.crates.io/crates/semver/semver-1.0.21.crate"
+    version: "1.0.21"
   }
 }
diff --git a/src/impls.rs b/src/impls.rs
index c3b6c60..cc4fd41 100644
--- a/src/impls.rs
+++ b/src/impls.rs
@@ -38,13 +38,13 @@
 
 impl PartialOrd for Prerelease {
     fn partial_cmp(&self, rhs: &Self) -> Option<Ordering> {
-        Some(Ord::cmp(self, rhs))
+        Some(self.cmp(rhs))
     }
 }
 
 impl PartialOrd for BuildMetadata {
     fn partial_cmp(&self, rhs: &Self) -> Option<Ordering> {
-        Some(Ord::cmp(self, rhs))
+        Some(self.cmp(rhs))
     }
 }
 
diff --git a/src/lib.rs b/src/lib.rs
index d6a8fe3..952cc2b 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -60,7 +60,7 @@
 //!
 //! [Specifying Dependencies]: https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html
 
-#![doc(html_root_url = "https://docs.rs/semver/1.0.17")]
+#![doc(html_root_url = "https://docs.rs/semver/1.0.21")]
 #![cfg_attr(doc_cfg, feature(doc_cfg))]
 #![cfg_attr(all(not(feature = "std"), not(no_alloc_crate)), no_std)]
 #![cfg_attr(not(no_unsafe_op_in_unsafe_fn_lint), deny(unsafe_op_in_unsafe_fn))]
@@ -76,7 +76,6 @@
     clippy::missing_errors_doc,
     clippy::must_use_candidate,
     clippy::needless_doctest_main,
-    clippy::option_if_let_else,
     clippy::ptr_as_ptr,
     clippy::redundant_else,
     clippy::semicolon_if_nothing_returned, // https://github.com/rust-lang/rust-clippy/issues/7324
@@ -102,6 +101,7 @@
 
 use crate::alloc::vec::Vec;
 use crate::identifier::Identifier;
+use core::cmp::Ordering;
 use core::str::FromStr;
 
 #[allow(unused_imports)]
@@ -431,6 +431,53 @@
     pub fn parse(text: &str) -> Result<Self, Error> {
         Version::from_str(text)
     }
+
+    /// Compare the major, minor, patch, and pre-release value of two versions,
+    /// disregarding build metadata. Versions that differ only in build metadata
+    /// are considered equal. This comparison is what the SemVer spec refers to
+    /// as "precedence".
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use semver::Version;
+    ///
+    /// let mut versions = [
+    ///     "1.20.0+c144a98".parse::<Version>().unwrap(),
+    ///     "1.20.0".parse().unwrap(),
+    ///     "1.0.0".parse().unwrap(),
+    ///     "1.0.0-alpha".parse().unwrap(),
+    ///     "1.20.0+bc17664".parse().unwrap(),
+    /// ];
+    ///
+    /// // This is a stable sort, so it preserves the relative order of equal
+    /// // elements. The three 1.20.0 versions differ only in build metadata so
+    /// // they are not reordered relative to one another.
+    /// versions.sort_by(Version::cmp_precedence);
+    /// assert_eq!(versions, [
+    ///     "1.0.0-alpha".parse().unwrap(),
+    ///     "1.0.0".parse().unwrap(),
+    ///     "1.20.0+c144a98".parse().unwrap(),
+    ///     "1.20.0".parse().unwrap(),
+    ///     "1.20.0+bc17664".parse().unwrap(),
+    /// ]);
+    ///
+    /// // Totally order the versions, including comparing the build metadata.
+    /// versions.sort();
+    /// assert_eq!(versions, [
+    ///     "1.0.0-alpha".parse().unwrap(),
+    ///     "1.0.0".parse().unwrap(),
+    ///     "1.20.0".parse().unwrap(),
+    ///     "1.20.0+bc17664".parse().unwrap(),
+    ///     "1.20.0+c144a98".parse().unwrap(),
+    /// ]);
+    /// ```
+    pub fn cmp_precedence(&self, other: &Self) -> Ordering {
+        Ord::cmp(
+            &(self.major, self.minor, self.patch, &self.pre),
+            &(other.major, other.minor, other.patch, &other.pre),
+        )
+    }
 }
 
 impl VersionReq {
diff --git a/tests/test_identifier.rs b/tests/test_identifier.rs
index dc888c9..40d8596 100644
--- a/tests/test_identifier.rs
+++ b/tests/test_identifier.rs
@@ -43,3 +43,9 @@
     assert_ne!(prerelease("aaaaaaaaa"), prerelease("bbbbbbbbb"));
     assert_ne!(build_metadata("1"), build_metadata("001"));
 }
+
+#[test]
+fn test_prerelease() {
+    let err = prerelease_err("1.b\0");
+    assert_to_string(err, "unexpected character in pre-release identifier");
+}
diff --git a/tests/test_version.rs b/tests/test_version.rs
index de3628f..991087f 100644
--- a/tests/test_version.rs
+++ b/tests/test_version.rs
@@ -47,6 +47,18 @@
     let err = version_err("1.2.3-01");
     assert_to_string(err, "invalid leading zero in pre-release identifier");
 
+    let err = version_err("1.2.3++");
+    assert_to_string(err, "empty identifier segment in build metadata");
+
+    let err = version_err("07");
+    assert_to_string(err, "invalid leading zero in major version number");
+
+    let err = version_err("111111111111111111111.0.0");
+    assert_to_string(err, "value of major version number exceeds u64::MAX");
+
+    let err = version_err("8\0");
+    assert_to_string(err, "unexpected character '\\0' after major version number");
+
     let parsed = version("1.2.3");
     let expected = Version::new(1, 2, 3);
     assert_eq!(parsed, expected);
diff --git a/tests/test_version_req.rs b/tests/test_version_req.rs
index 98a03ac..1ed2358 100644
--- a/tests/test_version_req.rs
+++ b/tests/test_version_req.rs
@@ -168,6 +168,9 @@
     // https://github.com/steveklabnik/semver/issues/56
     let err = req_err("1.2.3 - 2.3.4");
     assert_to_string(err, "expected comma after patch version number, found '-'");
+
+    let err = req_err(">1, >2, >3, >4, >5, >6, >7, >8, >9, >10, >11, >12, >13, >14, >15, >16, >17, >18, >19, >20, >21, >22, >23, >24, >25, >26, >27, >28, >29, >30, >31, >32, >33");
+    assert_to_string(err, "excessive number of version comparators");
 }
 
 #[test]
@@ -332,7 +335,7 @@
 }
 
 #[test]
-pub fn test_parse_errors() {
+pub fn test_parse() {
     let err = req_err("\0");
     assert_to_string(
         err,
@@ -368,6 +371,45 @@
 }
 
 #[test]
+fn test_comparator_parse() {
+    let parsed = comparator("1.2.3-alpha");
+    assert_to_string(parsed, "^1.2.3-alpha");
+
+    let parsed = comparator("2.X");
+    assert_to_string(parsed, "2.*");
+
+    let parsed = comparator("2");
+    assert_to_string(parsed, "^2");
+
+    let parsed = comparator("2.x.x");
+    assert_to_string(parsed, "2.*");
+
+    let err = comparator_err("1.2.3-01");
+    assert_to_string(err, "invalid leading zero in pre-release identifier");
+
+    let err = comparator_err("1.2.3+4.");
+    assert_to_string(err, "empty identifier segment in build metadata");
+
+    let err = comparator_err(">");
+    assert_to_string(
+        err,
+        "unexpected end of input while parsing major version number",
+    );
+
+    let err = comparator_err("1.");
+    assert_to_string(
+        err,
+        "unexpected end of input while parsing minor version number",
+    );
+
+    let err = comparator_err("1.*.");
+    assert_to_string(err, "unexpected character after wildcard in version req");
+
+    let err = comparator_err("1.2.3+4ÿ");
+    assert_to_string(err, "unexpected character 'ÿ' after build metadata");
+}
+
+#[test]
 fn test_cargo3202() {
     let ref r = req("0.*.*");
     assert_to_string(r, "0.*");
diff --git a/tests/util/mod.rs b/tests/util/mod.rs
index 5cc142c..07d691f 100644
--- a/tests/util/mod.rs
+++ b/tests/util/mod.rs
@@ -1,6 +1,6 @@
 #![allow(dead_code)]
 
-use semver::{BuildMetadata, Error, Prerelease, Version, VersionReq};
+use semver::{BuildMetadata, Comparator, Error, Prerelease, Version, VersionReq};
 use std::fmt::Display;
 
 #[cfg_attr(not(no_track_caller), track_caller)]
@@ -24,11 +24,26 @@
 }
 
 #[cfg_attr(not(no_track_caller), track_caller)]
+pub(super) fn comparator(text: &str) -> Comparator {
+    Comparator::parse(text).unwrap()
+}
+
+#[cfg_attr(not(no_track_caller), track_caller)]
+pub(super) fn comparator_err(text: &str) -> Error {
+    Comparator::parse(text).unwrap_err()
+}
+
+#[cfg_attr(not(no_track_caller), track_caller)]
 pub(super) fn prerelease(text: &str) -> Prerelease {
     Prerelease::new(text).unwrap()
 }
 
 #[cfg_attr(not(no_track_caller), track_caller)]
+pub(super) fn prerelease_err(text: &str) -> Error {
+    Prerelease::new(text).unwrap_err()
+}
+
+#[cfg_attr(not(no_track_caller), track_caller)]
 pub(super) fn build_metadata(text: &str) -> BuildMetadata {
     BuildMetadata::new(text).unwrap()
 }