summaryrefslogtreecommitdiff
path: root/libre/icedove/rustc_version-0.4.0.patch
diff options
context:
space:
mode:
Diffstat (limited to 'libre/icedove/rustc_version-0.4.0.patch')
-rw-r--r--libre/icedove/rustc_version-0.4.0.patch8613
1 files changed, 8613 insertions, 0 deletions
diff --git a/libre/icedove/rustc_version-0.4.0.patch b/libre/icedove/rustc_version-0.4.0.patch
new file mode 100644
index 000000000..9f50bca5c
--- /dev/null
+++ b/libre/icedove/rustc_version-0.4.0.patch
@@ -0,0 +1,8613 @@
+
+# HG changeset patch
+# User Mike Hommey <mh+mozilla@glandium.org>
+# Date 1654596092 0
+# Node ID f52e2ad948e88e2c4ce83599d379aa4a1e57334e
+# Parent 969171da8cc09d4eb7c070b0ecf33bc5cc504537
+Bug 1772048 - Update rustc_version and semver crates. r=emilio,webdriver-reviewers,kinetik,whimboo
+
+semver 1.0 doesn't and won't support Clone on semver::Error[1], so we
+convert the mozversion error type to store the string version of the
+error, which is an incompatible change requiring a version bump on the
+crate.
+
+1. https://github.com/dtolnay/semver/pull/280
+
+Differential Revision: https://phabricator.services.mozilla.com/D147825
+
+diff --git a/.cargo/config.in b/.cargo/config.in
+--- a/.cargo/config.in
++++ b/.cargo/config.in
+@@ -25,17 +25,17 @@ rev = "3bfc47d9a571d0842676043ba60716318
+ [source."https://github.com/mozilla/midir.git"]
+ git = "https://github.com/mozilla/midir.git"
+ replace-with = "vendored-sources"
+ rev = "4c11f0ffb5d6a10de4aff40a7b81218b33b94e6f"
+
+ [source."https://github.com/mozilla/cubeb-pulse-rs"]
+ git = "https://github.com/mozilla/cubeb-pulse-rs"
+ replace-with = "vendored-sources"
+-rev = "df4dc0288b07b865440f4c7e41ca49ca9ccffc63"
++rev = "1f1fe1e08e01a9a534ec7f079702a583a0899ce7"
+
+ [source."https://github.com/mozilla/cubeb-coreaudio-rs"]
+ git = "https://github.com/mozilla/cubeb-coreaudio-rs"
+ replace-with = "vendored-sources"
+ rev = "44eca95823bb57e964cf7b6d9791ed2ccb4b2108"
+
+ [source."https://github.com/mozilla/audioipc"]
+ git = "https://github.com/mozilla/audioipc"
+diff --git a/Cargo.lock b/Cargo.lock
+--- a/Cargo.lock
++++ b/Cargo.lock
+@@ -1157,17 +1157,17 @@ dependencies = [
+ "mach",
+ "ringbuf",
+ "triple_buffer",
+ ]
+
+ [[package]]
+ name = "cubeb-pulse"
+ version = "0.4.0"
+-source = "git+https://github.com/mozilla/cubeb-pulse-rs?rev=df4dc0288b07b865440f4c7e41ca49ca9ccffc63#df4dc0288b07b865440f4c7e41ca49ca9ccffc63"
++source = "git+https://github.com/mozilla/cubeb-pulse-rs?rev=1f1fe1e08e01a9a534ec7f079702a583a0899ce7#1f1fe1e08e01a9a534ec7f079702a583a0899ce7"
+ dependencies = [
+ "cubeb-backend",
+ "pulse",
+ "pulse-ffi",
+ "ringbuf",
+ "semver",
+ ]
+
+@@ -3399,17 +3399,17 @@ dependencies = [
+ "nsstring",
+ "url",
+ "uuid",
+ "xpcom",
+ ]
+
+ [[package]]
+ name = "mozversion"
+-version = "0.4.3"
++version = "0.5.0-alpha"
+ dependencies = [
+ "regex",
+ "rust-ini",
+ "semver",
+ ]
+
+ [[package]]
+ name = "mozwer_s"
+@@ -4122,26 +4122,26 @@ dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ ]
+
+ [[package]]
+ name = "pulse"
+ version = "0.3.0"
+-source = "git+https://github.com/mozilla/cubeb-pulse-rs?rev=df4dc0288b07b865440f4c7e41ca49ca9ccffc63#df4dc0288b07b865440f4c7e41ca49ca9ccffc63"
++source = "git+https://github.com/mozilla/cubeb-pulse-rs?rev=1f1fe1e08e01a9a534ec7f079702a583a0899ce7#1f1fe1e08e01a9a534ec7f079702a583a0899ce7"
+ dependencies = [
+ "bitflags",
+ "pulse-ffi",
+ ]
+
+ [[package]]
+ name = "pulse-ffi"
+ version = "0.1.0"
+-source = "git+https://github.com/mozilla/cubeb-pulse-rs?rev=df4dc0288b07b865440f4c7e41ca49ca9ccffc63#df4dc0288b07b865440f4c7e41ca49ca9ccffc63"
++source = "git+https://github.com/mozilla/cubeb-pulse-rs?rev=1f1fe1e08e01a9a534ec7f079702a583a0899ce7#1f1fe1e08e01a9a534ec7f079702a583a0899ce7"
+ dependencies = [
+ "libc",
+ ]
+
+ [[package]]
+ name = "qcms"
+ version = "0.2.0"
+ dependencies = [
+@@ -4456,19 +4456,19 @@ checksum = "7ef03e0a2b150c7a90d01faf6254
+ [[package]]
+ name = "rustc-hash"
+ version = "1.1.0"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
+
+ [[package]]
+ name = "rustc_version"
+-version = "0.2.3"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
++version = "0.4.0"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
+ dependencies = [
+ "semver",
+ ]
+
+ [[package]]
+ name = "ryu"
+ version = "1.0.10"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+@@ -4544,28 +4544,19 @@ dependencies = [
+ [[package]]
+ name = "self_cell"
+ version = "0.10.2"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+ checksum = "1ef965a420fe14fdac7dd018862966a4c14094f900e1650bbc71ddd7d580c8af"
+
+ [[package]]
+ name = "semver"
+-version = "0.9.0"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
+-dependencies = [
+- "semver-parser",
+-]
+-
+-[[package]]
+-name = "semver-parser"
+-version = "0.7.0"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
++version = "1.0.9"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "8cb243bdfdb5936c8dc3c45762a19d12ab4550cdc753bc247637d4ec35a040fd"
+
+ [[package]]
+ name = "serde"
+ version = "1.0.136"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+ checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789"
+ dependencies = [
+ "serde_derive",
+diff --git a/gfx/qcms/Cargo.toml b/gfx/qcms/Cargo.toml
+--- a/gfx/qcms/Cargo.toml
++++ b/gfx/qcms/Cargo.toml
+@@ -17,9 +17,9 @@ c_bindings = ["libc"]
+ neon = []
+ iccv4-enabled = []
+ cmyk = []
+
+ [dependencies]
+ libc = {version = "0.2", optional = true }
+
+ [build-dependencies]
+-rustc_version = "0.2"
++rustc_version = "0.4"
+diff --git a/mozglue/static/rust/Cargo.toml b/mozglue/static/rust/Cargo.toml
+--- a/mozglue/static/rust/Cargo.toml
++++ b/mozglue/static/rust/Cargo.toml
+@@ -8,12 +8,12 @@ license = "MPL"
+ path = "lib.rs"
+
+ [dependencies]
+ arrayvec = "0.5"
+
+ [build-dependencies]
+ mozbuild = "0.1"
+ cc = "1"
+-rustc_version = "0.2"
++rustc_version = "0.4"
+
+ [features]
+ moz_memory = []
+diff --git a/testing/geckodriver/Cargo.toml b/testing/geckodriver/Cargo.toml
+--- a/testing/geckodriver/Cargo.toml
++++ b/testing/geckodriver/Cargo.toml
+@@ -15,17 +15,17 @@ chrono = "0.4.6"
+ clap = { version = "3.1", default-features = false, features = ["cargo", "std", "suggestions", "wrap_help"] }
+ hyper = "0.14"
+ lazy_static = "1.0"
+ log = { version = "0.4", features = ["std"] }
+ marionette = { path = "./marionette", version="0.2.0" }
+ mozdevice = { path = "../mozbase/rust/mozdevice", version="0.5.0" }
+ mozprofile = { path = "../mozbase/rust/mozprofile", version="0.8.0" }
+ mozrunner = { path = "../mozbase/rust/mozrunner", version="0.14.0" }
+-mozversion = { path = "../mozbase/rust/mozversion", version="0.4.3" }
++mozversion = { path = "../mozbase/rust/mozversion", version="0.5.0-alpha" }
+ regex = { version="1.0", default-features = false, features = ["perf", "std"] }
+ serde = "1.0"
+ serde_derive = "1.0"
+ serde_json = "1.0"
+ serde_yaml = "0.8"
+ tempfile = "3"
+ url = "2.0"
+ uuid = { version = "0.8", features = ["v4"] }
+diff --git a/testing/mozbase/rust/mozversion/Cargo.toml b/testing/mozbase/rust/mozversion/Cargo.toml
+--- a/testing/mozbase/rust/mozversion/Cargo.toml
++++ b/testing/mozbase/rust/mozversion/Cargo.toml
+@@ -1,14 +1,14 @@
+ [package]
+ name = "mozversion"
+-version = "0.4.3"
++version = "0.5.0-alpha"
+ authors = ["Mozilla"]
+ description = "Utility for accessing Firefox version metadata"
+ keywords = ["mozilla", "firefox"]
+ repository = "https://hg.mozilla.org/mozilla-central/file/tip/testing/mozbase/rust/mozversion"
+ license = "MPL-2.0"
+ edition = "2018"
+
+ [dependencies]
+ regex = { version = "1", default-features = false, features = ["perf", "std"] }
+ rust-ini = "0.10"
+-semver = "0.9"
++semver = "1.0"
+diff --git a/testing/mozbase/rust/mozversion/src/lib.rs b/testing/mozbase/rust/mozversion/src/lib.rs
+--- a/testing/mozbase/rust/mozversion/src/lib.rs
++++ b/testing/mozbase/rust/mozversion/src/lib.rs
+@@ -101,18 +101,18 @@ impl Version {
+ // The way the semver crate handles prereleases isn't what we want here
+ // This should be fixed in the long term by implementing our own comparison
+ // operators, but for now just act as if prerelease metadata was missing,
+ // otherwise it is almost impossible to use this with nightly
+ semver::Version {
+ major: self.major,
+ minor: self.minor,
+ patch: self.patch,
+- pre: vec![],
+- build: vec![],
++ pre: semver::Prerelease::EMPTY,
++ build: semver::BuildMetadata::EMPTY,
+ }
+ }
+
+ pub fn matches(&self, version_req: &str) -> VersionResult<bool> {
+ let req = semver::VersionReq::parse(version_req)?;
+ Ok(req.matches(&self.to_semver()))
+ }
+ }
+@@ -269,17 +269,17 @@ fn parse_binary_version(version_str: &st
+
+ #[derive(Clone, Debug)]
+ pub enum Error {
+ /// Error parsing a version string
+ VersionError(String),
+ /// Error reading application metadata
+ MetadataError(String),
+ /// Error processing a string as a semver comparator
+- SemVerError(semver::ReqParseError),
++ SemVerError(String),
+ }
+
+ impl Display for Error {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match *self {
+ Error::VersionError(ref x) => {
+ "VersionError: ".fmt(f)?;
+ x.fmt(f)
+@@ -291,28 +291,25 @@ impl Display for Error {
+ Error::SemVerError(ref e) => {
+ "SemVerError: ".fmt(f)?;
+ e.fmt(f)
+ }
+ }
+ }
+ }
+
+-impl From<semver::ReqParseError> for Error {
+- fn from(err: semver::ReqParseError) -> Error {
+- Error::SemVerError(err)
++impl From<semver::Error> for Error {
++ fn from(err: semver::Error) -> Error {
++ Error::SemVerError(err.to_string())
+ }
+ }
+
+ impl error::Error for Error {
+ fn cause(&self) -> Option<&dyn error::Error> {
+- match *self {
+- Error::SemVerError(ref e) => Some(e),
+- Error::VersionError(_) | Error::MetadataError(_) => None,
+- }
++ None
+ }
+ }
+
+ pub type VersionResult<T> = Result<T, Error>;
+
+ #[cfg(target_os = "macos")]
+ mod platform {
+ use std::path::{Path, PathBuf};
+diff --git a/third_party/rust/cubeb-pulse/.cargo-checksum.json b/third_party/rust/cubeb-pulse/.cargo-checksum.json
+--- a/third_party/rust/cubeb-pulse/.cargo-checksum.json
++++ b/third_party/rust/cubeb-pulse/.cargo-checksum.json
+@@ -1,1 +1,1 @@
+-{"files":{".editorconfig":"bf047bd1da10cabb99eea666d1e57c321eba4716dccb3e4ed0e2c5fe3ca53858",".github/workflows/build.yml":"95d0d2542c04f0c932f58591b92c3051db5c95657bf5f24b6a6110f7b667568d","AUTHORS":"0e0ac930a68ce2f6b876126b195add177f0d3886facb9260f4d9b69f1988f0cc","Cargo.toml":"d8f84d114794b79a02c8d93724951a0b924f4815e446d666e66877c7a90d0446","LICENSE":"44c6b5ae5ec3fe2fbc608b00e6f4896f4d2d5c7e525fcbaa3eaa3cf2f3d5a983","README.md":"0079450bb4b013bac065ed1750851e461a3710ebad1f323817da1cb82db0bc4f","src/backend/context.rs":"839fbbd90e501c9e455e6b46729f8c3cc03b368b6b45d02c82399660b7cf8289","src/backend/cork_state.rs":"4a0f1afc7d9f333dac89218cc56d7d32fbffb487cd48c1c9a4e03d79cb3b5e28","src/backend/intern.rs":"11ca424e4eb77f8eb9fd5a6717d1e791facf9743156a8534f0016fcf64d57b0f","src/backend/mod.rs":"d5da05348bf1a7f65c85b14372964a49dc4849f0aee96c75e2c18b51fb03fcaf","src/backend/stream.rs":"525e1f6be1990deef3c42d34fc4e25947be642ce242514f8e3428737146cc755","src/capi.rs":"fa0fa020f0d0efe55aa0fc3596405e8407bbe2cbe6c7a558345304e6da87994e","src/lib.rs":"b41bbdc562cbfb130ed7c1e53fe69944774f515705341d8ce48a2f82c8c0c2c5"},"package":null}
+\ No newline at end of file
++{"files":{".editorconfig":"bf047bd1da10cabb99eea666d1e57c321eba4716dccb3e4ed0e2c5fe3ca53858",".github/workflows/build.yml":"95d0d2542c04f0c932f58591b92c3051db5c95657bf5f24b6a6110f7b667568d","AUTHORS":"0e0ac930a68ce2f6b876126b195add177f0d3886facb9260f4d9b69f1988f0cc","Cargo.toml":"13fe95ad27f37b8423958d78093ecff3ade9fffb28c5980604b624c2b617e5a7","LICENSE":"44c6b5ae5ec3fe2fbc608b00e6f4896f4d2d5c7e525fcbaa3eaa3cf2f3d5a983","README.md":"0079450bb4b013bac065ed1750851e461a3710ebad1f323817da1cb82db0bc4f","src/backend/context.rs":"839fbbd90e501c9e455e6b46729f8c3cc03b368b6b45d02c82399660b7cf8289","src/backend/cork_state.rs":"4a0f1afc7d9f333dac89218cc56d7d32fbffb487cd48c1c9a4e03d79cb3b5e28","src/backend/intern.rs":"11ca424e4eb77f8eb9fd5a6717d1e791facf9743156a8534f0016fcf64d57b0f","src/backend/mod.rs":"d5da05348bf1a7f65c85b14372964a49dc4849f0aee96c75e2c18b51fb03fcaf","src/backend/stream.rs":"e88a04ab7094b9df1bcdd07628369ec70ecb2062b91b0bd86f2642962814405c","src/capi.rs":"fa0fa020f0d0efe55aa0fc3596405e8407bbe2cbe6c7a558345304e6da87994e","src/lib.rs":"b41bbdc562cbfb130ed7c1e53fe69944774f515705341d8ce48a2f82c8c0c2c5"},"package":null}
+\ No newline at end of file
+diff --git a/third_party/rust/cubeb-pulse/Cargo.toml b/third_party/rust/cubeb-pulse/Cargo.toml
+--- a/third_party/rust/cubeb-pulse/Cargo.toml
++++ b/third_party/rust/cubeb-pulse/Cargo.toml
+@@ -10,10 +10,10 @@ pulse-dlopen = ["pulse-ffi/dlopen"]
+
+ [lib]
+ crate-type = ["staticlib", "rlib"]
+
+ [dependencies]
+ cubeb-backend = "0.10"
+ pulse-ffi = { path = "pulse-ffi" }
+ pulse = { path = "pulse-rs" }
+-semver = "^0.9"
++semver = "1.0"
+ ringbuf = "0.2"
+diff --git a/third_party/rust/cubeb-pulse/src/backend/stream.rs b/third_party/rust/cubeb-pulse/src/backend/stream.rs
+--- a/third_party/rust/cubeb-pulse/src/backend/stream.rs
++++ b/third_party/rust/cubeb-pulse/src/backend/stream.rs
+@@ -350,16 +350,25 @@ impl<'ctx> PulseStream<'ctx> {
+ ptr::null_mut(),
+ read_frames as c_long,
+ )
+ };
+
+ if got < 0 || got as usize != read_frames {
+ let _ = s.cancel_write();
+ stm.shutdown = true;
++ if got < 0 {
++ unsafe {
++ stm.state_callback.unwrap()(
++ stm as *mut _ as *mut _,
++ stm.user_ptr,
++ ffi::CUBEB_STATE_ERROR,
++ );
++ }
++ }
+ break;
+ }
+ }
+ }
+
+ if read_size > 0 {
+ let _ = s.drop();
+ }
+@@ -1064,16 +1073,23 @@ impl<'ctx> PulseStream<'ctx> {
+ read_ptr as *const _ as *mut _,
+ buffer,
+ (size / frame_size) as c_long,
+ ) as i64
+ };
+ if got < 0 {
+ let _ = stm.cancel_write();
+ self.shutdown = true;
++ unsafe {
++ self.state_callback.unwrap()(
++ self as *const _ as *mut _,
++ self.user_ptr,
++ ffi::CUBEB_STATE_ERROR,
++ );
++ }
+ return;
+ }
+
+ // If more iterations move offset of read buffer
+ if !input_data.is_null() {
+ let in_frame_size = self.input_sample_spec.frame_size();
+ read_offset += (size / frame_size) * in_frame_size;
+ }
+diff --git a/third_party/rust/rustc_version/.cargo-checksum.json b/third_party/rust/rustc_version/.cargo-checksum.json
+--- a/third_party/rust/rustc_version/.cargo-checksum.json
++++ b/third_party/rust/rustc_version/.cargo-checksum.json
+@@ -1,1 +1,1 @@
+-{"files":{"Cargo.toml":"80b9fb136c8c2945b4875b05b0f5a4b11e4722997e751f17d8d3f241d7c684db","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"c9a75f18b9ab2927829a208fc6aa2cf4e63b8420887ba29cdb265d6619ae82d5","README.md":"58bd14a1dfa1d828e6e99f35c3b7c2149d08e2d990d6ca93f92ab8ffb43275b7","src/errors.rs":"b28c2eeb1278fc3e8d68a64b177034faed67f6762335729d3a6d1e61be8fb034","src/lib.rs":"92a32673f77961724bc52b872781f06d22d166f06838c9582c5adae3c5214f51"},"package":"138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"}
+\ No newline at end of file
++{"files":{"Cargo.toml":"6a2e927f37b4897e75470e62face13eff0fe846c57f8fcfb98bcd5e0fe8ed0a2","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"c9a75f18b9ab2927829a208fc6aa2cf4e63b8420887ba29cdb265d6619ae82d5","README.md":"40f1138d4ddcfcfd0534429cea8dcbdcaf4a175aca1c26662f011f6e83d2fd7a","deny.toml":"22979f2da49546b27a5c892d5216bf74215987810a2d011b58870471883b9437","src/lib.rs":"bc18589948e3c04c3ffb491ffc3d4eccd8037c8e377d0bbae8aca2b21978b1de","tests/all.rs":"7b2969022feab85a948fafd331d9bb30d80357d01afaf7e0f723908e75f39e89"},"package":"bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"}
+\ No newline at end of file
+diff --git a/third_party/rust/rustc_version/Cargo.toml b/third_party/rust/rustc_version/Cargo.toml
+--- a/third_party/rust/rustc_version/Cargo.toml
++++ b/third_party/rust/rustc_version/Cargo.toml
+@@ -1,26 +1,27 @@
+ # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+ #
+ # When uploading crates to the registry Cargo will automatically
+ # "normalize" Cargo.toml files for maximal compatibility
+ # with all versions of Cargo and also rewrite `path` dependencies
+-# to registry (e.g. crates.io) dependencies
++# to registry (e.g., crates.io) dependencies
+ #
+ # If you believe there's an error in this file please file an
+ # issue against the rust-lang/cargo repository. If you're
+ # editing this file be aware that the upstream Cargo.toml
+ # will likely look very different (and much more reasonable)
+
+ [package]
++edition = "2018"
+ name = "rustc_version"
+-version = "0.2.3"
+-authors = ["Marvin Löbel <loebel.marvin@gmail.com>"]
++version = "0.4.0"
++authors = ["Dirkjan Ochtman <dirkjan@ochtman.nl>", "Marvin Löbel <loebel.marvin@gmail.com>"]
+ description = "A library for querying the version of a installed rustc compiler"
+ documentation = "https://docs.rs/rustc_version/"
+ readme = "README.md"
+ keywords = ["version", "rustc"]
+ license = "MIT/Apache-2.0"
+ repository = "https://github.com/Kimundi/rustc-version-rs"
+ [dependencies.semver]
+-version = "0.9"
+-[badges.travis-ci]
+-repository = "Kimundi/rustc-version-rs"
++version = "1.0"
++[dev-dependencies.doc-comment]
++version = "0.3"
+diff --git a/third_party/rust/rustc_version/README.md b/third_party/rust/rustc_version/README.md
+--- a/third_party/rust/rustc_version/README.md
++++ b/third_party/rust/rustc_version/README.md
+@@ -1,40 +1,46 @@
+ rustc-version-rs
+-==============
++================
++
++[![Documentation](https://docs.rs/rustc_version/badge.svg)](https://docs.rs/rustc_version/)
++[![Crates.io](https://img.shields.io/crates/v/rustc_version.svg)](https://crates.io/crates/rustc_version)
++[![Build status](https://github.com/Kimundi/rustc-version-rs/workflows/CI/badge.svg)](https://github.com/Kimundi/rustc-version-rs/actions?query=workflow%3ACI)
+
+ A library for querying the version of a `rustc` compiler.
+
+ This can be used by build scripts or other tools dealing with Rust sources
+-to make decisions based on the version of the compiler.
++to make decisions based on the version of the compiler. Current MSRV is 1.32.0.
+
+-[![Travis-CI Status](https://travis-ci.org/Kimundi/rustc-version-rs.png?branch=master)](https://travis-ci.org/Kimundi/rustc-version-rs)
++If this is of interest, also consider looking at these other crates:
++
++* [autocfg](https://crates.io/crates/autocfg/), which helps with feature detection instead of depending on compiler versions
++* [rustversion](https://github.com/dtolnay/rustversion) provides a procedural macro with no other dependencies
+
+ # Getting Started
+
+ [rustc-version-rs is available on crates.io](https://crates.io/crates/rustc_version).
+ It is recommended to look there for the newest released version, as well as links to the newest builds of the docs.
+
+ At the point of the last update of this README, the latest published version could be used like this:
+
+ Add the following dependency to your Cargo manifest...
+
+ ```toml
+ [build-dependencies]
+ rustc_version = "0.2"
+ ```
+
+-...and see the [docs](http://kimundi.github.io/rustc-version-rs/rustc_version/index.html) for how to use it.
++... and see the [docs](https://docs.rs/rustc_version) for how to use it.
+
+ # Example
+
+ ```rust
+ // This could be a cargo build script
+
+-extern crate rustc_version;
+ use rustc_version::{version, version_meta, Channel, Version};
+
+ fn main() {
+ // Assert we haven't travelled back in time
+ assert!(version().unwrap().major >= 1);
+
+ // Set cfg flags depending on release channel
+ match version_meta().unwrap().channel {
+diff --git a/third_party/rust/rustc_version/deny.toml b/third_party/rust/rustc_version/deny.toml
+new file mode 100644
+--- /dev/null
++++ b/third_party/rust/rustc_version/deny.toml
+@@ -0,0 +1,3 @@
++[licenses]
++allow-osi-fsf-free = "either"
++copyleft = "deny"
+diff --git a/third_party/rust/rustc_version/src/errors.rs b/third_party/rust/rustc_version/src/errors.rs
+deleted file mode 100644
+--- a/third_party/rust/rustc_version/src/errors.rs
++++ /dev/null
+@@ -1,79 +0,0 @@
+-use std::{self, error, fmt, io, str};
+-use semver::{self, Identifier};
+-
+-/// The error type for this crate.
+-#[derive(Debug)]
+-pub enum Error {
+- /// An error ocurrend when executing the `rustc` command.
+- CouldNotExecuteCommand(io::Error),
+- /// The output of `rustc -vV` was not valid utf-8.
+- Utf8Error(str::Utf8Error),
+- /// The output of `rustc -vV` was not in the expected format.
+- UnexpectedVersionFormat,
+- /// An error ocurred in parsing a `VersionReq`.
+- ReqParseError(semver::ReqParseError),
+- /// An error ocurred in parsing the semver.
+- SemVerError(semver::SemVerError),
+- /// The pre-release tag is unknown.
+- UnknownPreReleaseTag(Identifier),
+-}
+-use Error::*;
+-
+-impl fmt::Display for Error {
+- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+- use std::error::Error;
+- match *self {
+- CouldNotExecuteCommand(ref e) => write!(f, "{}: {}", self.description(), e),
+- Utf8Error(_) => write!(f, "{}", self.description()),
+- UnexpectedVersionFormat => write!(f, "{}", self.description()),
+- ReqParseError(ref e) => write!(f, "{}: {}", self.description(), e),
+- SemVerError(ref e) => write!(f, "{}: {}", self.description(), e),
+- UnknownPreReleaseTag(ref i) => write!(f, "{}: {}", self.description(), i),
+- }
+- }
+-}
+-
+-impl error::Error for Error {
+- fn cause(&self) -> Option<&error::Error> {
+- match *self {
+- CouldNotExecuteCommand(ref e) => Some(e),
+- Utf8Error(ref e) => Some(e),
+- UnexpectedVersionFormat => None,
+- ReqParseError(ref e) => Some(e),
+- SemVerError(ref e) => Some(e),
+- UnknownPreReleaseTag(_) => None,
+- }
+- }
+-
+- fn description(&self) -> &str {
+- match *self {
+- CouldNotExecuteCommand(_) => "could not execute command",
+- Utf8Error(_) => "invalid UTF-8 output from `rustc -vV`",
+- UnexpectedVersionFormat => "unexpected `rustc -vV` format",
+- ReqParseError(_) => "error parsing version requirement",
+- SemVerError(_) => "error parsing version",
+- UnknownPreReleaseTag(_) => "unknown pre-release tag",
+- }
+- }
+-}
+-
+-macro_rules! impl_from {
+- ($($err_ty:ty => $variant:ident),* $(,)*) => {
+- $(
+- impl From<$err_ty> for Error {
+- fn from(e: $err_ty) -> Error {
+- Error::$variant(e)
+- }
+- }
+- )*
+- }
+-}
+-
+-impl_from! {
+- str::Utf8Error => Utf8Error,
+- semver::SemVerError => SemVerError,
+- semver::ReqParseError => ReqParseError,
+-}
+-
+-/// The result type for this crate.
+-pub type Result<T> = std::result::Result<T, Error>;
+diff --git a/third_party/rust/rustc_version/src/lib.rs b/third_party/rust/rustc_version/src/lib.rs
+--- a/third_party/rust/rustc_version/src/lib.rs
++++ b/third_party/rust/rustc_version/src/lib.rs
+@@ -17,73 +17,138 @@
+ //! It calls `$RUSTC --version -v` and parses the output, falling
+ //! back to `rustc` if `$RUSTC` is not set.
+ //!
+ //! # Example
+ //!
+ //! ```rust
+ //! // This could be a cargo build script
+ //!
+-//! extern crate rustc_version;
+ //! use rustc_version::{version, version_meta, Channel, Version};
+ //!
+-//! fn main() {
+-//! // Assert we haven't travelled back in time
+-//! assert!(version().unwrap().major >= 1);
++//! // Assert we haven't travelled back in time
++//! assert!(version().unwrap().major >= 1);
+ //!
+-//! // Set cfg flags depending on release channel
+-//! match version_meta().unwrap().channel {
+-//! Channel::Stable => {
+-//! println!("cargo:rustc-cfg=RUSTC_IS_STABLE");
+-//! }
+-//! Channel::Beta => {
+-//! println!("cargo:rustc-cfg=RUSTC_IS_BETA");
+-//! }
+-//! Channel::Nightly => {
+-//! println!("cargo:rustc-cfg=RUSTC_IS_NIGHTLY");
+-//! }
+-//! Channel::Dev => {
+-//! println!("cargo:rustc-cfg=RUSTC_IS_DEV");
+-//! }
++//! // Set cfg flags depending on release channel
++//! match version_meta().unwrap().channel {
++//! Channel::Stable => {
++//! println!("cargo:rustc-cfg=RUSTC_IS_STABLE");
++//! }
++//! Channel::Beta => {
++//! println!("cargo:rustc-cfg=RUSTC_IS_BETA");
+ //! }
++//! Channel::Nightly => {
++//! println!("cargo:rustc-cfg=RUSTC_IS_NIGHTLY");
++//! }
++//! Channel::Dev => {
++//! println!("cargo:rustc-cfg=RUSTC_IS_DEV");
++//! }
++//! }
+ //!
+-//! // Check for a minimum version
+-//! if version().unwrap() >= Version::parse("1.4.0").unwrap() {
+-//! println!("cargo:rustc-cfg=compiler_has_important_bugfix");
+-//! }
++//! // Check for a minimum version
++//! if version().unwrap() >= Version::parse("1.4.0").unwrap() {
++//! println!("cargo:rustc-cfg=compiler_has_important_bugfix");
+ //! }
+ //! ```
+
+-extern crate semver;
+-use semver::Identifier;
++#[cfg(test)]
++#[macro_use]
++extern crate doc_comment;
++
++#[cfg(test)]
++doctest!("../README.md");
++
++use std::collections::HashMap;
+ use std::process::Command;
+-use std::{env, str};
+-use std::ffi::OsString;
++use std::{env, error, fmt, io, num, str};
++use std::{ffi::OsString, str::FromStr};
+
+ // Convenience re-export to allow version comparison without needing to add
+ // semver crate.
+ pub use semver::Version;
+
+-mod errors;
+-pub use errors::{Error, Result};
++use Error::*;
+
+ /// Release channel of the compiler.
+ #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
+ pub enum Channel {
+ /// Development release channel
+ Dev,
+ /// Nightly release channel
+ Nightly,
+ /// Beta release channel
+ Beta,
+ /// Stable release channel
+ Stable,
+ }
+
+-/// Rustc version plus metada like git short hash and build date.
++/// LLVM version
++///
++/// LLVM's version numbering scheme is not semver compatible until version 4.0
++///
++/// rustc [just prints the major and minor versions], so other parts of the version are not included.
++///
++/// [just prints the major and minor versions]: https://github.com/rust-lang/rust/blob/b5c9e2448c9ace53ad5c11585803894651b18b0a/compiler/rustc_codegen_llvm/src/llvm_util.rs#L173-L178
++#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
++pub struct LlvmVersion {
++ // fields must be ordered major, minor for comparison to be correct
++ /// Major version
++ pub major: u64,
++ /// Minor version
++ pub minor: u64,
++ // TODO: expose micro version here
++}
++
++impl fmt::Display for LlvmVersion {
++ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
++ write!(f, "{}.{}", self.major, self.minor)
++ }
++}
++
++impl FromStr for LlvmVersion {
++ type Err = LlvmVersionParseError;
++
++ fn from_str(s: &str) -> Result<Self, Self::Err> {
++ let mut parts = s
++ .split('.')
++ .map(|part| -> Result<u64, LlvmVersionParseError> {
++ if part == "0" {
++ Ok(0)
++ } else if part.starts_with('0') {
++ Err(LlvmVersionParseError::ComponentMustNotHaveLeadingZeros)
++ } else if part.starts_with('-') || part.starts_with('+') {
++ Err(LlvmVersionParseError::ComponentMustNotHaveSign)
++ } else {
++ Ok(part.parse()?)
++ }
++ });
++
++ let major = parts.next().unwrap()?;
++ let mut minor = 0;
++
++ if let Some(part) = parts.next() {
++ minor = part?;
++ } else if major < 4 {
++ // LLVM versions earlier than 4.0 have significant minor versions, so require the minor version in this case.
++ return Err(LlvmVersionParseError::MinorVersionRequiredBefore4);
++ }
++
++ if let Some(Err(e)) = parts.next() {
++ return Err(e);
++ }
++
++ if parts.next().is_some() {
++ return Err(LlvmVersionParseError::TooManyComponents);
++ }
++
++ Ok(Self { major, minor })
++ }
++}
++
++/// Rustc version plus metadata like git short hash and build date.
+ #[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
+ pub struct VersionMeta {
+ /// Version of the compiler
+ pub semver: Version,
+
+ /// Git short hash of the build of the compiler
+ pub commit_hash: Option<String>,
+
+@@ -96,27 +161,37 @@ pub struct VersionMeta {
+ /// Release channel of the compiler
+ pub channel: Channel,
+
+ /// Host target triple of the compiler
+ pub host: String,
+
+ /// Short version string of the compiler
+ pub short_version_string: String,
++
++ /// Version of LLVM used by the compiler
++ pub llvm_version: Option<LlvmVersion>,
+ }
+
+ impl VersionMeta {
+ /// Returns the version metadata for `cmd`, which should be a `rustc` command.
+- pub fn for_command(cmd: Command) -> Result<VersionMeta> {
+- let mut cmd = cmd;
++ pub fn for_command(mut cmd: Command) -> Result<VersionMeta> {
++ let out = cmd
++ .arg("-vV")
++ .output()
++ .map_err(Error::CouldNotExecuteCommand)?;
+
+- let out = cmd.arg("-vV").output().map_err(Error::CouldNotExecuteCommand)?;
+- let out = str::from_utf8(&out.stdout)?;
++ if !out.status.success() {
++ return Err(Error::CommandError {
++ stdout: String::from_utf8_lossy(&out.stdout).into(),
++ stderr: String::from_utf8_lossy(&out.stderr).into(),
++ });
++ }
+
+- version_meta_for(out)
++ version_meta_for(str::from_utf8(&out.stdout)?)
+ }
+ }
+
+ /// Returns the `rustc` SemVer version.
+ pub fn version() -> Result<Version> {
+ Ok(version_meta()?.semver)
+ }
+
+@@ -127,221 +202,216 @@ pub fn version_meta() -> Result<VersionM
+
+ VersionMeta::for_command(Command::new(cmd))
+ }
+
+ /// Parses a "rustc -vV" output string and returns
+ /// the SemVer version and additional metadata
+ /// like the git short hash and build date.
+ pub fn version_meta_for(verbose_version_string: &str) -> Result<VersionMeta> {
+- let out: Vec<_> = verbose_version_string.lines().collect();
+-
+- if !(out.len() >= 6 && out.len() <= 8) {
+- return Err(Error::UnexpectedVersionFormat);
+- }
++ let mut map = HashMap::new();
++ for (i, line) in verbose_version_string.lines().enumerate() {
++ if i == 0 {
++ map.insert("short", line);
++ continue;
++ }
+
+- let short_version_string = out[0];
++ let mut parts = line.splitn(2, ": ");
++ let key = match parts.next() {
++ Some(key) => key,
++ None => continue,
++ };
+
+- fn expect_prefix<'a>(line: &'a str, prefix: &str) -> Result<&'a str> {
+- if line.starts_with(prefix) {
+- Ok(&line[prefix.len()..])
+- } else {
+- Err(Error::UnexpectedVersionFormat)
++ if let Some(value) = parts.next() {
++ map.insert(key, value);
+ }
+ }
+
+- let commit_hash = match expect_prefix(out[2], "commit-hash: ")? {
+- "unknown" => None,
+- hash => Some(hash.to_owned()),
+- };
++ let short_version_string = expect_key("short", &map)?;
++ let host = expect_key("host", &map)?;
++ let release = expect_key("release", &map)?;
++ let semver: Version = release.parse()?;
+
+- let commit_date = match expect_prefix(out[3], "commit-date: ")? {
+- "unknown" => None,
+- hash => Some(hash.to_owned()),
++ let channel = match semver.pre.split('.').next().unwrap() {
++ "" => Channel::Stable,
++ "dev" => Channel::Dev,
++ "beta" => Channel::Beta,
++ "nightly" => Channel::Nightly,
++ x => return Err(Error::UnknownPreReleaseTag(x.to_owned())),
+ };
+
+- // Handle that the build date may or may not be present.
+- let mut idx = 4;
+- let mut build_date = None;
+- if out[idx].starts_with("build-date") {
+- build_date = match expect_prefix(out[idx], "build-date: ")? {
+- "unknown" => None,
+- s => Some(s.to_owned()),
+- };
+- idx += 1;
+- }
+-
+- let host = expect_prefix(out[idx], "host: ")?;
+- idx += 1;
+- let release = expect_prefix(out[idx], "release: ")?;
+-
+- let semver: Version = release.parse()?;
+-
+- let channel = if semver.pre.is_empty() {
+- Channel::Stable
+- } else {
+- match semver.pre[0] {
+- Identifier::AlphaNumeric(ref s) if s == "dev" => Channel::Dev,
+- Identifier::AlphaNumeric(ref s) if s == "beta" => Channel::Beta,
+- Identifier::AlphaNumeric(ref s) if s == "nightly" => Channel::Nightly,
+- ref x => return Err(Error::UnknownPreReleaseTag(x.clone())),
+- }
++ let commit_hash = expect_key_or_unknown("commit-hash", &map)?;
++ let commit_date = expect_key_or_unknown("commit-date", &map)?;
++ let build_date = map
++ .get("build-date")
++ .filter(|&v| *v != "unknown")
++ .map(|&v| String::from(v));
++ let llvm_version = match map.get("LLVM version") {
++ Some(&v) => Some(v.parse()?),
++ None => None,
+ };
+
+ Ok(VersionMeta {
+- semver: semver,
+- commit_hash: commit_hash,
+- commit_date: commit_date,
+- build_date: build_date,
+- channel: channel,
+- host: host.into(),
+- short_version_string: short_version_string.into(),
++ semver,
++ commit_hash,
++ commit_date,
++ build_date,
++ channel,
++ host,
++ short_version_string,
++ llvm_version,
+ })
+ }
+
+-#[test]
+-fn smoketest() {
+- let v = version().unwrap();
+- assert!(v.major >= 1);
++fn expect_key_or_unknown(key: &str, map: &HashMap<&str, &str>) -> Result<Option<String>, Error> {
++ match map.get(key) {
++ Some(&v) if v == "unknown" => Ok(None),
++ Some(&v) => Ok(Some(String::from(v))),
++ None => Err(Error::UnexpectedVersionFormat),
++ }
++}
+
+- let v = version_meta().unwrap();
+- assert!(v.semver.major >= 1);
+-
+- assert!(version().unwrap() >= Version::parse("1.0.0").unwrap());
++fn expect_key(key: &str, map: &HashMap<&str, &str>) -> Result<String, Error> {
++ map.get(key)
++ .map(|&v| String::from(v))
++ .ok_or(Error::UnexpectedVersionFormat)
+ }
+
+-#[test]
+-fn parse_unexpected() {
+- let res = version_meta_for(
+-"rustc 1.0.0 (a59de37e9 2015-05-13) (built 2015-05-14)
+-binary: rustc
+-commit-hash: a59de37e99060162a2674e3ff45409ac73595c0e
+-commit-date: 2015-05-13
+-rust-birthday: 2015-05-14
+-host: x86_64-unknown-linux-gnu
+-release: 1.0.0");
++/// LLVM Version Parse Error
++#[derive(Debug)]
++pub enum LlvmVersionParseError {
++ /// An error occurred in parsing a version component as an integer
++ ParseIntError(num::ParseIntError),
++ /// A version component must not have leading zeros
++ ComponentMustNotHaveLeadingZeros,
++ /// A version component has a sign
++ ComponentMustNotHaveSign,
++ /// Minor version component must be zero on LLVM versions later than 4.0
++ MinorVersionMustBeZeroAfter4,
++ /// Minor version component is required on LLVM versions earlier than 4.0
++ MinorVersionRequiredBefore4,
++ /// Too many components
++ TooManyComponents,
++}
+
+- assert!(match res {
+- Err(Error::UnexpectedVersionFormat) => true,
+- _ => false,
+- });
+-
++impl From<num::ParseIntError> for LlvmVersionParseError {
++ fn from(e: num::ParseIntError) -> Self {
++ LlvmVersionParseError::ParseIntError(e)
++ }
+ }
+
+-#[test]
+-fn parse_1_0_0() {
+- let version = version_meta_for(
+-"rustc 1.0.0 (a59de37e9 2015-05-13) (built 2015-05-14)
+-binary: rustc
+-commit-hash: a59de37e99060162a2674e3ff45409ac73595c0e
+-commit-date: 2015-05-13
+-build-date: 2015-05-14
+-host: x86_64-unknown-linux-gnu
+-release: 1.0.0").unwrap();
+-
+- assert_eq!(version.semver, Version::parse("1.0.0").unwrap());
+- assert_eq!(version.commit_hash, Some("a59de37e99060162a2674e3ff45409ac73595c0e".into()));
+- assert_eq!(version.commit_date, Some("2015-05-13".into()));
+- assert_eq!(version.build_date, Some("2015-05-14".into()));
+- assert_eq!(version.channel, Channel::Stable);
+- assert_eq!(version.host, "x86_64-unknown-linux-gnu");
+- assert_eq!(version.short_version_string, "rustc 1.0.0 (a59de37e9 2015-05-13) (built 2015-05-14)");
++impl fmt::Display for LlvmVersionParseError {
++ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
++ match self {
++ LlvmVersionParseError::ParseIntError(e) => {
++ write!(f, "error parsing LLVM version component: {}", e)
++ }
++ LlvmVersionParseError::ComponentMustNotHaveLeadingZeros => {
++ write!(f, "a version component must not have leading zeros")
++ }
++ LlvmVersionParseError::ComponentMustNotHaveSign => {
++ write!(f, "a version component must not have a sign")
++ }
++ LlvmVersionParseError::MinorVersionMustBeZeroAfter4 => write!(
++ f,
++ "LLVM's minor version component must be 0 for versions greater than 4.0"
++ ),
++ LlvmVersionParseError::MinorVersionRequiredBefore4 => write!(
++ f,
++ "LLVM's minor version component is required for versions less than 4.0"
++ ),
++ LlvmVersionParseError::TooManyComponents => write!(f, "too many version components"),
++ }
++ }
+ }
+
+-
+-#[test]
+-fn parse_unknown() {
+- let version = version_meta_for(
+-"rustc 1.3.0
+-binary: rustc
+-commit-hash: unknown
+-commit-date: unknown
+-host: x86_64-unknown-linux-gnu
+-release: 1.3.0").unwrap();
+-
+- assert_eq!(version.semver, Version::parse("1.3.0").unwrap());
+- assert_eq!(version.commit_hash, None);
+- assert_eq!(version.commit_date, None);
+- assert_eq!(version.channel, Channel::Stable);
+- assert_eq!(version.host, "x86_64-unknown-linux-gnu");
+- assert_eq!(version.short_version_string, "rustc 1.3.0");
++impl error::Error for LlvmVersionParseError {
++ fn source(&self) -> Option<&(dyn error::Error + 'static)> {
++ match self {
++ LlvmVersionParseError::ParseIntError(e) => Some(e),
++ LlvmVersionParseError::ComponentMustNotHaveLeadingZeros
++ | LlvmVersionParseError::ComponentMustNotHaveSign
++ | LlvmVersionParseError::MinorVersionMustBeZeroAfter4
++ | LlvmVersionParseError::MinorVersionRequiredBefore4
++ | LlvmVersionParseError::TooManyComponents => None,
++ }
++ }
+ }
+
+-#[test]
+-fn parse_nightly() {
+- let version = version_meta_for(
+-"rustc 1.5.0-nightly (65d5c0833 2015-09-29)
+-binary: rustc
+-commit-hash: 65d5c083377645a115c4ac23a620d3581b9562b6
+-commit-date: 2015-09-29
+-host: x86_64-unknown-linux-gnu
+-release: 1.5.0-nightly").unwrap();
+-
+- assert_eq!(version.semver, Version::parse("1.5.0-nightly").unwrap());
+- assert_eq!(version.commit_hash, Some("65d5c083377645a115c4ac23a620d3581b9562b6".into()));
+- assert_eq!(version.commit_date, Some("2015-09-29".into()));
+- assert_eq!(version.channel, Channel::Nightly);
+- assert_eq!(version.host, "x86_64-unknown-linux-gnu");
+- assert_eq!(version.short_version_string, "rustc 1.5.0-nightly (65d5c0833 2015-09-29)");
+-}
+-
+-#[test]
+-fn parse_stable() {
+- let version = version_meta_for(
+-"rustc 1.3.0 (9a92aaf19 2015-09-15)
+-binary: rustc
+-commit-hash: 9a92aaf19a64603b02b4130fe52958cc12488900
+-commit-date: 2015-09-15
+-host: x86_64-unknown-linux-gnu
+-release: 1.3.0").unwrap();
+-
+- assert_eq!(version.semver, Version::parse("1.3.0").unwrap());
+- assert_eq!(version.commit_hash, Some("9a92aaf19a64603b02b4130fe52958cc12488900".into()));
+- assert_eq!(version.commit_date, Some("2015-09-15".into()));
+- assert_eq!(version.channel, Channel::Stable);
+- assert_eq!(version.host, "x86_64-unknown-linux-gnu");
+- assert_eq!(version.short_version_string, "rustc 1.3.0 (9a92aaf19 2015-09-15)");
++/// The error type for this crate.
++#[derive(Debug)]
++pub enum Error {
++ /// An error occurred while trying to find the `rustc` to run.
++ CouldNotExecuteCommand(io::Error),
++ /// Error output from the command that was run.
++ CommandError {
++ /// stdout output from the command
++ stdout: String,
++ /// stderr output from the command
++ stderr: String,
++ },
++ /// The output of `rustc -vV` was not valid utf-8.
++ Utf8Error(str::Utf8Error),
++ /// The output of `rustc -vV` was not in the expected format.
++ UnexpectedVersionFormat,
++ /// An error occurred in parsing the semver.
++ SemVerError(semver::Error),
++ /// The pre-release tag is unknown.
++ UnknownPreReleaseTag(String),
++ /// An error occurred in parsing a `LlvmVersion`.
++ LlvmVersionError(LlvmVersionParseError),
+ }
+
+-#[test]
+-fn parse_1_16_0_nightly() {
+- let version = version_meta_for(
+-"rustc 1.16.0-nightly (5d994d8b7 2017-01-05)
+-binary: rustc
+-commit-hash: 5d994d8b7e482e87467d4a521911477bd8284ce3
+-commit-date: 2017-01-05
+-host: x86_64-unknown-linux-gnu
+-release: 1.16.0-nightly
+-LLVM version: 3.9").unwrap();
+-
+- assert_eq!(version.semver, Version::parse("1.16.0-nightly").unwrap());
+- assert_eq!(version.commit_hash, Some("5d994d8b7e482e87467d4a521911477bd8284ce3".into()));
+- assert_eq!(version.commit_date, Some("2017-01-05".into()));
+- assert_eq!(version.channel, Channel::Nightly);
+- assert_eq!(version.host, "x86_64-unknown-linux-gnu");
+- assert_eq!(version.short_version_string, "rustc 1.16.0-nightly (5d994d8b7 2017-01-05)");
++impl fmt::Display for Error {
++ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
++ match *self {
++ CouldNotExecuteCommand(ref e) => write!(f, "could not execute command: {}", e),
++ CommandError {
++ ref stdout,
++ ref stderr,
++ } => write!(
++ f,
++ "error from command -- stderr:\n\n{}\n\nstderr:\n\n{}",
++ stderr, stdout,
++ ),
++ Utf8Error(_) => write!(f, "invalid UTF-8 output from `rustc -vV`"),
++ UnexpectedVersionFormat => write!(f, "unexpected `rustc -vV` format"),
++ SemVerError(ref e) => write!(f, "error parsing version: {}", e),
++ UnknownPreReleaseTag(ref i) => write!(f, "unknown pre-release tag: {}", i),
++ LlvmVersionError(ref e) => write!(f, "error parsing LLVM's version: {}", e),
++ }
++ }
+ }
+
+-/*
+-#[test]
+-fn version_matches_replacement() {
+- let f = |s1: &str, s2: &str| {
+- let a = Version::parse(s1).unwrap();
+- let b = Version::parse(s2).unwrap();
+- println!("{} <= {} : {}", s1, s2, a <= b);
+- };
+-
+- println!();
++impl error::Error for Error {
++ fn source(&self) -> Option<&(dyn error::Error + 'static)> {
++ match *self {
++ CouldNotExecuteCommand(ref e) => Some(e),
++ CommandError { .. } => None,
++ Utf8Error(ref e) => Some(e),
++ UnexpectedVersionFormat => None,
++ SemVerError(ref e) => Some(e),
++ UnknownPreReleaseTag(_) => None,
++ LlvmVersionError(ref e) => Some(e),
++ }
++ }
++}
+
+- f("1.5.0", "1.5.0");
+- f("1.5.0-nightly", "1.5.0");
+- f("1.5.0", "1.5.0-nightly");
+- f("1.5.0-nightly", "1.5.0-nightly");
++macro_rules! impl_from {
++ ($($err_ty:ty => $variant:ident),* $(,)*) => {
++ $(
++ impl From<$err_ty> for Error {
++ fn from(e: $err_ty) -> Error {
++ Error::$variant(e)
++ }
++ }
++ )*
++ }
++}
+
+- f("1.5.0", "1.6.0");
+- f("1.5.0-nightly", "1.6.0");
+- f("1.5.0", "1.6.0-nightly");
+- f("1.5.0-nightly", "1.6.0-nightly");
++impl_from! {
++ str::Utf8Error => Utf8Error,
++ semver::Error => SemVerError,
++ LlvmVersionParseError => LlvmVersionError,
++}
+
+- panic!();
+-
+-}
+-*/
++/// The result type for this crate.
++pub type Result<T, E = Error> = std::result::Result<T, E>;
+diff --git a/third_party/rust/rustc_version/tests/all.rs b/third_party/rust/rustc_version/tests/all.rs
+new file mode 100644
+--- /dev/null
++++ b/third_party/rust/rustc_version/tests/all.rs
+@@ -0,0 +1,456 @@
++#![allow(clippy::match_like_matches_macro)]
++
++use std::process::Command;
++
++use rustc_version::{
++ version, version_meta, version_meta_for, Channel, Error, LlvmVersion, LlvmVersionParseError,
++ Version, VersionMeta,
++};
++
++#[test]
++fn rustc_error() {
++ let mut cmd = Command::new("rustc");
++ cmd.arg("--FOO");
++ let stderr = match VersionMeta::for_command(cmd) {
++ Err(Error::CommandError { stdout: _, stderr }) => stderr,
++ _ => panic!("command error expected"),
++ };
++ assert_eq!(stderr, "error: Unrecognized option: \'FOO\'\n\n");
++}
++
++#[test]
++fn smoketest() {
++ let v = version().unwrap();
++ assert!(v.major >= 1);
++
++ let v = version_meta().unwrap();
++ assert!(v.semver.major >= 1);
++
++ assert!(version().unwrap() >= Version::parse("1.0.0").unwrap());
++}
++
++#[test]
++fn parse_1_0_0() {
++ let version = version_meta_for(
++ "rustc 1.0.0 (a59de37e9 2015-05-13) (built 2015-05-14)
++binary: rustc
++commit-hash: a59de37e99060162a2674e3ff45409ac73595c0e
++commit-date: 2015-05-13
++build-date: 2015-05-14
++host: x86_64-unknown-linux-gnu
++release: 1.0.0",
++ )
++ .unwrap();
++
++ assert_eq!(version.semver, Version::parse("1.0.0").unwrap());
++ assert_eq!(
++ version.commit_hash,
++ Some("a59de37e99060162a2674e3ff45409ac73595c0e".into())
++ );
++ assert_eq!(version.commit_date, Some("2015-05-13".into()));
++ assert_eq!(version.build_date, Some("2015-05-14".into()));
++ assert_eq!(version.channel, Channel::Stable);
++ assert_eq!(version.host, "x86_64-unknown-linux-gnu");
++ assert_eq!(
++ version.short_version_string,
++ "rustc 1.0.0 (a59de37e9 2015-05-13) (built 2015-05-14)"
++ );
++ assert_eq!(version.llvm_version, None);
++}
++
++#[test]
++fn parse_unknown() {
++ let version = version_meta_for(
++ "rustc 1.3.0
++binary: rustc
++commit-hash: unknown
++commit-date: unknown
++host: x86_64-unknown-linux-gnu
++release: 1.3.0",
++ )
++ .unwrap();
++
++ assert_eq!(version.semver, Version::parse("1.3.0").unwrap());
++ assert_eq!(version.commit_hash, None);
++ assert_eq!(version.commit_date, None);
++ assert_eq!(version.channel, Channel::Stable);
++ assert_eq!(version.host, "x86_64-unknown-linux-gnu");
++ assert_eq!(version.short_version_string, "rustc 1.3.0");
++ assert_eq!(version.llvm_version, None);
++}
++
++#[test]
++fn parse_nightly() {
++ let version = version_meta_for(
++ "rustc 1.5.0-nightly (65d5c0833 2015-09-29)
++binary: rustc
++commit-hash: 65d5c083377645a115c4ac23a620d3581b9562b6
++commit-date: 2015-09-29
++host: x86_64-unknown-linux-gnu
++release: 1.5.0-nightly",
++ )
++ .unwrap();
++
++ assert_eq!(version.semver, Version::parse("1.5.0-nightly").unwrap());
++ assert_eq!(
++ version.commit_hash,
++ Some("65d5c083377645a115c4ac23a620d3581b9562b6".into())
++ );
++ assert_eq!(version.commit_date, Some("2015-09-29".into()));
++ assert_eq!(version.channel, Channel::Nightly);
++ assert_eq!(version.host, "x86_64-unknown-linux-gnu");
++ assert_eq!(
++ version.short_version_string,
++ "rustc 1.5.0-nightly (65d5c0833 2015-09-29)"
++ );
++ assert_eq!(version.llvm_version, None);
++}
++
++#[test]
++fn parse_stable() {
++ let version = version_meta_for(
++ "rustc 1.3.0 (9a92aaf19 2015-09-15)
++binary: rustc
++commit-hash: 9a92aaf19a64603b02b4130fe52958cc12488900
++commit-date: 2015-09-15
++host: x86_64-unknown-linux-gnu
++release: 1.3.0",
++ )
++ .unwrap();
++
++ assert_eq!(version.semver, Version::parse("1.3.0").unwrap());
++ assert_eq!(
++ version.commit_hash,
++ Some("9a92aaf19a64603b02b4130fe52958cc12488900".into())
++ );
++ assert_eq!(version.commit_date, Some("2015-09-15".into()));
++ assert_eq!(version.channel, Channel::Stable);
++ assert_eq!(version.host, "x86_64-unknown-linux-gnu");
++ assert_eq!(
++ version.short_version_string,
++ "rustc 1.3.0 (9a92aaf19 2015-09-15)"
++ );
++ assert_eq!(version.llvm_version, None);
++}
++
++#[test]
++fn parse_1_16_0_nightly() {
++ let version = version_meta_for(
++ "rustc 1.16.0-nightly (5d994d8b7 2017-01-05)
++binary: rustc
++commit-hash: 5d994d8b7e482e87467d4a521911477bd8284ce3
++commit-date: 2017-01-05
++host: x86_64-unknown-linux-gnu
++release: 1.16.0-nightly
++LLVM version: 3.9",
++ )
++ .unwrap();
++
++ assert_eq!(version.semver, Version::parse("1.16.0-nightly").unwrap());
++ assert_eq!(
++ version.commit_hash,
++ Some("5d994d8b7e482e87467d4a521911477bd8284ce3".into())
++ );
++ assert_eq!(version.commit_date, Some("2017-01-05".into()));
++ assert_eq!(version.channel, Channel::Nightly);
++ assert_eq!(version.host, "x86_64-unknown-linux-gnu");
++ assert_eq!(
++ version.short_version_string,
++ "rustc 1.16.0-nightly (5d994d8b7 2017-01-05)"
++ );
++ assert_eq!(
++ version.llvm_version,
++ Some(LlvmVersion { major: 3, minor: 9 })
++ );
++}
++
++#[test]
++fn parse_1_47_0_stable() {
++ let version = version_meta_for(
++ "rustc 1.47.0 (18bf6b4f0 2020-10-07)
++binary: rustc
++commit-hash: 18bf6b4f01a6feaf7259ba7cdae58031af1b7b39
++commit-date: 2020-10-07
++host: powerpc64le-unknown-linux-gnu
++release: 1.47.0
++LLVM version: 11.0",
++ )
++ .unwrap();
++
++ assert_eq!(version.semver, Version::parse("1.47.0").unwrap());
++ assert_eq!(
++ version.commit_hash,
++ Some("18bf6b4f01a6feaf7259ba7cdae58031af1b7b39".into())
++ );
++ assert_eq!(version.commit_date, Some("2020-10-07".into()));
++ assert_eq!(version.channel, Channel::Stable);
++ assert_eq!(version.host, "powerpc64le-unknown-linux-gnu");
++ assert_eq!(
++ version.short_version_string,
++ "rustc 1.47.0 (18bf6b4f0 2020-10-07)"
++ );
++ assert_eq!(
++ version.llvm_version,
++ Some(LlvmVersion {
++ major: 11,
++ minor: 0,
++ })
++ );
++}
++
++#[test]
++fn parse_llvm_micro() {
++ let version = version_meta_for(
++ "rustc 1.51.0-nightly (4253153db 2021-01-17)
++binary: rustc
++commit-hash: 4253153db205251f72ea4493687a31e04a2a8ca0
++commit-date: 2021-01-17
++host: x86_64-pc-windows-msvc
++release: 1.51.0-nightly
++LLVM version: 11.0.1",
++ )
++ .unwrap();
++
++ assert_eq!(version.semver, Version::parse("1.51.0-nightly").unwrap());
++ assert_eq!(
++ version.commit_hash.unwrap(),
++ "4253153db205251f72ea4493687a31e04a2a8ca0"
++ );
++ assert_eq!(version.commit_date.unwrap(), "2021-01-17");
++ assert_eq!(version.host, "x86_64-pc-windows-msvc");
++ assert_eq!(
++ version.short_version_string,
++ "rustc 1.51.0-nightly (4253153db 2021-01-17)"
++ );
++ assert_eq!(
++ version.llvm_version,
++ Some(LlvmVersion {
++ major: 11,
++ minor: 0
++ })
++ );
++}
++
++#[test]
++fn parse_debian_buster() {
++ let version = version_meta_for(
++ "rustc 1.41.1
++binary: rustc
++commit-hash: unknown
++commit-date: unknown
++host: powerpc64le-unknown-linux-gnu
++release: 1.41.1
++LLVM version: 7.0",
++ )
++ .unwrap();
++
++ assert_eq!(version.semver, Version::parse("1.41.1").unwrap());
++ assert_eq!(version.commit_hash, None);
++ assert_eq!(version.commit_date, None);
++ assert_eq!(version.channel, Channel::Stable);
++ assert_eq!(version.host, "powerpc64le-unknown-linux-gnu");
++ assert_eq!(version.short_version_string, "rustc 1.41.1");
++ assert_eq!(
++ version.llvm_version,
++ Some(LlvmVersion { major: 7, minor: 0 })
++ );
++}
++
++#[test]
++fn parse_termux() {
++ let version = version_meta_for(
++ "rustc 1.46.0
++binary: rustc
++commit-hash: unknown
++commit-date: unknown
++host: aarch64-linux-android
++release: 1.46.0
++LLVM version: 10.0",
++ )
++ .unwrap();
++
++ assert_eq!(version.semver, Version::parse("1.46.0").unwrap());
++ assert_eq!(version.commit_hash, None);
++ assert_eq!(version.commit_date, None);
++ assert_eq!(version.channel, Channel::Stable);
++ assert_eq!(version.host, "aarch64-linux-android");
++ assert_eq!(version.short_version_string, "rustc 1.46.0");
++ assert_eq!(
++ version.llvm_version,
++ Some(LlvmVersion {
++ major: 10,
++ minor: 0,
++ })
++ );
++}
++
++#[test]
++fn parse_llvm_version_empty() {
++ let res: Result<LlvmVersion, _> = "".parse();
++ assert!(match res {
++ Err(LlvmVersionParseError::ParseIntError(_)) => true,
++ _ => false,
++ });
++}
++
++#[test]
++fn parse_llvm_version_invalid_char() {
++ let res: Result<LlvmVersion, _> = "A".parse();
++ assert!(match res {
++ Err(LlvmVersionParseError::ParseIntError(_)) => true,
++ _ => false,
++ });
++}
++
++#[test]
++fn parse_llvm_version_overflow() {
++ let res: Result<LlvmVersion, _> = "9999999999999999999999999999999".parse();
++ assert!(match res {
++ Err(LlvmVersionParseError::ParseIntError(_)) => true,
++ _ => false,
++ });
++}
++
++#[test]
++fn parse_llvm_version_leading_zero_on_zero() {
++ let res: Result<LlvmVersion, _> = "00".parse();
++ assert!(match res {
++ Err(LlvmVersionParseError::ComponentMustNotHaveLeadingZeros) => true,
++ _ => false,
++ });
++}
++
++#[test]
++fn parse_llvm_version_leading_zero_on_nonzero() {
++ let res: Result<LlvmVersion, _> = "01".parse();
++ assert!(match res {
++ Err(LlvmVersionParseError::ComponentMustNotHaveLeadingZeros) => true,
++ _ => false,
++ });
++}
++
++#[test]
++fn parse_llvm_version_4_components() {
++ let res: Result<LlvmVersion, _> = "4.0.0.0".parse();
++
++ assert!(match res {
++ Err(LlvmVersionParseError::TooManyComponents) => true,
++ _ => false,
++ });
++}
++
++#[test]
++fn parse_llvm_version_component_sign_plus() {
++ let res: Result<LlvmVersion, _> = "1.+3".parse();
++
++ assert!(match res {
++ Err(LlvmVersionParseError::ComponentMustNotHaveSign) => true,
++ _ => false,
++ });
++}
++
++#[test]
++fn parse_llvm_version_component_sign_minus() {
++ let res: Result<LlvmVersion, _> = "1.-3".parse();
++
++ assert!(match res {
++ Err(LlvmVersionParseError::ComponentMustNotHaveSign) => true,
++ _ => false,
++ });
++}
++
++#[test]
++fn parse_llvm_version_3() {
++ let res: Result<LlvmVersion, _> = "3".parse();
++
++ assert!(match res {
++ Err(LlvmVersionParseError::MinorVersionRequiredBefore4) => true,
++ _ => false,
++ });
++}
++
++#[test]
++fn parse_llvm_version_5() {
++ let v: LlvmVersion = "5".parse().unwrap();
++ assert_eq!(v, LlvmVersion { major: 5, minor: 0 });
++}
++
++#[test]
++fn parse_llvm_version_5_0() {
++ let v: LlvmVersion = "5.0".parse().unwrap();
++ assert_eq!(v, LlvmVersion { major: 5, minor: 0 });
++}
++
++#[test]
++fn parse_llvm_version_4_0() {
++ let v: LlvmVersion = "4.0".parse().unwrap();
++ assert_eq!(v, LlvmVersion { major: 4, minor: 0 });
++}
++
++#[test]
++fn parse_llvm_version_3_0() {
++ let v: LlvmVersion = "3.0".parse().unwrap();
++ assert_eq!(v, LlvmVersion { major: 3, minor: 0 });
++}
++
++#[test]
++fn parse_llvm_version_3_9() {
++ let v: LlvmVersion = "3.9".parse().unwrap();
++ assert_eq!(v, LlvmVersion { major: 3, minor: 9 });
++}
++
++#[test]
++fn parse_llvm_version_11_0() {
++ let v: LlvmVersion = "11.0".parse().unwrap();
++ assert_eq!(
++ v,
++ LlvmVersion {
++ major: 11,
++ minor: 0
++ }
++ );
++}
++
++#[test]
++fn parse_llvm_version_11() {
++ let v: LlvmVersion = "11".parse().unwrap();
++ assert_eq!(
++ v,
++ LlvmVersion {
++ major: 11,
++ minor: 0
++ }
++ );
++}
++
++#[test]
++fn test_llvm_version_comparison() {
++ // check that field order is correct
++ assert!(LlvmVersion { major: 3, minor: 9 } < LlvmVersion { major: 4, minor: 0 });
++}
++
++/*
++#[test]
++fn version_matches_replacement() {
++ let f = |s1: &str, s2: &str| {
++ let a = Version::parse(s1).unwrap();
++ let b = Version::parse(s2).unwrap();
++ println!("{} <= {} : {}", s1, s2, a <= b);
++ };
++
++ println!();
++
++ f("1.5.0", "1.5.0");
++ f("1.5.0-nightly", "1.5.0");
++ f("1.5.0", "1.5.0-nightly");
++ f("1.5.0-nightly", "1.5.0-nightly");
++
++ f("1.5.0", "1.6.0");
++ f("1.5.0-nightly", "1.6.0");
++ f("1.5.0", "1.6.0-nightly");
++ f("1.5.0-nightly", "1.6.0-nightly");
++
++ panic!();
++
++}
++*/
+diff --git a/third_party/rust/semver-parser/.cargo-checksum.json b/third_party/rust/semver-parser/.cargo-checksum.json
+deleted file mode 100644
+--- a/third_party/rust/semver-parser/.cargo-checksum.json
++++ /dev/null
+@@ -1,1 +0,0 @@
+-{"files":{"Cargo.toml":"67597114802114d2a7fdb457c1cf5f7e0c951b21e287c6a47b9a86b9028cf64d","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"d38feaa4f9468cd1e0ece22e0ad2eadfe6195a9a0a3843b7c722d5c7d81804fb","src/common.rs":"dc42336abd34e19ca9f732f33657e106f98dcc8c10d4c2564bc4f160cb31926e","src/lib.rs":"3ac8ef5a280344a25cb18ac386034c0fee8d64060fa14af5e25ed49f0cb2fd9e","src/range.rs":"3596f048d466d43887aff1e8c8c834476672a4627631ed35379c35466b5f02ec","src/recognize.rs":"9f16eda9fcd7d8af7eee4c3b89c611bd648040273fde6b35778f8a50b004c8b1","src/version.rs":"dbd91a4e4fd92a0aa9eb4f858ecbc1ecd680aa60572cc2ad2085e5c5c30e5b77"},"package":"388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"}
+\ No newline at end of file
+diff --git a/third_party/rust/semver-parser/Cargo.toml b/third_party/rust/semver-parser/Cargo.toml
+deleted file mode 100644
+--- a/third_party/rust/semver-parser/Cargo.toml
++++ /dev/null
+@@ -1,11 +0,0 @@
+-[package]
+-name = "semver-parser"
+-version = "0.7.0"
+-authors = ["Steve Klabnik <steve@steveklabnik.com>"]
+-license = "MIT/Apache-2.0"
+-repository = "https://github.com/steveklabnik/semver-parser"
+-homepage = "https://github.com/steveklabnik/semver-parser"
+-documentation = "https://docs.rs/semver-parser"
+-description = """
+-Parsing of the semver spec.
+-"""
+diff --git a/third_party/rust/semver-parser/LICENSE-APACHE b/third_party/rust/semver-parser/LICENSE-APACHE
+deleted file mode 100644
+--- a/third_party/rust/semver-parser/LICENSE-APACHE
++++ /dev/null
+@@ -1,201 +0,0 @@
+- Apache License
+- Version 2.0, January 2004
+- http://www.apache.org/licenses/
+-
+-TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+-
+-1. Definitions.
+-
+- "License" shall mean the terms and conditions for use, reproduction,
+- and distribution as defined by Sections 1 through 9 of this document.
+-
+- "Licensor" shall mean the copyright owner or entity authorized by
+- the copyright owner that is granting the License.
+-
+- "Legal Entity" shall mean the union of the acting entity and all
+- other entities that control, are controlled by, or are under common
+- control with that entity. For the purposes of this definition,
+- "control" means (i) the power, direct or indirect, to cause the
+- direction or management of such entity, whether by contract or
+- otherwise, or (ii) ownership of fifty percent (50%) or more of the
+- outstanding shares, or (iii) beneficial ownership of such entity.
+-
+- "You" (or "Your") shall mean an individual or Legal Entity
+- exercising permissions granted by this License.
+-
+- "Source" form shall mean the preferred form for making modifications,
+- including but not limited to software source code, documentation
+- source, and configuration files.
+-
+- "Object" form shall mean any form resulting from mechanical
+- transformation or translation of a Source form, including but
+- not limited to compiled object code, generated documentation,
+- and conversions to other media types.
+-
+- "Work" shall mean the work of authorship, whether in Source or
+- Object form, made available under the License, as indicated by a
+- copyright notice that is included in or attached to the work
+- (an example is provided in the Appendix below).
+-
+- "Derivative Works" shall mean any work, whether in Source or Object
+- form, that is based on (or derived from) the Work and for which the
+- editorial revisions, annotations, elaborations, or other modifications
+- represent, as a whole, an original work of authorship. For the purposes
+- of this License, Derivative Works shall not include works that remain
+- separable from, or merely link (or bind by name) to the interfaces of,
+- the Work and Derivative Works thereof.
+-
+- "Contribution" shall mean any work of authorship, including
+- the original version of the Work and any modifications or additions
+- to that Work or Derivative Works thereof, that is intentionally
+- submitted to Licensor for inclusion in the Work by the copyright owner
+- or by an individual or Legal Entity authorized to submit on behalf of
+- the copyright owner. For the purposes of this definition, "submitted"
+- means any form of electronic, verbal, or written communication sent
+- to the Licensor or its representatives, including but not limited to
+- communication on electronic mailing lists, source code control systems,
+- and issue tracking systems that are managed by, or on behalf of, the
+- Licensor for the purpose of discussing and improving the Work, but
+- excluding communication that is conspicuously marked or otherwise
+- designated in writing by the copyright owner as "Not a Contribution."
+-
+- "Contributor" shall mean Licensor and any individual or Legal Entity
+- on behalf of whom a Contribution has been received by Licensor and
+- subsequently incorporated within the Work.
+-
+-2. Grant of Copyright License. Subject to the terms and conditions of
+- this License, each Contributor hereby grants to You a perpetual,
+- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+- copyright license to reproduce, prepare Derivative Works of,
+- publicly display, publicly perform, sublicense, and distribute the
+- Work and such Derivative Works in Source or Object form.
+-
+-3. Grant of Patent License. Subject to the terms and conditions of
+- this License, each Contributor hereby grants to You a perpetual,
+- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+- (except as stated in this section) patent license to make, have made,
+- use, offer to sell, sell, import, and otherwise transfer the Work,
+- where such license applies only to those patent claims licensable
+- by such Contributor that are necessarily infringed by their
+- Contribution(s) alone or by combination of their Contribution(s)
+- with the Work to which such Contribution(s) was submitted. If You
+- institute patent litigation against any entity (including a
+- cross-claim or counterclaim in a lawsuit) alleging that the Work
+- or a Contribution incorporated within the Work constitutes direct
+- or contributory patent infringement, then any patent licenses
+- granted to You under this License for that Work shall terminate
+- as of the date such litigation is filed.
+-
+-4. Redistribution. You may reproduce and distribute copies of the
+- Work or Derivative Works thereof in any medium, with or without
+- modifications, and in Source or Object form, provided that You
+- meet the following conditions:
+-
+- (a) You must give any other recipients of the Work or
+- Derivative Works a copy of this License; and
+-
+- (b) You must cause any modified files to carry prominent notices
+- stating that You changed the files; and
+-
+- (c) You must retain, in the Source form of any Derivative Works
+- that You distribute, all copyright, patent, trademark, and
+- attribution notices from the Source form of the Work,
+- excluding those notices that do not pertain to any part of
+- the Derivative Works; and
+-
+- (d) If the Work includes a "NOTICE" text file as part of its
+- distribution, then any Derivative Works that You distribute must
+- include a readable copy of the attribution notices contained
+- within such NOTICE file, excluding those notices that do not
+- pertain to any part of the Derivative Works, in at least one
+- of the following places: within a NOTICE text file distributed
+- as part of the Derivative Works; within the Source form or
+- documentation, if provided along with the Derivative Works; or,
+- within a display generated by the Derivative Works, if and
+- wherever such third-party notices normally appear. The contents
+- of the NOTICE file are for informational purposes only and
+- do not modify the License. You may add Your own attribution
+- notices within Derivative Works that You distribute, alongside
+- or as an addendum to the NOTICE text from the Work, provided
+- that such additional attribution notices cannot be construed
+- as modifying the License.
+-
+- You may add Your own copyright statement to Your modifications and
+- may provide additional or different license terms and conditions
+- for use, reproduction, or distribution of Your modifications, or
+- for any such Derivative Works as a whole, provided Your use,
+- reproduction, and distribution of the Work otherwise complies with
+- the conditions stated in this License.
+-
+-5. Submission of Contributions. Unless You explicitly state otherwise,
+- any Contribution intentionally submitted for inclusion in the Work
+- by You to the Licensor shall be under the terms and conditions of
+- this License, without any additional terms or conditions.
+- Notwithstanding the above, nothing herein shall supersede or modify
+- the terms of any separate license agreement you may have executed
+- with Licensor regarding such Contributions.
+-
+-6. Trademarks. This License does not grant permission to use the trade
+- names, trademarks, service marks, or product names of the Licensor,
+- except as required for reasonable and customary use in describing the
+- origin of the Work and reproducing the content of the NOTICE file.
+-
+-7. Disclaimer of Warranty. Unless required by applicable law or
+- agreed to in writing, Licensor provides the Work (and each
+- Contributor provides its Contributions) on an "AS IS" BASIS,
+- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+- implied, including, without limitation, any warranties or conditions
+- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+- PARTICULAR PURPOSE. You are solely responsible for determining the
+- appropriateness of using or redistributing the Work and assume any
+- risks associated with Your exercise of permissions under this License.
+-
+-8. Limitation of Liability. In no event and under no legal theory,
+- whether in tort (including negligence), contract, or otherwise,
+- unless required by applicable law (such as deliberate and grossly
+- negligent acts) or agreed to in writing, shall any Contributor be
+- liable to You for damages, including any direct, indirect, special,
+- incidental, or consequential damages of any character arising as a
+- result of this License or out of the use or inability to use the
+- Work (including but not limited to damages for loss of goodwill,
+- work stoppage, computer failure or malfunction, or any and all
+- other commercial damages or losses), even if such Contributor
+- has been advised of the possibility of such damages.
+-
+-9. Accepting Warranty or Additional Liability. While redistributing
+- the Work or Derivative Works thereof, You may choose to offer,
+- and charge a fee for, acceptance of support, warranty, indemnity,
+- or other liability obligations and/or rights consistent with this
+- License. However, in accepting such obligations, You may act only
+- on Your own behalf and on Your sole responsibility, not on behalf
+- of any other Contributor, and only if You agree to indemnify,
+- defend, and hold each Contributor harmless for any liability
+- incurred by, or claims asserted against, such Contributor by reason
+- of your accepting any such warranty or additional liability.
+-
+-END OF TERMS AND CONDITIONS
+-
+-APPENDIX: How to apply the Apache License to your work.
+-
+- To apply the Apache License to your work, attach the following
+- boilerplate notice, with the fields enclosed by brackets "[]"
+- replaced with your own identifying information. (Don't include
+- the brackets!) The text should be enclosed in the appropriate
+- comment syntax for the file format. We also recommend that a
+- file or class name and description of purpose be included on the
+- same "printed page" as the copyright notice for easier
+- identification within third-party archives.
+-
+-Copyright [yyyy] [name of copyright owner]
+-
+-Licensed under the Apache License, Version 2.0 (the "License");
+-you may not use this file except in compliance with the License.
+-You may obtain a copy of the License at
+-
+- http://www.apache.org/licenses/LICENSE-2.0
+-
+-Unless required by applicable law or agreed to in writing, software
+-distributed under the License is distributed on an "AS IS" BASIS,
+-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-See the License for the specific language governing permissions and
+-limitations under the License.
+diff --git a/third_party/rust/semver-parser/LICENSE-MIT b/third_party/rust/semver-parser/LICENSE-MIT
+deleted file mode 100644
+--- a/third_party/rust/semver-parser/LICENSE-MIT
++++ /dev/null
+@@ -1,25 +0,0 @@
+-Copyright (c) 2016 Steve Klabnik
+-
+-Permission is hereby granted, free of charge, to any
+-person obtaining a copy of this software and associated
+-documentation files (the "Software"), to deal in the
+-Software without restriction, including without
+-limitation the rights to use, copy, modify, merge,
+-publish, distribute, sublicense, and/or sell copies of
+-the Software, and to permit persons to whom the Software
+-is furnished to do so, subject to the following
+-conditions:
+-
+-The above copyright notice and this permission notice
+-shall be included in all copies or substantial portions
+-of the Software.
+-
+-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
+-ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+-TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+-PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+-SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+-IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+-DEALINGS IN THE SOFTWARE.
+diff --git a/third_party/rust/semver-parser/src/common.rs b/third_party/rust/semver-parser/src/common.rs
+deleted file mode 100644
+--- a/third_party/rust/semver-parser/src/common.rs
++++ /dev/null
+@@ -1,66 +0,0 @@
+-use version::Identifier;
+-use recognize::{Recognize, Alt, OneOrMore, Inclusive, OneByte};
+-use std::str::from_utf8;
+-
+-// by the time we get here, we know that it's all valid characters, so this doesn't need to return
+-// a result or anything
+-fn parse_meta(s: &str) -> Vec<Identifier> {
+- // Originally, I wanted to implement this method via calling parse, but parse is tolerant of
+- // leading zeroes, and we want anything with leading zeroes to be considered alphanumeric, not
+- // numeric. So the strategy is to check with a recognizer first, and then call parse once
+- // we've determined that it's a number without a leading zero.
+- s.split(".")
+- .map(|part| {
+- // another wrinkle: we made sure that any number starts with a
+- // non-zero. But there's a problem: an actual zero is a number, yet
+- // gets left out by this heuristic. So let's also check for the
+- // single, lone zero.
+- if is_alpha_numeric(part) {
+- Identifier::AlphaNumeric(part.to_string())
+- } else {
+- // we can unwrap here because we know it is only digits due to the regex
+- Identifier::Numeric(part.parse().unwrap())
+- }
+- }).collect()
+-}
+-
+-// parse optional metadata (preceded by the prefix character)
+-pub fn parse_optional_meta(s: &[u8], prefix_char: u8)-> Result<(Vec<Identifier>, usize), String> {
+- if let Some(len) = prefix_char.p(s) {
+- let start = len;
+- if let Some(len) = letters_numbers_dash_dot(&s[start..]) {
+- let end = start + len;
+- Ok((parse_meta(from_utf8(&s[start..end]).unwrap()), end))
+- } else {
+- Err("Error parsing prerelease".to_string())
+- }
+- } else {
+- Ok((Vec::new(), 0))
+- }
+-}
+-
+-pub fn is_alpha_numeric(s: &str) -> bool {
+- if let Some((_val, len)) = numeric_identifier(s.as_bytes()) {
+- // Return true for number with leading zero
+- // Note: doing it this way also handily makes overflow fail over.
+- len != s.len()
+- } else {
+- true
+- }
+-}
+-
+-// Note: could plumb overflow error up to return value as Result
+-pub fn numeric_identifier(s: &[u8]) -> Option<(u64, usize)> {
+- if let Some(len) = Alt(b'0', OneOrMore(Inclusive(b'0'..b'9'))).p(s) {
+- from_utf8(&s[0..len]).unwrap().parse().ok().map(|val| (val, len))
+- } else {
+- None
+- }
+-}
+-
+-pub fn letters_numbers_dash_dot(s: &[u8]) -> Option<usize> {
+- OneOrMore(OneByte(|c| c == b'-' || c == b'.' ||
+- (b'0' <= c && c <= b'9') ||
+- (b'a' <= c && c <= b'z') ||
+- (b'A' <= c && c <= b'Z'))).p(s)
+-}
+diff --git a/third_party/rust/semver-parser/src/lib.rs b/third_party/rust/semver-parser/src/lib.rs
+deleted file mode 100644
+--- a/third_party/rust/semver-parser/src/lib.rs
++++ /dev/null
+@@ -1,8 +0,0 @@
+-pub mod version;
+-pub mod range;
+-
+-// for private stuff the two share
+-mod common;
+-
+-// for recognizer combinators
+-mod recognize;
+diff --git a/third_party/rust/semver-parser/src/range.rs b/third_party/rust/semver-parser/src/range.rs
+deleted file mode 100644
+--- a/third_party/rust/semver-parser/src/range.rs
++++ /dev/null
+@@ -1,696 +0,0 @@
+-use common::{self, numeric_identifier, letters_numbers_dash_dot};
+-use version::Identifier;
+-use std::str::{FromStr, from_utf8};
+-use recognize::*;
+-
+-#[derive(Debug)]
+-pub struct VersionReq {
+- pub predicates: Vec<Predicate>,
+-}
+-
+-#[derive(PartialEq,Debug)]
+-pub enum WildcardVersion {
+- Major,
+- Minor,
+- Patch,
+-}
+-
+-#[derive(PartialEq,Debug)]
+-pub enum Op {
+- Ex, // Exact
+- Gt, // Greater than
+- GtEq, // Greater than or equal to
+- Lt, // Less than
+- LtEq, // Less than or equal to
+- Tilde, // e.g. ~1.0.0
+- Compatible, // compatible by definition of semver, indicated by ^
+- Wildcard(WildcardVersion), // x.y.*, x.*, *
+-}
+-
+-impl FromStr for Op {
+- type Err = String;
+-
+- fn from_str(s: &str) -> Result<Op, String> {
+- match s {
+- "=" => Ok(Op::Ex),
+- ">" => Ok(Op::Gt),
+- ">=" => Ok(Op::GtEq),
+- "<" => Ok(Op::Lt),
+- "<=" => Ok(Op::LtEq),
+- "~" => Ok(Op::Tilde),
+- "^" => Ok(Op::Compatible),
+- _ => Err(String::from("Could not parse Op")),
+- }
+- }
+-}
+-
+-#[derive(PartialEq,Debug)]
+-pub struct Predicate {
+- pub op: Op,
+- pub major: u64,
+- pub minor: Option<u64>,
+- pub patch: Option<u64>,
+- pub pre: Vec<Identifier>,
+-}
+-
+-fn numeric_or_wild(s: &[u8]) -> Option<(Option<u64>, usize)> {
+- if let Some((val, len)) = numeric_identifier(s) {
+- Some((Some(val), len))
+- } else if let Some(len) = OneOf(b"*xX").p(s) {
+- Some((None, len))
+- } else {
+- None
+- }
+-}
+-
+-fn dot_numeric_or_wild(s: &[u8]) -> Option<(Option<u64>, usize)> {
+- b'.'.p(s).and_then(|len|
+- numeric_or_wild(&s[len..]).map(|(val, len2)| (val, len + len2))
+- )
+-}
+-
+-fn operation(s: &[u8]) -> Option<(Op, usize)> {
+- if let Some(len) = "=".p(s) {
+- Some((Op::Ex, len))
+- } else if let Some(len) = ">=".p(s) {
+- Some((Op::GtEq, len))
+- } else if let Some(len) = ">".p(s) {
+- Some((Op::Gt, len))
+- } else if let Some(len) = "<=".p(s) {
+- Some((Op::LtEq, len))
+- } else if let Some(len) = "<".p(s) {
+- Some((Op::Lt, len))
+- } else if let Some(len) = "~".p(s) {
+- Some((Op::Tilde, len))
+- } else if let Some(len) = "^".p(s) {
+- Some((Op::Compatible, len))
+- } else {
+- None
+- }
+-}
+-
+-fn whitespace(s: &[u8]) -> Option<usize> {
+- ZeroOrMore(OneOf(b"\t\r\n ")).p(s)
+-}
+-
+-pub fn parse_predicate(range: &str) -> Result<Predicate, String> {
+- let s = range.trim().as_bytes();
+- let mut i = 0;
+- let mut operation = if let Some((op, len)) = operation(&s[i..]) {
+- i += len;
+- op
+- } else {
+- // operations default to Compatible
+- Op::Compatible
+- };
+- if let Some(len) = whitespace.p(&s[i..]) {
+- i += len;
+- }
+- let major = if let Some((major, len)) = numeric_identifier(&s[i..]) {
+- i += len;
+- major
+- } else {
+- return Err("Error parsing major version number: ".to_string());
+- };
+- let minor = if let Some((minor, len)) = dot_numeric_or_wild(&s[i..]) {
+- i += len;
+- if minor.is_none() {
+- operation = Op::Wildcard(WildcardVersion::Minor);
+- }
+- minor
+- } else {
+- None
+- };
+- let patch = if let Some((patch, len)) = dot_numeric_or_wild(&s[i..]) {
+- i += len;
+- if patch.is_none() {
+- operation = Op::Wildcard(WildcardVersion::Patch);
+- }
+- patch
+- } else {
+- None
+- };
+- let (pre, pre_len) = common::parse_optional_meta(&s[i..], b'-')?;
+- i += pre_len;
+- if let Some(len) = (b'+', letters_numbers_dash_dot).p(&s[i..]) {
+- i += len;
+- }
+- if i != s.len() {
+- return Err("Extra junk after valid predicate: ".to_string() +
+- from_utf8(&s[i..]).unwrap());
+- }
+- Ok(Predicate {
+- op: operation,
+- major: major,
+- minor: minor,
+- patch: patch,
+- pre: pre,
+- })
+-}
+-
+-pub fn parse(ranges: &str) -> Result<VersionReq, String> {
+- // null is an error
+- if ranges == "\0" {
+- return Err(String::from("Null is not a valid VersionReq"));
+- }
+-
+- // an empty range is a major version wildcard
+- // so is a lone * or x of either capitalization
+- if (ranges == "")
+- || (ranges == "*")
+- || (ranges == "x")
+- || (ranges == "X") {
+- return Ok(VersionReq {
+- predicates: vec![Predicate {
+- op: Op::Wildcard(WildcardVersion::Major),
+- major: 0,
+- minor: None,
+- patch: None,
+- pre: Vec::new(),
+- }],
+- });
+- }
+-
+-
+- let ranges = ranges.trim();
+-
+- let predicates: Result<Vec<_>, String> = ranges
+- .split(",")
+- .map(|range| {
+- parse_predicate(range)
+- })
+- .collect();
+-
+- let predicates = try!(predicates);
+-
+- if predicates.len() == 0 {
+- return Err(String::from("VersionReq did not parse properly"));
+- }
+-
+- Ok(VersionReq {
+- predicates: predicates,
+- })
+-}
+-
+-#[cfg(test)]
+-mod tests {
+- use super::*;
+- use range;
+- use version::Identifier;
+-
+- #[test]
+- fn test_parsing_default() {
+- let r = range::parse("1.0.0").unwrap();
+-
+- assert_eq!(Predicate {
+- op: Op::Compatible,
+- major: 1,
+- minor: Some(0),
+- patch: Some(0),
+- pre: Vec::new(),
+- },
+- r.predicates[0]
+- );
+- }
+-
+- #[test]
+- fn test_parsing_exact_01() {
+- let r = range::parse("=1.0.0").unwrap();
+-
+- assert_eq!(Predicate {
+- op: Op::Ex,
+- major: 1,
+- minor: Some(0),
+- patch: Some(0),
+- pre: Vec::new(),
+- },
+- r.predicates[0]
+- );
+- }
+-
+- #[test]
+- fn test_parsing_exact_02() {
+- let r = range::parse("=0.9.0").unwrap();
+-
+- assert_eq!(Predicate {
+- op: Op::Ex,
+- major: 0,
+- minor: Some(9),
+- patch: Some(0),
+- pre: Vec::new(),
+- },
+- r.predicates[0]
+- );
+- }
+-
+- #[test]
+- fn test_parsing_exact_03() {
+- let r = range::parse("=0.1.0-beta2.a").unwrap();
+-
+- assert_eq!(Predicate {
+- op: Op::Ex,
+- major: 0,
+- minor: Some(1),
+- patch: Some(0),
+- pre: vec![Identifier::AlphaNumeric(String::from("beta2")),
+- Identifier::AlphaNumeric(String::from("a"))],
+- },
+- r.predicates[0]
+- );
+- }
+-
+- #[test]
+- pub fn test_parsing_greater_than() {
+- let r = range::parse("> 1.0.0").unwrap();
+-
+- assert_eq!(Predicate {
+- op: Op::Gt,
+- major: 1,
+- minor: Some(0),
+- patch: Some(0),
+- pre: Vec::new(),
+- },
+- r.predicates[0]
+- );
+- }
+-
+- #[test]
+- pub fn test_parsing_greater_than_01() {
+- let r = range::parse(">= 1.0.0").unwrap();
+-
+- assert_eq!(Predicate {
+- op: Op::GtEq,
+- major: 1,
+- minor: Some(0),
+- patch: Some(0),
+- pre: Vec::new(),
+- },
+- r.predicates[0]
+- );
+- }
+-
+- #[test]
+- pub fn test_parsing_greater_than_02() {
+- let r = range::parse(">= 2.1.0-alpha2").unwrap();
+-
+- assert_eq!(Predicate {
+- op: Op::GtEq,
+- major: 2,
+- minor: Some(1),
+- patch: Some(0),
+- pre: vec![Identifier::AlphaNumeric(String::from("alpha2"))],
+- },
+- r.predicates[0]
+- );
+- }
+-
+- #[test]
+- pub fn test_parsing_less_than() {
+- let r = range::parse("< 1.0.0").unwrap();
+-
+- assert_eq!(Predicate {
+- op: Op::Lt,
+- major: 1,
+- minor: Some(0),
+- patch: Some(0),
+- pre: Vec::new(),
+- },
+- r.predicates[0]
+- );
+- }
+-
+- #[test]
+- pub fn test_parsing_less_than_eq() {
+- let r = range::parse("<= 2.1.0-alpha2").unwrap();
+-
+- assert_eq!(Predicate {
+- op: Op::LtEq,
+- major: 2,
+- minor: Some(1),
+- patch: Some(0),
+- pre: vec![Identifier::AlphaNumeric(String::from("alpha2"))],
+- },
+- r.predicates[0]
+- );
+- }
+-
+- #[test]
+- pub fn test_parsing_tilde() {
+- let r = range::parse("~1").unwrap();
+-
+- assert_eq!(Predicate {
+- op: Op::Tilde,
+- major: 1,
+- minor: None,
+- patch: None,
+- pre: Vec::new(),
+- },
+- r.predicates[0]
+- );
+- }
+-
+- #[test]
+- pub fn test_parsing_compatible() {
+- let r = range::parse("^0").unwrap();
+-
+- assert_eq!(Predicate {
+- op: Op::Compatible,
+- major: 0,
+- minor: None,
+- patch: None,
+- pre: Vec::new(),
+- },
+- r.predicates[0]
+- );
+- }
+-
+- #[test]
+- fn test_parsing_blank() {
+- let r = range::parse("").unwrap();
+-
+- assert_eq!(Predicate {
+- op: Op::Wildcard(WildcardVersion::Major),
+- major: 0,
+- minor: None,
+- patch: None,
+- pre: Vec::new(),
+- },
+- r.predicates[0]
+- );
+- }
+-
+- #[test]
+- fn test_parsing_wildcard() {
+- let r = range::parse("*").unwrap();
+-
+- assert_eq!(Predicate {
+- op: Op::Wildcard(WildcardVersion::Major),
+- major: 0,
+- minor: None,
+- patch: None,
+- pre: Vec::new(),
+- },
+- r.predicates[0]
+- );
+- }
+-
+- #[test]
+- fn test_parsing_x() {
+- let r = range::parse("x").unwrap();
+-
+- assert_eq!(Predicate {
+- op: Op::Wildcard(WildcardVersion::Major),
+- major: 0,
+- minor: None,
+- patch: None,
+- pre: Vec::new(),
+- },
+- r.predicates[0]
+- );
+- }
+-
+- #[test]
+- fn test_parsing_capital_x() {
+- let r = range::parse("X").unwrap();
+-
+- assert_eq!(Predicate {
+- op: Op::Wildcard(WildcardVersion::Major),
+- major: 0,
+- minor: None,
+- patch: None,
+- pre: Vec::new(),
+- },
+- r.predicates[0]
+- );
+- }
+-
+- #[test]
+- fn test_parsing_minor_wildcard_star() {
+- let r = range::parse("1.*").unwrap();
+-
+- assert_eq!(Predicate {
+- op: Op::Wildcard(WildcardVersion::Minor),
+- major: 1,
+- minor: None,
+- patch: None,
+- pre: Vec::new(),
+- },
+- r.predicates[0]
+- );
+- }
+-
+- #[test]
+- fn test_parsing_minor_wildcard_x() {
+- let r = range::parse("1.x").unwrap();
+-
+- assert_eq!(Predicate {
+- op: Op::Wildcard(WildcardVersion::Minor),
+- major: 1,
+- minor: None,
+- patch: None,
+- pre: Vec::new(),
+- },
+- r.predicates[0]
+- );
+- }
+-
+- #[test]
+- fn test_parsing_minor_wildcard_capital_x() {
+- let r = range::parse("1.X").unwrap();
+-
+- assert_eq!(Predicate {
+- op: Op::Wildcard(WildcardVersion::Minor),
+- major: 1,
+- minor: None,
+- patch: None,
+- pre: Vec::new(),
+- },
+- r.predicates[0]
+- );
+- }
+-
+- #[test]
+- fn test_parsing_patch_wildcard_star() {
+- let r = range::parse("1.2.*").unwrap();
+-
+- assert_eq!(Predicate {
+- op: Op::Wildcard(WildcardVersion::Patch),
+- major: 1,
+- minor: Some(2),
+- patch: None,
+- pre: Vec::new(),
+- },
+- r.predicates[0]
+- );
+- }
+-
+- #[test]
+- fn test_parsing_patch_wildcard_x() {
+- let r = range::parse("1.2.x").unwrap();
+-
+- assert_eq!(Predicate {
+- op: Op::Wildcard(WildcardVersion::Patch),
+- major: 1,
+- minor: Some(2),
+- patch: None,
+- pre: Vec::new(),
+- },
+- r.predicates[0]
+- );
+- }
+-
+- #[test]
+- fn test_parsing_patch_wildcard_capital_x() {
+- let r = range::parse("1.2.X").unwrap();
+-
+- assert_eq!(Predicate {
+- op: Op::Wildcard(WildcardVersion::Patch),
+- major: 1,
+- minor: Some(2),
+- patch: None,
+- pre: Vec::new(),
+- },
+- r.predicates[0]
+- );
+- }
+-
+- #[test]
+- pub fn test_multiple_01() {
+- let r = range::parse("> 0.0.9, <= 2.5.3").unwrap();
+-
+- assert_eq!(Predicate {
+- op: Op::Gt,
+- major: 0,
+- minor: Some(0),
+- patch: Some(9),
+- pre: Vec::new(),
+- },
+- r.predicates[0]
+- );
+-
+- assert_eq!(Predicate {
+- op: Op::LtEq,
+- major: 2,
+- minor: Some(5),
+- patch: Some(3),
+- pre: Vec::new(),
+- },
+- r.predicates[1]
+- );
+- }
+-
+- #[test]
+- pub fn test_multiple_02() {
+- let r = range::parse("0.3.0, 0.4.0").unwrap();
+-
+- assert_eq!(Predicate {
+- op: Op::Compatible,
+- major: 0,
+- minor: Some(3),
+- patch: Some(0),
+- pre: Vec::new(),
+- },
+- r.predicates[0]
+- );
+-
+- assert_eq!(Predicate {
+- op: Op::Compatible,
+- major: 0,
+- minor: Some(4),
+- patch: Some(0),
+- pre: Vec::new(),
+- },
+- r.predicates[1]
+- );
+- }
+-
+- #[test]
+- pub fn test_multiple_03() {
+- let r = range::parse("<= 0.2.0, >= 0.5.0").unwrap();
+-
+- assert_eq!(Predicate {
+- op: Op::LtEq,
+- major: 0,
+- minor: Some(2),
+- patch: Some(0),
+- pre: Vec::new(),
+- },
+- r.predicates[0]
+- );
+-
+- assert_eq!(Predicate {
+- op: Op::GtEq,
+- major: 0,
+- minor: Some(5),
+- patch: Some(0),
+- pre: Vec::new(),
+- },
+- r.predicates[1]
+- );
+- }
+-
+- #[test]
+- pub fn test_multiple_04() {
+- let r = range::parse("0.1.0, 0.1.4, 0.1.6").unwrap();
+-
+- assert_eq!(Predicate {
+- op: Op::Compatible,
+- major: 0,
+- minor: Some(1),
+- patch: Some(0),
+- pre: Vec::new(),
+- },
+- r.predicates[0]
+- );
+-
+- assert_eq!(Predicate {
+- op: Op::Compatible,
+- major: 0,
+- minor: Some(1),
+- patch: Some(4),
+- pre: Vec::new(),
+- },
+- r.predicates[1]
+- );
+-
+- assert_eq!(Predicate {
+- op: Op::Compatible,
+- major: 0,
+- minor: Some(1),
+- patch: Some(6),
+- pre: Vec::new(),
+- },
+- r.predicates[2]
+- );
+- }
+-
+- #[test]
+- pub fn test_multiple_05() {
+- let r = range::parse(">=0.5.1-alpha3, <0.6").unwrap();
+-
+- assert_eq!(Predicate {
+- op: Op::GtEq,
+- major: 0,
+- minor: Some(5),
+- patch: Some(1),
+- pre: vec![Identifier::AlphaNumeric(String::from("alpha3"))],
+- },
+- r.predicates[0]
+- );
+-
+- assert_eq!(Predicate {
+- op: Op::Lt,
+- major: 0,
+- minor: Some(6),
+- patch: None,
+- pre: Vec::new(),
+- },
+- r.predicates[1]
+- );
+- }
+-
+- #[test]
+- fn test_parse_build_metadata_with_predicate() {
+- assert_eq!(range::parse("^1.2.3+meta").unwrap().predicates[0].op,
+- Op::Compatible);
+- assert_eq!(range::parse("~1.2.3+meta").unwrap().predicates[0].op,
+- Op::Tilde);
+- assert_eq!(range::parse("=1.2.3+meta").unwrap().predicates[0].op,
+- Op::Ex);
+- assert_eq!(range::parse("<=1.2.3+meta").unwrap().predicates[0].op,
+- Op::LtEq);
+- assert_eq!(range::parse(">=1.2.3+meta").unwrap().predicates[0].op,
+- Op::GtEq);
+- assert_eq!(range::parse("<1.2.3+meta").unwrap().predicates[0].op,
+- Op::Lt);
+- assert_eq!(range::parse(">1.2.3+meta").unwrap().predicates[0].op,
+- Op::Gt);
+- }
+-
+- #[test]
+- pub fn test_parse_errors() {
+- assert!(range::parse("\0").is_err());
+- assert!(range::parse(">= >= 0.0.2").is_err());
+- assert!(range::parse(">== 0.0.2").is_err());
+- assert!(range::parse("a.0.0").is_err());
+- assert!(range::parse("1.0.0-").is_err());
+- assert!(range::parse(">=").is_err());
+- assert!(range::parse("> 0.1.0,").is_err());
+- assert!(range::parse("> 0.3.0, ,").is_err());
+- }
+-
+- #[test]
+- pub fn test_large_major_version() {
+- assert!(range::parse("18446744073709551617.0.0").is_err());
+- }
+-
+- #[test]
+- pub fn test_large_minor_version() {
+- assert!(range::parse("0.18446744073709551617.0").is_err());
+- }
+-
+- #[test]
+- pub fn test_large_patch_version() {
+- assert!(range::parse("0.0.18446744073709551617").is_err());
+- }
+-}
+diff --git a/third_party/rust/semver-parser/src/recognize.rs b/third_party/rust/semver-parser/src/recognize.rs
+deleted file mode 100644
+--- a/third_party/rust/semver-parser/src/recognize.rs
++++ /dev/null
+@@ -1,154 +0,0 @@
+-// Copyright 2017 Google Inc. All rights reserved.
+-//
+-// Licensed under either of MIT or Apache License, Version 2.0,
+-// at your option.
+-//
+-// Use of this source code is governed by a MIT-style
+-// license that can be found in the LICENSE file or at
+-// https://opensource.org/licenses/MIT.
+-//
+-// Licensed under the Apache License, Version 2.0 (the "License");
+-// you may not use this file except in compliance with the License.
+-// You may obtain a copy of the License at
+-//
+-// http://www.apache.org/licenses/LICENSE-2.0
+-//
+-// Unless required by applicable law or agreed to in writing, software
+-// distributed under the License is distributed on an "AS IS" BASIS,
+-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-// See the License for the specific language governing permissions and
+-// limitations under the License.
+-
+-//! Simple recognizer combinators.
+-
+-// This version is similar to a similar one in the "lang" module of
+-// xi-editor, but is stripped down to only the needed combinators.
+-
+-use std::ops;
+-
+-pub trait Recognize {
+- fn p(&self, s: &[u8]) -> Option<usize>;
+-}
+-
+-impl<F: Fn(&[u8]) -> Option<usize>> Recognize for F {
+- #[inline(always)]
+- fn p(&self, s: &[u8]) -> Option<usize> {
+- self(s)
+- }
+-}
+-
+-pub struct OneByte<F>(pub F);
+-
+-impl<F: Fn(u8) -> bool> Recognize for OneByte<F> {
+- #[inline(always)]
+- fn p(&self, s: &[u8]) -> Option<usize> {
+- if s.is_empty() || !self.0(s[0]) {
+- None
+- } else {
+- Some(1)
+- }
+- }
+-}
+-
+-impl Recognize for u8 {
+- #[inline(always)]
+- fn p(&self, s: &[u8]) -> Option<usize> {
+- OneByte(|b| b == *self).p(s)
+- }
+-}
+-
+-/// Use Inclusive(a..b) to indicate an inclusive range. When a...b syntax becomes
+-/// stable, we can get rid of this and switch to that.
+-pub struct Inclusive<T>(pub T);
+-
+-impl Recognize for Inclusive<ops::Range<u8>> {
+- #[inline(always)]
+- fn p(&self, s: &[u8]) -> Option<usize> {
+- OneByte(|x| x >= self.0.start && x <= self.0.end).p(s)
+- }
+-}
+-
+-impl<'a> Recognize for &'a [u8] {
+- #[inline(always)]
+- fn p(&self, s: &[u8]) -> Option<usize> {
+- let len = self.len();
+- if s.len() >= len && &s[..len] == *self {
+- Some(len)
+- } else {
+- None
+- }
+- }
+-}
+-
+-impl<'a> Recognize for &'a str {
+- #[inline(always)]
+- fn p(&self, s: &[u8]) -> Option<usize> {
+- self.as_bytes().p(s)
+- }
+-}
+-
+-impl<P1: Recognize, P2: Recognize> Recognize for (P1, P2) {
+- #[inline(always)]
+- fn p(&self, s: &[u8]) -> Option<usize> {
+- self.0.p(s).and_then(|len1|
+- self.1.p(&s[len1..]).map(|len2|
+- len1 + len2))
+- }
+-}
+-
+-/// Choice from two heterogeneous alternatives.
+-pub struct Alt<P1, P2>(pub P1, pub P2);
+-
+-impl<P1: Recognize, P2: Recognize> Recognize for Alt<P1, P2> {
+- #[inline(always)]
+- fn p(&self, s: &[u8]) -> Option<usize> {
+- self.0.p(s).or_else(|| self.1.p(s))
+- }
+-}
+-
+-/// Choice from a homogenous slice of parsers.
+-pub struct OneOf<'a, P: 'a>(pub &'a [P]);
+-
+-impl<'a, P: Recognize> Recognize for OneOf<'a, P> {
+- #[inline]
+- fn p(&self, s: &[u8]) -> Option<usize> {
+- for ref p in self.0 {
+- if let Some(len) = p.p(s) {
+- return Some(len);
+- }
+- }
+- None
+- }
+-}
+-
+-pub struct OneOrMore<P>(pub P);
+-
+-impl<P: Recognize> Recognize for OneOrMore<P> {
+- #[inline]
+- fn p(&self, s: &[u8]) -> Option<usize> {
+- let mut i = 0;
+- let mut count = 0;
+- while let Some(len) = self.0.p(&s[i..]) {
+- i += len;
+- count += 1;
+- }
+- if count >= 1 {
+- Some(i)
+- } else {
+- None
+- }
+- }
+-}
+-
+-pub struct ZeroOrMore<P>(pub P);
+-
+-impl<P: Recognize> Recognize for ZeroOrMore<P> {
+- #[inline]
+- fn p(&self, s: &[u8]) -> Option<usize> {
+- let mut i = 0;
+- while let Some(len) = self.0.p(&s[i..]) {
+- i += len;
+- }
+- Some(i)
+- }
+-}
+diff --git a/third_party/rust/semver-parser/src/version.rs b/third_party/rust/semver-parser/src/version.rs
+deleted file mode 100644
+--- a/third_party/rust/semver-parser/src/version.rs
++++ /dev/null
+@@ -1,365 +0,0 @@
+-use std::fmt;
+-use std::str::from_utf8;
+-
+-use recognize::*;
+-
+-use common::{self, numeric_identifier};
+-
+-#[derive(Clone, Debug, PartialEq, Eq)]
+-pub struct Version {
+- pub major: u64,
+- pub minor: u64,
+- pub patch: u64,
+- pub pre: Vec<Identifier>,
+- pub build: Vec<Identifier>,
+-}
+-
+-#[derive(Clone, Debug, PartialEq, Eq)]
+-pub enum Identifier {
+- /// An identifier that's solely numbers.
+- Numeric(u64),
+- /// An identifier with letters and numbers.
+- AlphaNumeric(String),
+-}
+-
+-pub fn parse(version: &str) -> Result<Version, String> {
+- let s = version.trim().as_bytes();
+- let mut i = 0;
+- let major = if let Some((major, len)) = numeric_identifier(&s[i..]) {
+- i += len;
+- major
+- } else {
+- return Err("Error parsing major identifier".to_string());
+- };
+- if let Some(len) = b'.'.p(&s[i..]) {
+- i += len;
+- } else {
+- return Err("Expected dot".to_string());
+- }
+- let minor = if let Some((minor, len)) = numeric_identifier(&s[i..]) {
+- i += len;
+- minor
+- } else {
+- return Err("Error parsing minor identifier".to_string());
+- };
+- if let Some(len) = b'.'.p(&s[i..]) {
+- i += len;
+- } else {
+- return Err("Expected dot".to_string());
+- }
+- let patch = if let Some((patch, len)) = numeric_identifier(&s[i..]) {
+- i += len;
+- patch
+- } else {
+- return Err("Error parsing patch identifier".to_string());
+- };
+- let (pre, pre_len) = common::parse_optional_meta(&s[i..], b'-')?;
+- i += pre_len;
+- let (build, build_len) = common::parse_optional_meta(&s[i..], b'+')?;
+- i += build_len;
+- if i != s.len() {
+- return Err("Extra junk after valid version: ".to_string() +
+- from_utf8(&s[i..]).unwrap());
+- }
+- Ok(Version {
+- major: major,
+- minor: minor,
+- patch: patch,
+- pre: pre,
+- build: build,
+- })
+-}
+-
+-impl fmt::Display for Version {
+- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+- try!(write!(f, "{}.{}.{}", self.major, self.minor, self.patch));
+- if !self.pre.is_empty() {
+- let strs: Vec<_> =
+- self.pre.iter().map(ToString::to_string).collect();
+- try!(write!(f, "-{}", strs.join(".")));
+- }
+- if !self.build.is_empty() {
+- let strs: Vec<_> =
+- self.build.iter().map(ToString::to_string).collect();
+- try!(write!(f, "+{}", strs.join(".")));
+- }
+- Ok(())
+- }
+-}
+-
+-impl fmt::Display for Identifier {
+- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+- match *self {
+- Identifier::Numeric(ref id) => id.fmt(f),
+- Identifier::AlphaNumeric(ref id) => id.fmt(f),
+- }
+- }
+-}
+-
+-#[cfg(test)]
+-mod tests {
+- use version;
+- use super::*;
+-
+- #[test]
+- fn parse_empty() {
+- let version = "";
+-
+- let parsed = version::parse(version);
+-
+- assert!(parsed.is_err(), "empty string incorrectly considered a valid parse");
+- }
+-
+- #[test]
+- fn parse_blank() {
+- let version = " ";
+-
+- let parsed = version::parse(version);
+-
+- assert!(parsed.is_err(), "blank string incorrectly considered a valid parse");
+- }
+-
+- #[test]
+- fn parse_no_minor_patch() {
+- let version = "1";
+-
+- let parsed = version::parse(version);
+-
+- assert!(parsed.is_err(), format!("'{}' incorrectly considered a valid parse", version));
+- }
+-
+- #[test]
+- fn parse_no_patch() {
+- let version = "1.2";
+-
+- let parsed = version::parse(version);
+-
+- assert!(parsed.is_err(), format!("'{}' incorrectly considered a valid parse", version));
+- }
+-
+- #[test]
+- fn parse_empty_pre() {
+- let version = "1.2.3-";
+-
+- let parsed = version::parse(version);
+-
+- assert!(parsed.is_err(), format!("'{}' incorrectly considered a valid parse", version));
+- }
+-
+- #[test]
+- fn parse_letters() {
+- let version = "a.b.c";
+-
+- let parsed = version::parse(version);
+-
+- assert!(parsed.is_err(), format!("'{}' incorrectly considered a valid parse", version));
+- }
+-
+- #[test]
+- fn parse_with_letters() {
+- let version = "1.2.3 a.b.c";
+-
+- let parsed = version::parse(version);
+-
+- assert!(parsed.is_err(), format!("'{}' incorrectly considered a valid parse", version));
+- }
+-
+- #[test]
+- fn parse_basic_version() {
+- let version = "1.2.3";
+-
+- let parsed = version::parse(version).unwrap();
+-
+- assert_eq!(1, parsed.major);
+- assert_eq!(2, parsed.minor);
+- assert_eq!(3, parsed.patch);
+- }
+-
+- #[test]
+- fn parse_trims_input() {
+- let version = " 1.2.3 ";
+-
+- let parsed = version::parse(version).unwrap();
+-
+- assert_eq!(1, parsed.major);
+- assert_eq!(2, parsed.minor);
+- assert_eq!(3, parsed.patch);
+- }
+-
+- #[test]
+- fn parse_no_major_leading_zeroes() {
+- let version = "01.0.0";
+-
+- let parsed = version::parse(version);
+-
+- assert!(parsed.is_err(), "01 incorrectly considered a valid major version");
+- }
+-
+- #[test]
+- fn parse_no_minor_leading_zeroes() {
+- let version = "0.01.0";
+-
+- let parsed = version::parse(version);
+-
+- assert!(parsed.is_err(), "01 incorrectly considered a valid minor version");
+- }
+-
+- #[test]
+- fn parse_no_patch_leading_zeroes() {
+- let version = "0.0.01";
+-
+- let parsed = version::parse(version);
+-
+- assert!(parsed.is_err(), "01 incorrectly considered a valid patch version");
+- }
+-
+- #[test]
+- fn parse_no_major_overflow() {
+- let version = "98765432109876543210.0.0";
+-
+- let parsed = version::parse(version);
+-
+- assert!(parsed.is_err(), "98765432109876543210 incorrectly considered a valid major version");
+- }
+-
+- #[test]
+- fn parse_no_minor_overflow() {
+- let version = "0.98765432109876543210.0";
+-
+- let parsed = version::parse(version);
+-
+- assert!(parsed.is_err(), "98765432109876543210 incorrectly considered a valid minor version");
+- }
+-
+- #[test]
+- fn parse_no_patch_overflow() {
+- let version = "0.0.98765432109876543210";
+-
+- let parsed = version::parse(version);
+-
+- assert!(parsed.is_err(), "98765432109876543210 incorrectly considered a valid patch version");
+- }
+-
+- #[test]
+- fn parse_basic_prerelease() {
+- let version = "1.2.3-pre";
+-
+- let parsed = version::parse(version).unwrap();
+-
+- let expected_pre = vec![Identifier::AlphaNumeric(String::from("pre"))];
+- assert_eq!(expected_pre, parsed.pre);
+- }
+-
+- #[test]
+- fn parse_prerelease_alphanumeric() {
+- let version = "1.2.3-alpha1";
+-
+- let parsed = version::parse(version).unwrap();
+-
+- let expected_pre = vec![Identifier::AlphaNumeric(String::from("alpha1"))];
+- assert_eq!(expected_pre, parsed.pre);
+- }
+-
+- #[test]
+- fn parse_prerelease_zero() {
+- let version = "1.2.3-pre.0";
+-
+- let parsed = version::parse(version).unwrap();
+-
+- let expected_pre = vec![Identifier::AlphaNumeric(String::from("pre")),
+- Identifier::Numeric(0)];
+- assert_eq!(expected_pre, parsed.pre);
+- }
+-
+- #[test]
+- fn parse_basic_build() {
+- let version = "1.2.3+build";
+-
+- let parsed = version::parse(version).unwrap();
+-
+- let expected_build = vec![Identifier::AlphaNumeric(String::from("build"))];
+- assert_eq!(expected_build, parsed.build);
+- }
+-
+- #[test]
+- fn parse_build_alphanumeric() {
+- let version = "1.2.3+build5";
+-
+- let parsed = version::parse(version).unwrap();
+-
+- let expected_build = vec![Identifier::AlphaNumeric(String::from("build5"))];
+- assert_eq!(expected_build, parsed.build);
+- }
+-
+- #[test]
+- fn parse_pre_and_build() {
+- let version = "1.2.3-alpha1+build5";
+-
+- let parsed = version::parse(version).unwrap();
+-
+- let expected_pre = vec![Identifier::AlphaNumeric(String::from("alpha1"))];
+- assert_eq!(expected_pre, parsed.pre);
+-
+- let expected_build = vec![Identifier::AlphaNumeric(String::from("build5"))];
+- assert_eq!(expected_build, parsed.build);
+- }
+-
+- #[test]
+- fn parse_complex_metadata_01() {
+- let version = "1.2.3-1.alpha1.9+build5.7.3aedf ";
+-
+- let parsed = version::parse(version).unwrap();
+-
+- let expected_pre = vec![Identifier::Numeric(1),
+- Identifier::AlphaNumeric(String::from("alpha1")),
+- Identifier::Numeric(9)];
+- assert_eq!(expected_pre, parsed.pre);
+-
+- let expected_build = vec![Identifier::AlphaNumeric(String::from("build5")),
+- Identifier::Numeric(7),
+- Identifier::AlphaNumeric(String::from("3aedf"))];
+- assert_eq!(expected_build, parsed.build);
+- }
+-
+- #[test]
+- fn parse_complex_metadata_02() {
+- let version = "0.4.0-beta.1+0851523";
+-
+- let parsed = version::parse(version).unwrap();
+-
+- let expected_pre = vec![Identifier::AlphaNumeric(String::from("beta")),
+- Identifier::Numeric(1)];
+- assert_eq!(expected_pre, parsed.pre);
+-
+- let expected_build = vec![Identifier::AlphaNumeric(String::from("0851523"))];
+- assert_eq!(expected_build, parsed.build);
+- }
+-
+- #[test]
+- fn parse_metadata_overflow() {
+- let version = "0.4.0-beta.1+98765432109876543210";
+-
+- let parsed = version::parse(version).unwrap();
+-
+- let expected_pre = vec![Identifier::AlphaNumeric(String::from("beta")),
+- Identifier::Numeric(1)];
+- assert_eq!(expected_pre, parsed.pre);
+-
+- let expected_build = vec![Identifier::AlphaNumeric(String::from("98765432109876543210"))];
+- assert_eq!(expected_build, parsed.build);
+- }
+-
+- #[test]
+- fn parse_regression_01() {
+- let version = "0.0.0-WIP";
+-
+- let parsed = version::parse(version).unwrap();
+-
+- assert_eq!(0, parsed.major);
+- assert_eq!(0, parsed.minor);
+- assert_eq!(0, parsed.patch);
+-
+- let expected_pre = vec![Identifier::AlphaNumeric(String::from("WIP"))];
+- assert_eq!(expected_pre, parsed.pre);
+- }
+-}
+diff --git a/third_party/rust/semver/.cargo-checksum.json b/third_party/rust/semver/.cargo-checksum.json
+--- a/third_party/rust/semver/.cargo-checksum.json
++++ b/third_party/rust/semver/.cargo-checksum.json
+@@ -1,1 +1,1 @@
+-{"files":{"Cargo.toml":"a5b995796b5559de8975a6fee7166c9fda6c21b449ec90bef5f9baaeddd479a5","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"c780d8c3c802c5fe2c316127900385010c3e57f71c851eea9e8ed8495e2030dd","src/lib.rs":"cb1725a8bb90c1043f187c6ba504d0a9d07793e2f39f5205f926c58849311770","src/version.rs":"ffdf9c628597b889f149f3b2b1245b97c774eae1ce7030bd19235eabecaaede0","src/version_req.rs":"40d20720f5fdc0b3d9e398e64eb448a65987229bd322cab0fedf0cf1843f3bd8","tests/deprecation.rs":"b5ec79e19d61968d05b96b876c449e54d43cbd1762c6e63c23c3470f9db56292","tests/regression.rs":"180b699ad029b81e6135d42f0a8e6d782177bc29a41132f875ee6f8607a46b56","tests/serde.rs":"cdbbefc576ffcc814c30dad9598ab87a7fd9d14c5f42f1349e1db6afc72f8fed"},"package":"1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"}
+\ No newline at end of file
++{"files":{"Cargo.toml":"2a2126f8fe5d20540ae6cfbf6649ed3af365ffb9a0a788a7552a6e7649a7a75f","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"57659341319915482c0b83779fb7f3f0f3accb7a8b881965799116afb5e9f7e9","benches/parse.rs":"6531f66f80ce2fc83878f9bf84f94c42e96f1e709466f2b88be8d95a3cec1511","build.rs":"47b42941210d44567c8561107420d7825aa1d01332c2d2f8892d9e20646a1c77","src/backport.rs":"f8866548840434c8974f135528693f25aacc4ad03639c4e3aea3be351e13fdf8","src/display.rs":"9ba42f7a6579aa9c7dd72f2380036f5c9664592f3eacd09ea25cef291a3e64e5","src/error.rs":"3bb489f4a29f38d93370e64ae8d6e4e9b451a055cd7d392b6aeacab7eb3e1953","src/eval.rs":"b7e7ec976051b9f87ddf5cfdbaad64654d98d86ae0763f7d88b14eeaeac6013c","src/identifier.rs":"601231351ac58602b7d193cb0951b5146bd868b62aba938d5cbe52cf2b93414b","src/impls.rs":"79b5a2ac6ca3d4cb46adfb1494756079f53bef780dd81c3a8d3adf86f91395c8","src/lib.rs":"8e116a19e521909f3fa50206c078f1e23bf033dc8057ba6101f80d5bc5900fed","src/parse.rs":"93593f62cdae489feb4f2e8ae1fa93d90dca63db50669b6265346ffaaf687be5","src/serde.rs":"970d343a6bac21ddd965168d3cc2af9998796bf29bf545e8b37c6bcdd97d9710","tests/node/mod.rs":"2710d9b8daace2038b66db0f8f4cc522dee938e7cbc42d7739c31995343c32f4","tests/test_autotrait.rs":"070500c32ceee14a8a0110c04a01f98278b24614a0aec8c382dcea3da0343f58","tests/test_identifier.rs":"6c3da46c73df210527b60f1069131b15e2c65eb7b5d11793940d00cf66812f4d","tests/test_version.rs":"09e37c3df162205acf3683d1c760a6001e34e1c709fd4a1a265d82450e340003","tests/test_version_req.rs":"b6eea0258cc3b6d567a9f6c42693a97316345083495236c47e85374fd45f7cf0","tests/util/mod.rs":"db61c2cd86af864d8be4f2a3d5f25c86d7712201cc6ab47b715facf5f7f275b7"},"package":"8cb243bdfdb5936c8dc3c45762a19d12ab4550cdc753bc247637d4ec35a040fd"}
+\ No newline at end of file
+diff --git a/third_party/rust/semver/Cargo.toml b/third_party/rust/semver/Cargo.toml
+--- a/third_party/rust/semver/Cargo.toml
++++ b/third_party/rust/semver/Cargo.toml
+@@ -1,45 +1,38 @@
+ # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+ #
+ # When uploading crates to the registry Cargo will automatically
+ # "normalize" Cargo.toml files for maximal compatibility
+ # with all versions of Cargo and also rewrite `path` dependencies
+-# to registry (e.g. crates.io) dependencies
++# to registry (e.g., crates.io) dependencies.
+ #
+-# If you believe there's an error in this file please file an
+-# issue against the rust-lang/cargo repository. If you're
+-# editing this file be aware that the upstream Cargo.toml
+-# will likely look very different (and much more reasonable)
++# If you are reading this file be aware that the original Cargo.toml
++# will likely look very different (and much more reasonable).
++# See Cargo.toml.orig for the original contents.
+
+ [package]
++edition = "2018"
++rust-version = "1.31"
+ name = "semver"
+-version = "0.9.0"
+-authors = ["Steve Klabnik <steve@steveklabnik.com>", "The Rust Project Developers"]
+-description = "Semantic version parsing and comparison.\n"
+-homepage = "https://docs.rs/crate/semver/"
+-documentation = "https://docs.rs/crate/semver/"
++version = "1.0.9"
++authors = ["David Tolnay <dtolnay@gmail.com>"]
++description = "Parser and evaluator for Cargo's flavor of Semantic Versioning"
++documentation = "https://docs.rs/semver"
+ readme = "README.md"
+-license = "MIT/Apache-2.0"
+-repository = "https://github.com/steveklabnik/semver"
+-[dependencies.semver-parser]
+-version = "0.7.0"
++license = "MIT OR Apache-2.0"
++repository = "https://github.com/dtolnay/semver"
++
++[package.metadata.docs.rs]
++targets = ["x86_64-unknown-linux-gnu"]
++rustdoc-args = [
++ "--cfg",
++ "doc_cfg",
++]
+
+ [dependencies.serde]
+ version = "1.0"
+ optional = true
+-[dev-dependencies.crates-index]
+-version = "0.5.0"
+-
+-[dev-dependencies.serde_json]
+-version = "1.0"
+-
+-[dev-dependencies.serde_derive]
+-version = "1.0"
+-
+-[dev-dependencies.tempdir]
+-version = "0.3.4"
++default-features = false
+
+ [features]
+-default = []
+-ci = ["serde"]
+-[badges.travis-ci]
+-repository = "steveklabnik/semver"
++default = ["std"]
++std = []
+diff --git a/third_party/rust/semver/LICENSE-MIT b/third_party/rust/semver/LICENSE-MIT
+--- a/third_party/rust/semver/LICENSE-MIT
++++ b/third_party/rust/semver/LICENSE-MIT
+@@ -1,10 +1,8 @@
+-Copyright (c) 2014 The Rust Project Developers
+-
+ Permission is hereby granted, free of charge, to any
+ person obtaining a copy of this software and associated
+ documentation files (the "Software"), to deal in the
+ Software without restriction, including without
+ limitation the rights to use, copy, modify, merge,
+ publish, distribute, sublicense, and/or sell copies of
+ the Software, and to permit persons to whom the Software
+ is furnished to do so, subject to the following
+diff --git a/third_party/rust/semver/README.md b/third_party/rust/semver/README.md
+--- a/third_party/rust/semver/README.md
++++ b/third_party/rust/semver/README.md
+@@ -1,103 +1,84 @@
+ semver
+ ======
+
+-Semantic version parsing and comparison.
+-
+-[![Build Status](https://api.travis-ci.org/steveklabnik/semver.svg?branch=master)](https://travis-ci.org/steveklabnik/semver)
+-
+-[Documentation](https://steveklabnik.github.io/semver)
+-
+-Semantic versioning (see http://semver.org/) is a set of rules for
+-assigning version numbers.
++[<img alt="github" src="https://img.shields.io/badge/github-dtolnay/semver-8da0cb?style=for-the-badge&labelColor=555555&logo=github" height="20">](https://github.com/dtolnay/semver)
++[<img alt="crates.io" src="https://img.shields.io/crates/v/semver.svg?style=for-the-badge&color=fc8d62&logo=rust" height="20">](https://crates.io/crates/semver)
++[<img alt="docs.rs" src="https://img.shields.io/badge/docs.rs-semver-66c2a5?style=for-the-badge&labelColor=555555&logoColor=white&logo=data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDUxMiA1MTIiPjxwYXRoIGZpbGw9IiNmNWY1ZjUiIGQ9Ik00ODguNiAyNTAuMkwzOTIgMjE0VjEwNS41YzAtMTUtOS4zLTI4LjQtMjMuNC0zMy43bC0xMDAtMzcuNWMtOC4xLTMuMS0xNy4xLTMuMS0yNS4zIDBsLTEwMCAzNy41Yy0xNC4xIDUuMy0yMy40IDE4LjctMjMuNCAzMy43VjIxNGwtOTYuNiAzNi4yQzkuMyAyNTUuNSAwIDI2OC45IDAgMjgzLjlWMzk0YzAgMTMuNiA3LjcgMjYuMSAxOS45IDMyLjJsMTAwIDUwYzEwLjEgNS4xIDIyLjEgNS4xIDMyLjIgMGwxMDMuOS01MiAxMDMuOSA1MmMxMC4xIDUuMSAyMi4xIDUuMSAzMi4yIDBsMTAwLTUwYzEyLjItNi4xIDE5LjktMTguNiAxOS45LTMyLjJWMjgzLjljMC0xNS05LjMtMjguNC0yMy40LTMzLjd6TTM1OCAyMTQuOGwtODUgMzEuOXYtNjguMmw4NS0zN3Y3My4zek0xNTQgMTA0LjFsMTAyLTM4LjIgMTAyIDM4LjJ2LjZsLTEwMiA0MS40LTEwMi00MS40di0uNnptODQgMjkxLjFsLTg1IDQyLjV2LTc5LjFsODUtMzguOHY3NS40em0wLTExMmwtMTAyIDQxLjQtMTAyLTQxLjR2LS42bDEwMi0zOC4yIDEwMiAzOC4ydi42em0yNDAgMTEybC04NSA0Mi41di03OS4xbDg1LTM4Ljh2NzUuNHptMC0xMTJsLTEwMiA0MS40LTEwMi00MS40di0uNmwxMDItMzguMiAxMDIgMzguMnYuNnoiPjwvcGF0aD48L3N2Zz4K" height="20">](https://docs.rs/semver)
++[<img alt="build status" src="https://img.shields.io/github/workflow/status/dtolnay/semver/CI/master?style=for-the-badge" height="20">](https://github.com/dtolnay/semver/actions?query=branch%3Amaster)
+
+-## SemVer and the Rust ecosystem
+-
+-Rust itself follows the SemVer specification, as does its standard libraries. The two are
+-not tied together.
++A parser and evaluator for Cargo's flavor of Semantic Versioning.
+
+-[Cargo](https://crates.io), Rust's package manager, uses SemVer to determine which versions of
+-packages you need installed.
+-
+-## Installation
+-
+-To use `semver`, add this to your `[dependencies]` section:
++Semantic Versioning (see <https://semver.org>) is a guideline for how version
++numbers are assigned and incremented. It is widely followed within the
++Cargo/crates.io ecosystem for Rust.
+
+ ```toml
+-semver = "0.7.0"
+-```
+-
+-And this to your crate root:
+-
+-```rust
+-extern crate semver;
+-```
+-
+-## Versions
+-
+-At its simplest, the `semver` crate allows you to construct `Version` objects using the `parse`
+-method:
+-
+-```rust
+-use semver::Version;
+-
+-assert!(Version::parse("1.2.3") == Ok(Version {
+- major: 1,
+- minor: 2,
+- patch: 3,
+- pre: vec!(),
+- build: vec!(),
+-}));
++[dependencies]
++semver = "1.0"
+ ```
+
+-If you have multiple `Version`s, you can use the usual comparison operators to compare them:
+-
+-```rust
+-use semver::Version;
++*Compiler support: requires rustc 1.31+*
+
+-assert!(Version::parse("1.2.3-alpha") != Version::parse("1.2.3-beta"));
+-assert!(Version::parse("1.2.3-alpha2") > Version::parse("1.2.0"));
+-```
+-
+-## Requirements
++<br>
+
+-The `semver` crate also provides the ability to compare requirements, which are more complex
+-comparisons.
+-
+-For example, creating a requirement that only matches versions greater than or
+-equal to 1.0.0:
++## Example
+
+ ```rust
+-use semver::Version;
+-use semver::VersionReq;
++use semver::{BuildMetadata, Prerelease, Version, VersionReq};
++
++fn main() {
++ let req = VersionReq::parse(">=1.2.3, <1.8.0").unwrap();
+
+-let r = VersionReq::parse(">= 1.0.0").unwrap();
+-let v = Version::parse("1.0.0").unwrap();
++ // Check whether this requirement matches version 1.2.3-alpha.1 (no)
++ let version = Version {
++ major: 1,
++ minor: 2,
++ patch: 3,
++ pre: Prerelease::new("alpha.1").unwrap(),
++ build: BuildMetadata::EMPTY,
++ };
++ assert!(!req.matches(&version));
+
+-assert!(r.to_string() == ">= 1.0.0".to_string());
+-assert!(r.matches(&v))
++ // Check whether it matches 1.3.0 (yes it does)
++ let version = Version::parse("1.3.0").unwrap();
++ assert!(req.matches(&version));
++}
+ ```
+
+-It also allows parsing of `~x.y.z` and `^x.y.z` requirements as defined at
+-https://www.npmjs.org/doc/misc/semver.html
++<br>
++
++## Scope of this crate
+
+-**Tilde requirements** specify a minimal version with some updates:
++Besides Cargo, several other package ecosystems and package managers for other
++languages also use SemVer:&ensp;RubyGems/Bundler for Ruby, npm for JavaScript,
++Composer for PHP, CocoaPods for Objective-C...
+
+-```notrust
+-~1.2.3 := >=1.2.3 <1.3.0
+-~1.2 := >=1.2.0 <1.3.0
+-~1 := >=1.0.0 <2.0.0
+-```
++The `semver` crate is specifically intended to implement Cargo's interpretation
++of Semantic Versioning.
++
++Where the various tools differ in their interpretation or implementation of the
++spec, this crate follows the implementation choices made by Cargo. If you are
++operating on version numbers from some other package ecosystem, you will want to
++use a different semver library which is appropriate to that ecosystem.
++
++The extent of Cargo's SemVer support is documented in the *[Specifying
++Dependencies]* chapter of the Cargo reference.
+
+-**Caret requirements** allow SemVer compatible updates to a specified version,
+-`0.x` and `0.x+1` are not considered compatible, but `1.x` and `1.x+1` are.
++[Specifying Dependencies]: https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html
+
+-`0.0.x` is not considered compatible with any other version.
+-Missing minor and patch versions are desugared to `0` but allow flexibility for that value.
++<br>
++
++#### License
+
+-```notrust
+-^1.2.3 := >=1.2.3 <2.0.0
+-^0.2.3 := >=0.2.3 <0.3.0
+-^0.0.3 := >=0.0.3 <0.0.4
+-^0.0 := >=0.0.0 <0.1.0
+-^0 := >=0.0.0 <1.0.0
+-```
++<sup>
++Licensed under either of <a href="LICENSE-APACHE">Apache License, Version
++2.0</a> or <a href="LICENSE-MIT">MIT license</a> at your option.
++</sup>
++
++<br>
++
++<sub>
++Unless you explicitly state otherwise, any contribution intentionally submitted
++for inclusion in this crate by you, as defined in the Apache-2.0 license, shall
++be dual licensed as above, without any additional terms or conditions.
++</sub>
+diff --git a/third_party/rust/semver/benches/parse.rs b/third_party/rust/semver/benches/parse.rs
+new file mode 100644
+--- /dev/null
++++ b/third_party/rust/semver/benches/parse.rs
+@@ -0,0 +1,24 @@
++#![feature(test)]
++
++extern crate test;
++
++use semver::{Prerelease, Version, VersionReq};
++use test::{black_box, Bencher};
++
++#[bench]
++fn parse_prerelease(b: &mut Bencher) {
++ let text = "x.7.z.92";
++ b.iter(|| black_box(text).parse::<Prerelease>().unwrap());
++}
++
++#[bench]
++fn parse_version(b: &mut Bencher) {
++ let text = "1.0.2021-beta+exp.sha.5114f85";
++ b.iter(|| black_box(text).parse::<Version>().unwrap());
++}
++
++#[bench]
++fn parse_version_req(b: &mut Bencher) {
++ let text = ">=1.2.3, <2.0.0";
++ b.iter(|| black_box(text).parse::<VersionReq>().unwrap());
++}
+diff --git a/third_party/rust/semver/build.rs b/third_party/rust/semver/build.rs
+new file mode 100644
+--- /dev/null
++++ b/third_party/rust/semver/build.rs
+@@ -0,0 +1,73 @@
++use std::env;
++use std::process::Command;
++use std::str;
++
++fn main() {
++ let compiler = match rustc_minor_version() {
++ Some(compiler) => compiler,
++ None => return,
++ };
++
++ if compiler < 33 {
++ // Exhaustive integer patterns. On older compilers, a final `_` arm is
++ // required even if every possible integer value is otherwise covered.
++ // https://github.com/rust-lang/rust/issues/50907
++ println!("cargo:rustc-cfg=no_exhaustive_int_match");
++ }
++
++ if compiler < 36 {
++ // extern crate alloc.
++ // https://blog.rust-lang.org/2019/07/04/Rust-1.36.0.html#the-alloc-crate-is-stable
++ println!("cargo:rustc-cfg=no_alloc_crate");
++ }
++
++ if compiler < 39 {
++ // const Vec::new.
++ // https://doc.rust-lang.org/std/vec/struct.Vec.html#method.new
++ println!("cargo:rustc-cfg=no_const_vec_new");
++ }
++
++ if compiler < 40 {
++ // #[non_exhaustive].
++ // https://blog.rust-lang.org/2019/12/19/Rust-1.40.0.html#non_exhaustive-structs-enums-and-variants
++ println!("cargo:rustc-cfg=no_non_exhaustive");
++ }
++
++ if compiler < 45 {
++ // String::strip_prefix.
++ // https://doc.rust-lang.org/std/primitive.str.html#method.repeat
++ println!("cargo:rustc-cfg=no_str_strip_prefix");
++ }
++
++ if compiler < 46 {
++ // #[track_caller].
++ // https://blog.rust-lang.org/2020/08/27/Rust-1.46.0.html#track_caller
++ println!("cargo:rustc-cfg=no_track_caller");
++ }
++
++ if compiler < 52 {
++ // #![deny(unsafe_op_in_unsafe_fn)].
++ // https://github.com/rust-lang/rust/issues/71668
++ println!("cargo:rustc-cfg=no_unsafe_op_in_unsafe_fn_lint");
++ }
++
++ if compiler < 53 {
++ // Efficient intrinsics for count-leading-zeros and count-trailing-zeros
++ // on NonZero integers stabilized in 1.53.0. On many architectures these
++ // are more efficient than counting zeros on ordinary zeroable integers.
++ // https://doc.rust-lang.org/std/num/struct.NonZeroU64.html#method.leading_zeros
++ // https://doc.rust-lang.org/std/num/struct.NonZeroU64.html#method.trailing_zeros
++ println!("cargo:rustc-cfg=no_nonzero_bitscan");
++ }
++}
++
++fn rustc_minor_version() -> Option<u32> {
++ let rustc = env::var_os("RUSTC")?;
++ let output = Command::new(rustc).arg("--version").output().ok()?;
++ let version = str::from_utf8(&output.stdout).ok()?;
++ let mut pieces = version.split('.');
++ if pieces.next() != Some("rustc 1") {
++ return None;
++ }
++ pieces.next()?.parse().ok()
++}
+diff --git a/third_party/rust/semver/src/backport.rs b/third_party/rust/semver/src/backport.rs
+new file mode 100644
+--- /dev/null
++++ b/third_party/rust/semver/src/backport.rs
+@@ -0,0 +1,51 @@
++#[cfg(no_str_strip_prefix)] // rustc <1.45
++pub(crate) trait StripPrefixExt {
++ fn strip_prefix(&self, ch: char) -> Option<&str>;
++}
++
++#[cfg(no_str_strip_prefix)]
++impl StripPrefixExt for str {
++ fn strip_prefix(&self, ch: char) -> Option<&str> {
++ if self.starts_with(ch) {
++ Some(&self[ch.len_utf8()..])
++ } else {
++ None
++ }
++ }
++}
++
++pub(crate) use crate::alloc::vec::Vec;
++
++#[cfg(no_alloc_crate)] // rustc <1.36
++pub(crate) mod alloc {
++ pub use std::vec;
++
++ pub mod alloc {
++ use std::mem;
++
++ pub struct Layout {
++ size: usize,
++ }
++
++ impl Layout {
++ pub unsafe fn from_size_align_unchecked(size: usize, align: usize) -> Self {
++ assert_eq!(align, 2);
++ Layout { size }
++ }
++ }
++
++ pub unsafe fn alloc(layout: Layout) -> *mut u8 {
++ let len_u16 = (layout.size + 1) / 2;
++ let mut vec = Vec::new();
++ vec.reserve_exact(len_u16);
++ let ptr: *mut u16 = vec.as_mut_ptr();
++ mem::forget(vec);
++ ptr as *mut u8
++ }
++
++ pub unsafe fn dealloc(ptr: *mut u8, layout: Layout) {
++ let len_u16 = (layout.size + 1) / 2;
++ unsafe { Vec::from_raw_parts(ptr as *mut u16, 0, len_u16) };
++ }
++ }
++}
+diff --git a/third_party/rust/semver/src/display.rs b/third_party/rust/semver/src/display.rs
+new file mode 100644
+--- /dev/null
++++ b/third_party/rust/semver/src/display.rs
+@@ -0,0 +1,165 @@
++use crate::{BuildMetadata, Comparator, Op, Prerelease, Version, VersionReq};
++use core::fmt::{self, Alignment, Debug, Display, Write};
++
++impl Display for Version {
++ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
++ let do_display = |formatter: &mut fmt::Formatter| -> fmt::Result {
++ write!(formatter, "{}.{}.{}", self.major, self.minor, self.patch)?;
++ if !self.pre.is_empty() {
++ write!(formatter, "-{}", self.pre)?;
++ }
++ if !self.build.is_empty() {
++ write!(formatter, "+{}", self.build)?;
++ }
++ Ok(())
++ };
++
++ let do_len = || -> usize {
++ digits(self.major)
++ + 1
++ + digits(self.minor)
++ + 1
++ + digits(self.patch)
++ + !self.pre.is_empty() as usize
++ + self.pre.len()
++ + !self.build.is_empty() as usize
++ + self.build.len()
++ };
++
++ pad(formatter, do_display, do_len)
++ }
++}
++
++impl Display for VersionReq {
++ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
++ if self.comparators.is_empty() {
++ return formatter.write_str("*");
++ }
++ for (i, comparator) in self.comparators.iter().enumerate() {
++ if i > 0 {
++ formatter.write_str(", ")?;
++ }
++ write!(formatter, "{}", comparator)?;
++ }
++ Ok(())
++ }
++}
++
++impl Display for Comparator {
++ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
++ let op = match self.op {
++ Op::Exact => "=",
++ Op::Greater => ">",
++ Op::GreaterEq => ">=",
++ Op::Less => "<",
++ Op::LessEq => "<=",
++ Op::Tilde => "~",
++ Op::Caret => "^",
++ Op::Wildcard => "",
++ #[cfg(no_non_exhaustive)]
++ Op::__NonExhaustive => unreachable!(),
++ };
++ formatter.write_str(op)?;
++ write!(formatter, "{}", self.major)?;
++ if let Some(minor) = &self.minor {
++ write!(formatter, ".{}", minor)?;
++ if let Some(patch) = &self.patch {
++ write!(formatter, ".{}", patch)?;
++ if !self.pre.is_empty() {
++ write!(formatter, "-{}", self.pre)?;
++ }
++ } else if self.op == Op::Wildcard {
++ formatter.write_str(".*")?;
++ }
++ } else if self.op == Op::Wildcard {
++ formatter.write_str(".*")?;
++ }
++ Ok(())
++ }
++}
++
++impl Display for Prerelease {
++ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
++ formatter.write_str(self.as_str())
++ }
++}
++
++impl Display for BuildMetadata {
++ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
++ formatter.write_str(self.as_str())
++ }
++}
++
++impl Debug for Version {
++ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
++ let mut debug = formatter.debug_struct("Version");
++ debug
++ .field("major", &self.major)
++ .field("minor", &self.minor)
++ .field("patch", &self.patch);
++ if !self.pre.is_empty() {
++ debug.field("pre", &self.pre);
++ }
++ if !self.build.is_empty() {
++ debug.field("build", &self.build);
++ }
++ debug.finish()
++ }
++}
++
++impl Debug for Prerelease {
++ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
++ write!(formatter, "Prerelease(\"{}\")", self)
++ }
++}
++
++impl Debug for BuildMetadata {
++ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
++ write!(formatter, "BuildMetadata(\"{}\")", self)
++ }
++}
++
++fn pad(
++ formatter: &mut fmt::Formatter,
++ do_display: impl FnOnce(&mut fmt::Formatter) -> fmt::Result,
++ do_len: impl FnOnce() -> usize,
++) -> fmt::Result {
++ let min_width = match formatter.width() {
++ Some(min_width) => min_width,
++ None => return do_display(formatter),
++ };
++
++ let len = do_len();
++ if len >= min_width {
++ return do_display(formatter);
++ }
++
++ let default_align = Alignment::Left;
++ let align = formatter.align().unwrap_or(default_align);
++ let padding = min_width - len;
++ let (pre_pad, post_pad) = match align {
++ Alignment::Left => (0, padding),
++ Alignment::Right => (padding, 0),
++ Alignment::Center => (padding / 2, (padding + 1) / 2),
++ };
++
++ let fill = formatter.fill();
++ for _ in 0..pre_pad {
++ formatter.write_char(fill)?;
++ }
++
++ do_display(formatter)?;
++
++ for _ in 0..post_pad {
++ formatter.write_char(fill)?;
++ }
++ Ok(())
++}
++
++fn digits(val: u64) -> usize {
++ if val < 10 {
++ 1
++ } else {
++ 1 + digits(val / 10)
++ }
++}
+diff --git a/third_party/rust/semver/src/error.rs b/third_party/rust/semver/src/error.rs
+new file mode 100644
+--- /dev/null
++++ b/third_party/rust/semver/src/error.rs
+@@ -0,0 +1,124 @@
++use crate::parse::Error;
++use core::fmt::{self, Debug, Display};
++
++pub(crate) enum ErrorKind {
++ UnexpectedEnd(Position),
++ UnexpectedChar(Position, char),
++ UnexpectedCharAfter(Position, char),
++ ExpectedCommaFound(Position, char),
++ LeadingZero(Position),
++ Overflow(Position),
++ EmptySegment(Position),
++ IllegalCharacter(Position),
++ WildcardNotTheOnlyComparator(char),
++ UnexpectedAfterWildcard,
++ ExcessiveComparators,
++}
++
++#[derive(Copy, Clone, Eq, PartialEq)]
++pub(crate) enum Position {
++ Major,
++ Minor,
++ Patch,
++ Pre,
++ Build,
++}
++
++#[cfg(feature = "std")]
++#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
++impl std::error::Error for Error {}
++
++impl Display for Error {
++ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
++ match &self.kind {
++ ErrorKind::UnexpectedEnd(pos) => {
++ write!(formatter, "unexpected end of input while parsing {}", pos)
++ }
++ ErrorKind::UnexpectedChar(pos, ch) => {
++ write!(
++ formatter,
++ "unexpected character {} while parsing {}",
++ QuotedChar(*ch),
++ pos,
++ )
++ }
++ ErrorKind::UnexpectedCharAfter(pos, ch) => {
++ write!(
++ formatter,
++ "unexpected character {} after {}",
++ QuotedChar(*ch),
++ pos,
++ )
++ }
++ ErrorKind::ExpectedCommaFound(pos, ch) => {
++ write!(
++ formatter,
++ "expected comma after {}, found {}",
++ pos,
++ QuotedChar(*ch),
++ )
++ }
++ ErrorKind::LeadingZero(pos) => {
++ write!(formatter, "invalid leading zero in {}", pos)
++ }
++ ErrorKind::Overflow(pos) => {
++ write!(formatter, "value of {} exceeds u64::MAX", pos)
++ }
++ ErrorKind::EmptySegment(pos) => {
++ write!(formatter, "empty identifier segment in {}", pos)
++ }
++ ErrorKind::IllegalCharacter(pos) => {
++ write!(formatter, "unexpected character in {}", pos)
++ }
++ ErrorKind::WildcardNotTheOnlyComparator(ch) => {
++ write!(
++ formatter,
++ "wildcard req ({}) must be the only comparator in the version req",
++ ch,
++ )
++ }
++ ErrorKind::UnexpectedAfterWildcard => {
++ formatter.write_str("unexpected character after wildcard in version req")
++ }
++ ErrorKind::ExcessiveComparators => {
++ formatter.write_str("excessive number of version comparators")
++ }
++ }
++ }
++}
++
++impl Display for Position {
++ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
++ formatter.write_str(match self {
++ Position::Major => "major version number",
++ Position::Minor => "minor version number",
++ Position::Patch => "patch version number",
++ Position::Pre => "pre-release identifier",
++ Position::Build => "build metadata",
++ })
++ }
++}
++
++impl Debug for Error {
++ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
++ formatter.write_str("Error(\"")?;
++ Display::fmt(self, formatter)?;
++ formatter.write_str("\")")?;
++ Ok(())
++ }
++}
++
++struct QuotedChar(char);
++
++impl Display for QuotedChar {
++ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
++ // Standard library versions prior to https://github.com/rust-lang/rust/pull/95345
++ // print character 0 as '\u{0}'. We prefer '\0' to keep error messages
++ // the same across all supported Rust versions.
++ if self.0 == '\0' {
++ formatter.write_str("'\\0'")
++ } else {
++ write!(formatter, "{:?}", self.0)
++ }
++ }
++}
+diff --git a/third_party/rust/semver/src/eval.rs b/third_party/rust/semver/src/eval.rs
+new file mode 100644
+--- /dev/null
++++ b/third_party/rust/semver/src/eval.rs
+@@ -0,0 +1,181 @@
++use crate::{Comparator, Op, Version, VersionReq};
++
++pub(crate) fn matches_req(req: &VersionReq, ver: &Version) -> bool {
++ for cmp in &req.comparators {
++ if !matches_impl(cmp, ver) {
++ return false;
++ }
++ }
++
++ if ver.pre.is_empty() {
++ return true;
++ }
++
++ // If a version has a prerelease tag (for example, 1.2.3-alpha.3) then it
++ // will only be allowed to satisfy req if at least one comparator with the
++ // same major.minor.patch also has a prerelease tag.
++ for cmp in &req.comparators {
++ if pre_is_compatible(cmp, ver) {
++ return true;
++ }
++ }
++
++ false
++}
++
++pub(crate) fn matches_comparator(cmp: &Comparator, ver: &Version) -> bool {
++ matches_impl(cmp, ver) && (ver.pre.is_empty() || pre_is_compatible(cmp, ver))
++}
++
++fn matches_impl(cmp: &Comparator, ver: &Version) -> bool {
++ match cmp.op {
++ Op::Exact | Op::Wildcard => matches_exact(cmp, ver),
++ Op::Greater => matches_greater(cmp, ver),
++ Op::GreaterEq => matches_exact(cmp, ver) || matches_greater(cmp, ver),
++ Op::Less => matches_less(cmp, ver),
++ Op::LessEq => matches_exact(cmp, ver) || matches_less(cmp, ver),
++ Op::Tilde => matches_tilde(cmp, ver),
++ Op::Caret => matches_caret(cmp, ver),
++ #[cfg(no_non_exhaustive)]
++ Op::__NonExhaustive => unreachable!(),
++ }
++}
++
++fn matches_exact(cmp: &Comparator, ver: &Version) -> bool {
++ if ver.major != cmp.major {
++ return false;
++ }
++
++ if let Some(minor) = cmp.minor {
++ if ver.minor != minor {
++ return false;
++ }
++ }
++
++ if let Some(patch) = cmp.patch {
++ if ver.patch != patch {
++ return false;
++ }
++ }
++
++ ver.pre == cmp.pre
++}
++
++fn matches_greater(cmp: &Comparator, ver: &Version) -> bool {
++ if ver.major != cmp.major {
++ return ver.major > cmp.major;
++ }
++
++ match cmp.minor {
++ None => return false,
++ Some(minor) => {
++ if ver.minor != minor {
++ return ver.minor > minor;
++ }
++ }
++ }
++
++ match cmp.patch {
++ None => return false,
++ Some(patch) => {
++ if ver.patch != patch {
++ return ver.patch > patch;
++ }
++ }
++ }
++
++ ver.pre > cmp.pre
++}
++
++fn matches_less(cmp: &Comparator, ver: &Version) -> bool {
++ if ver.major != cmp.major {
++ return ver.major < cmp.major;
++ }
++
++ match cmp.minor {
++ None => return false,
++ Some(minor) => {
++ if ver.minor != minor {
++ return ver.minor < minor;
++ }
++ }
++ }
++
++ match cmp.patch {
++ None => return false,
++ Some(patch) => {
++ if ver.patch != patch {
++ return ver.patch < patch;
++ }
++ }
++ }
++
++ ver.pre < cmp.pre
++}
++
++fn matches_tilde(cmp: &Comparator, ver: &Version) -> bool {
++ if ver.major != cmp.major {
++ return false;
++ }
++
++ if let Some(minor) = cmp.minor {
++ if ver.minor != minor {
++ return false;
++ }
++ }
++
++ if let Some(patch) = cmp.patch {
++ if ver.patch != patch {
++ return ver.patch > patch;
++ }
++ }
++
++ ver.pre >= cmp.pre
++}
++
++fn matches_caret(cmp: &Comparator, ver: &Version) -> bool {
++ if ver.major != cmp.major {
++ return false;
++ }
++
++ let minor = match cmp.minor {
++ None => return true,
++ Some(minor) => minor,
++ };
++
++ let patch = match cmp.patch {
++ None => {
++ if cmp.major > 0 {
++ return ver.minor >= minor;
++ } else {
++ return ver.minor == minor;
++ }
++ }
++ Some(patch) => patch,
++ };
++
++ if cmp.major > 0 {
++ if ver.minor != minor {
++ return ver.minor > minor;
++ } else if ver.patch != patch {
++ return ver.patch > patch;
++ }
++ } else if minor > 0 {
++ if ver.minor != minor {
++ return false;
++ } else if ver.patch != patch {
++ return ver.patch > patch;
++ }
++ } else if ver.minor != minor || ver.patch != patch {
++ return false;
++ }
++
++ ver.pre >= cmp.pre
++}
++
++fn pre_is_compatible(cmp: &Comparator, ver: &Version) -> bool {
++ cmp.major == ver.major
++ && cmp.minor == Some(ver.minor)
++ && cmp.patch == Some(ver.patch)
++ && !cmp.pre.is_empty()
++}
+diff --git a/third_party/rust/semver/src/identifier.rs b/third_party/rust/semver/src/identifier.rs
+new file mode 100644
+--- /dev/null
++++ b/third_party/rust/semver/src/identifier.rs
+@@ -0,0 +1,400 @@
++// This module implements Identifier, a short-optimized string allowed to
++// contain only the ASCII characters hyphen, dot, 0-9, A-Z, a-z.
++//
++// As of mid-2021, the distribution of pre-release lengths on crates.io is:
++//
++// length count length count length count
++// 0 355929 11 81 24 2
++// 1 208 12 48 25 6
++// 2 236 13 55 26 10
++// 3 1909 14 25 27 4
++// 4 1284 15 15 28 1
++// 5 1742 16 35 30 1
++// 6 3440 17 9 31 5
++// 7 5624 18 6 32 1
++// 8 1321 19 12 36 2
++// 9 179 20 2 37 379
++// 10 65 23 11
++//
++// and the distribution of build metadata lengths is:
++//
++// length count length count length count
++// 0 364445 8 7725 18 1
++// 1 72 9 16 19 1
++// 2 7 10 85 20 1
++// 3 28 11 17 22 4
++// 4 9 12 10 26 1
++// 5 68 13 9 27 1
++// 6 73 14 10 40 5
++// 7 53 15 6
++//
++// Therefore it really behooves us to be able to use the entire 8 bytes of a
++// pointer for inline storage. For both pre-release and build metadata there are
++// vastly more strings with length exactly 8 bytes than the sum over all lengths
++// longer than 8 bytes.
++//
++// To differentiate the inline representation from the heap allocated long
++// representation, we'll allocate heap pointers with 2-byte alignment so that
++// they are guaranteed to have an unset least significant bit. Then in the repr
++// we store for pointers, we rotate a 1 into the most significant bit of the
++// most significant byte, which is never set for an ASCII byte.
++//
++// Inline repr:
++//
++// 0xxxxxxx 0xxxxxxx 0xxxxxxx 0xxxxxxx 0xxxxxxx 0xxxxxxx 0xxxxxxx 0xxxxxxx
++//
++// Heap allocated repr:
++//
++// 1ppppppp pppppppp pppppppp pppppppp pppppppp pppppppp pppppppp pppppppp 0
++// ^ most significant bit least significant bit of orig ptr, rotated out ^
++//
++// Since the most significant bit doubles as a sign bit for the similarly sized
++// signed integer type, the CPU has an efficient instruction for inspecting it,
++// meaning we can differentiate between an inline repr and a heap allocated repr
++// in one instruction. Effectively an inline repr always looks like a positive
++// i64 while a heap allocated repr always looks like a negative i64.
++//
++// For the inline repr, we store \0 padding on the end of the stored characters,
++// and thus the string length is readily determined efficiently by a cttz (count
++// trailing zeros) or bsf (bit scan forward) instruction.
++//
++// For the heap allocated repr, the length is encoded as a base-128 varint at
++// the head of the allocation.
++//
++// Empty strings are stored as an all-1 bit pattern, corresponding to -1i64.
++// Consequently the all-0 bit pattern is never a legal representation in any
++// repr, leaving it available as a niche for downstream code. For example this
++// allows size_of::<Version>() == size_of::<Option<Version>>().
++
++use crate::alloc::alloc::{alloc, dealloc, Layout};
++use core::mem;
++use core::num::{NonZeroU64, NonZeroUsize};
++use core::ptr::{self, NonNull};
++use core::slice;
++use core::str;
++
++const PTR_BYTES: usize = mem::size_of::<NonNull<u8>>();
++
++// If pointers are already 8 bytes or bigger, then 0. If pointers are smaller
++// than 8 bytes, then Identifier will contain a byte array to raise its size up
++// to 8 bytes total.
++const TAIL_BYTES: usize = 8 * (PTR_BYTES < 8) as usize - PTR_BYTES * (PTR_BYTES < 8) as usize;
++
++#[repr(C, align(8))]
++pub(crate) struct Identifier {
++ head: NonNull<u8>,
++ tail: [u8; TAIL_BYTES],
++}
++
++impl Identifier {
++ pub(crate) const fn empty() -> Self {
++ // This is a separate constant because unsafe function calls are not
++ // allowed in a const fn body, only in a const, until later rustc than
++ // what we support.
++ const HEAD: NonNull<u8> = unsafe { NonNull::new_unchecked(!0 as *mut u8) };
++
++ // `mov rax, -1`
++ Identifier {
++ head: HEAD,
++ tail: [!0; TAIL_BYTES],
++ }
++ }
++
++ // SAFETY: string must be ASCII and not contain \0 bytes.
++ pub(crate) unsafe fn new_unchecked(string: &str) -> Self {
++ let len = string.len();
++ match len as u64 {
++ 0 => Self::empty(),
++ 1..=8 => {
++ let mut bytes = [0u8; mem::size_of::<Identifier>()];
++ // SAFETY: string is big enough to read len bytes, bytes is big
++ // enough to write len bytes, and they do not overlap.
++ unsafe { ptr::copy_nonoverlapping(string.as_ptr(), bytes.as_mut_ptr(), len) };
++ // SAFETY: the head field is nonzero because the input string
++ // was at least 1 byte of ASCII and did not contain \0.
++ unsafe { mem::transmute::<[u8; mem::size_of::<Identifier>()], Identifier>(bytes) }
++ }
++ 9..=0xff_ffff_ffff_ffff => {
++ // SAFETY: len is in a range that does not contain 0.
++ let size = bytes_for_varint(unsafe { NonZeroUsize::new_unchecked(len) }) + len;
++ let align = 2;
++ // SAFETY: align is not zero, align is a power of two, and
++ // rounding size up to align does not overflow usize::MAX.
++ let layout = unsafe { Layout::from_size_align_unchecked(size, align) };
++ // SAFETY: layout's size is nonzero.
++ let ptr = unsafe { alloc(layout) };
++ let mut write = ptr;
++ let mut varint_remaining = len;
++ while varint_remaining > 0 {
++ // SAFETY: size is bytes_for_varint(len) bytes + len bytes.
++ // This is writing the first bytes_for_varint(len) bytes.
++ unsafe { ptr::write(write, varint_remaining as u8 | 0x80) };
++ varint_remaining >>= 7;
++ // SAFETY: still in bounds of the same allocation.
++ write = unsafe { write.add(1) };
++ }
++ // SAFETY: size is bytes_for_varint(len) bytes + len bytes. This
++ // is writing to the last len bytes.
++ unsafe { ptr::copy_nonoverlapping(string.as_ptr(), write, len) };
++ Identifier {
++ head: ptr_to_repr(ptr),
++ tail: [0; TAIL_BYTES],
++ }
++ }
++ 0x100_0000_0000_0000..=0xffff_ffff_ffff_ffff => {
++ unreachable!("please refrain from storing >64 petabytes of text in semver version");
++ }
++ #[cfg(no_exhaustive_int_match)] // rustc <1.33
++ _ => unreachable!(),
++ }
++ }
++
++ pub(crate) fn is_empty(&self) -> bool {
++ // `cmp rdi, -1` -- basically: `repr as i64 == -1`
++ let empty = Self::empty();
++ let is_empty = self.head == empty.head && self.tail == empty.tail;
++ // The empty representation does nothing on Drop. We can't let this one
++ // drop normally because `impl Drop for Identifier` calls is_empty; that
++ // would be an infinite recursion.
++ mem::forget(empty);
++ is_empty
++ }
++
++ fn is_inline(&self) -> bool {
++ // `test rdi, rdi` -- basically: `repr as i64 >= 0`
++ self.head.as_ptr() as usize >> (PTR_BYTES * 8 - 1) == 0
++ }
++
++ fn is_empty_or_inline(&self) -> bool {
++ // `cmp rdi, -2` -- basically: `repr as i64 > -2`
++ self.is_empty() || self.is_inline()
++ }
++
++ pub(crate) fn as_str(&self) -> &str {
++ if self.is_empty() {
++ ""
++ } else if self.is_inline() {
++ // SAFETY: repr is in the inline representation.
++ unsafe { inline_as_str(self) }
++ } else {
++ // SAFETY: repr is in the heap allocated representation.
++ unsafe { ptr_as_str(&self.head) }
++ }
++ }
++}
++
++impl Clone for Identifier {
++ fn clone(&self) -> Self {
++ if self.is_empty_or_inline() {
++ Identifier {
++ head: self.head,
++ tail: self.tail,
++ }
++ } else {
++ let ptr = repr_to_ptr(self.head);
++ // SAFETY: ptr is one of our own heap allocations.
++ let len = unsafe { decode_len(ptr) };
++ let size = bytes_for_varint(len) + len.get();
++ let align = 2;
++ // SAFETY: align is not zero, align is a power of two, and rounding
++ // size up to align does not overflow usize::MAX. This is just
++ // duplicating a previous allocation where all of these guarantees
++ // were already made.
++ let layout = unsafe { Layout::from_size_align_unchecked(size, align) };
++ // SAFETY: layout's size is nonzero.
++ let clone = unsafe { alloc(layout) };
++ // SAFETY: new allocation cannot overlap the previous one (this was
++ // not a realloc). The argument ptrs are readable/writeable
++ // respectively for size bytes.
++ unsafe { ptr::copy_nonoverlapping(ptr, clone, size) }
++ Identifier {
++ head: ptr_to_repr(clone),
++ tail: [0; TAIL_BYTES],
++ }
++ }
++ }
++}
++
++impl Drop for Identifier {
++ fn drop(&mut self) {
++ if self.is_empty_or_inline() {
++ return;
++ }
++ let ptr = repr_to_ptr_mut(self.head);
++ // SAFETY: ptr is one of our own heap allocations.
++ let len = unsafe { decode_len(ptr) };
++ let size = bytes_for_varint(len) + len.get();
++ let align = 2;
++ // SAFETY: align is not zero, align is a power of two, and rounding
++ // size up to align does not overflow usize::MAX. These guarantees were
++ // made when originally allocating this memory.
++ let layout = unsafe { Layout::from_size_align_unchecked(size, align) };
++ // SAFETY: ptr was previously allocated by the same allocator with the
++ // same layout.
++ unsafe { dealloc(ptr, layout) }
++ }
++}
++
++impl PartialEq for Identifier {
++ fn eq(&self, rhs: &Self) -> bool {
++ if self.is_empty_or_inline() {
++ // Fast path (most common)
++ self.head == rhs.head && self.tail == rhs.tail
++ } else if rhs.is_empty_or_inline() {
++ false
++ } else {
++ // SAFETY: both reprs are in the heap allocated representation.
++ unsafe { ptr_as_str(&self.head) == ptr_as_str(&rhs.head) }
++ }
++ }
++}
++
++unsafe impl Send for Identifier {}
++unsafe impl Sync for Identifier {}
++
++// We use heap pointers that are 2-byte aligned, meaning they have an
++// insignificant 0 in the least significant bit. We take advantage of that
++// unneeded bit to rotate a 1 into the most significant bit to make the repr
++// distinguishable from ASCII bytes.
++fn ptr_to_repr(original: *mut u8) -> NonNull<u8> {
++ // `mov eax, 1`
++ // `shld rax, rdi, 63`
++ let modified = (original as usize | 1).rotate_right(1);
++
++ // `original + (modified - original)`, but being mindful of provenance.
++ let diff = modified.wrapping_sub(original as usize);
++ let modified = original.wrapping_add(diff);
++
++ // SAFETY: the most significant bit of repr is known to be set, so the value
++ // is not zero.
++ unsafe { NonNull::new_unchecked(modified) }
++}
++
++// Shift out the 1 previously placed into the most significant bit of the least
++// significant byte. Shift in a low 0 bit to reconstruct the original 2-byte
++// aligned pointer.
++fn repr_to_ptr(modified: NonNull<u8>) -> *const u8 {
++ // `lea rax, [rdi + rdi]`
++ let modified = modified.as_ptr();
++ let original = (modified as usize) << 1;
++
++ // `modified + (original - modified)`, but being mindful of provenance.
++ let diff = original.wrapping_sub(modified as usize);
++ modified.wrapping_add(diff)
++}
++
++fn repr_to_ptr_mut(repr: NonNull<u8>) -> *mut u8 {
++ repr_to_ptr(repr) as *mut u8
++}
++
++// Compute the length of the inline string, assuming the argument is in short
++// string representation. Short strings are stored as 1 to 8 nonzero ASCII
++// bytes, followed by \0 padding for the remaining bytes.
++//
++// SAFETY: the identifier must indeed be in the inline representation.
++unsafe fn inline_len(repr: &Identifier) -> NonZeroUsize {
++ // SAFETY: Identifier's layout is align(8) and at least size 8. We're doing
++ // an aligned read of the first 8 bytes from it. The bytes are not all zero
++ // because inline strings are at least 1 byte long and cannot contain \0.
++ let repr = unsafe { ptr::read(repr as *const Identifier as *const NonZeroU64) };
++
++ // Rustc >=1.53 has intrinsics for counting zeros on a non-zeroable integer.
++ // On many architectures these are more efficient than counting on ordinary
++ // zeroable integers (bsf vs cttz). On rustc <1.53 without those intrinsics,
++ // we count zeros in the u64 rather than the NonZeroU64.
++ #[cfg(no_nonzero_bitscan)]
++ let repr = repr.get();
++
++ #[cfg(target_endian = "little")]
++ let zero_bits_on_string_end = repr.leading_zeros();
++ #[cfg(target_endian = "big")]
++ let zero_bits_on_string_end = repr.trailing_zeros();
++
++ let nonzero_bytes = 8 - zero_bits_on_string_end as usize / 8;
++
++ // SAFETY: repr is nonzero, so it has at most 63 zero bits on either end,
++ // thus at least one nonzero byte.
++ unsafe { NonZeroUsize::new_unchecked(nonzero_bytes) }
++}
++
++// SAFETY: repr must be in the inline representation, i.e. at least 1 and at
++// most 8 nonzero ASCII bytes padded on the end with \0 bytes.
++unsafe fn inline_as_str(repr: &Identifier) -> &str {
++ let ptr = repr as *const Identifier as *const u8;
++ let len = unsafe { inline_len(repr) }.get();
++ // SAFETY: we are viewing the nonzero ASCII prefix of the inline repr's
++ // contents as a slice of bytes. Input/output lifetimes are correctly
++ // associated.
++ let slice = unsafe { slice::from_raw_parts(ptr, len) };
++ // SAFETY: the string contents are known to be only ASCII bytes, which are
++ // always valid UTF-8.
++ unsafe { str::from_utf8_unchecked(slice) }
++}
++
++// Decode varint. Varints consist of between one and eight base-128 digits, each
++// of which is stored in a byte with most significant bit set. Adjacent to the
++// varint in memory there is guaranteed to be at least 9 ASCII bytes, each of
++// which has an unset most significant bit.
++//
++// SAFETY: ptr must be one of our own heap allocations, with the varint header
++// already written.
++unsafe fn decode_len(ptr: *const u8) -> NonZeroUsize {
++ // SAFETY: There is at least one byte of varint followed by at least 9 bytes
++ // of string content, which is at least 10 bytes total for the allocation,
++ // so reading the first two is no problem.
++ let [first, second] = unsafe { ptr::read(ptr as *const [u8; 2]) };
++ if second < 0x80 {
++ // SAFETY: the length of this heap allocated string has been encoded as
++ // one base-128 digit, so the length is at least 9 and at most 127. It
++ // cannot be zero.
++ unsafe { NonZeroUsize::new_unchecked((first & 0x7f) as usize) }
++ } else {
++ return unsafe { decode_len_cold(ptr) };
++
++ // Identifiers 128 bytes or longer. This is not exercised by any crate
++ // version currently published to crates.io.
++ #[cold]
++ #[inline(never)]
++ unsafe fn decode_len_cold(mut ptr: *const u8) -> NonZeroUsize {
++ let mut len = 0;
++ let mut shift = 0;
++ loop {
++ // SAFETY: varint continues while there are bytes having the
++ // most significant bit set, i.e. until we start hitting the
++ // ASCII string content with msb unset.
++ let byte = unsafe { *ptr };
++ if byte < 0x80 {
++ // SAFETY: the string length is known to be 128 bytes or
++ // longer.
++ return unsafe { NonZeroUsize::new_unchecked(len) };
++ }
++ // SAFETY: still in bounds of the same allocation.
++ ptr = unsafe { ptr.add(1) };
++ len += ((byte & 0x7f) as usize) << shift;
++ shift += 7;
++ }
++ }
++ }
++}
++
++// SAFETY: repr must be in the heap allocated representation, with varint header
++// and string contents already written.
++unsafe fn ptr_as_str(repr: &NonNull<u8>) -> &str {
++ let ptr = repr_to_ptr(*repr);
++ let len = unsafe { decode_len(ptr) };
++ let header = bytes_for_varint(len);
++ let slice = unsafe { slice::from_raw_parts(ptr.add(header), len.get()) };
++ // SAFETY: all identifier contents are ASCII bytes, which are always valid
++ // UTF-8.
++ unsafe { str::from_utf8_unchecked(slice) }
++}
++
++// Number of base-128 digits required for the varint representation of a length.
++fn bytes_for_varint(len: NonZeroUsize) -> usize {
++ #[cfg(no_nonzero_bitscan)] // rustc <1.53
++ let len = len.get();
++
++ let usize_bits = mem::size_of::<usize>() * 8;
++ let len_bits = usize_bits - len.leading_zeros() as usize;
++ (len_bits + 6) / 7
++}
+diff --git a/third_party/rust/semver/src/impls.rs b/third_party/rust/semver/src/impls.rs
+new file mode 100644
+--- /dev/null
++++ b/third_party/rust/semver/src/impls.rs
+@@ -0,0 +1,156 @@
++use crate::backport::*;
++use crate::identifier::Identifier;
++use crate::{BuildMetadata, Comparator, Prerelease, VersionReq};
++use core::cmp::Ordering;
++use core::hash::{Hash, Hasher};
++use core::iter::FromIterator;
++use core::ops::Deref;
++
++impl Default for Identifier {
++ fn default() -> Self {
++ Identifier::empty()
++ }
++}
++
++impl Eq for Identifier {}
++
++impl Hash for Identifier {
++ fn hash<H: Hasher>(&self, hasher: &mut H) {
++ self.as_str().hash(hasher);
++ }
++}
++
++impl Deref for Prerelease {
++ type Target = str;
++
++ fn deref(&self) -> &Self::Target {
++ self.identifier.as_str()
++ }
++}
++
++impl Deref for BuildMetadata {
++ type Target = str;
++
++ fn deref(&self) -> &Self::Target {
++ self.identifier.as_str()
++ }
++}
++
++impl PartialOrd for Prerelease {
++ fn partial_cmp(&self, rhs: &Self) -> Option<Ordering> {
++ Some(Ord::cmp(self, rhs))
++ }
++}
++
++impl PartialOrd for BuildMetadata {
++ fn partial_cmp(&self, rhs: &Self) -> Option<Ordering> {
++ Some(Ord::cmp(self, rhs))
++ }
++}
++
++impl Ord for Prerelease {
++ fn cmp(&self, rhs: &Self) -> Ordering {
++ match self.is_empty() {
++ true if rhs.is_empty() => return Ordering::Equal,
++ // A real release compares greater than prerelease.
++ true => return Ordering::Greater,
++ // Prerelease compares less than the real release.
++ false if rhs.is_empty() => return Ordering::Less,
++ false => {}
++ }
++
++ let lhs = self.as_str().split('.');
++ let mut rhs = rhs.as_str().split('.');
++
++ for lhs in lhs {
++ let rhs = match rhs.next() {
++ // Spec: "A larger set of pre-release fields has a higher
++ // precedence than a smaller set, if all of the preceding
++ // identifiers are equal."
++ None => return Ordering::Greater,
++ Some(rhs) => rhs,
++ };
++
++ let string_cmp = || Ord::cmp(lhs, rhs);
++ let is_ascii_digit = |b: u8| b.is_ascii_digit();
++ let ordering = match (
++ lhs.bytes().all(is_ascii_digit),
++ rhs.bytes().all(is_ascii_digit),
++ ) {
++ // Respect numeric ordering, for example 99 < 100. Spec says:
++ // "Identifiers consisting of only digits are compared
++ // numerically."
++ (true, true) => Ord::cmp(&lhs.len(), &rhs.len()).then_with(string_cmp),
++ // Spec: "Numeric identifiers always have lower precedence than
++ // non-numeric identifiers."
++ (true, false) => return Ordering::Less,
++ (false, true) => return Ordering::Greater,
++ // Spec: "Identifiers with letters or hyphens are compared
++ // lexically in ASCII sort order."
++ (false, false) => string_cmp(),
++ };
++
++ if ordering != Ordering::Equal {
++ return ordering;
++ }
++ }
++
++ if rhs.next().is_none() {
++ Ordering::Equal
++ } else {
++ Ordering::Less
++ }
++ }
++}
++
++impl Ord for BuildMetadata {
++ fn cmp(&self, rhs: &Self) -> Ordering {
++ let lhs = self.as_str().split('.');
++ let mut rhs = rhs.as_str().split('.');
++
++ for lhs in lhs {
++ let rhs = match rhs.next() {
++ None => return Ordering::Greater,
++ Some(rhs) => rhs,
++ };
++
++ let is_ascii_digit = |b: u8| b.is_ascii_digit();
++ let ordering = match (
++ lhs.bytes().all(is_ascii_digit),
++ rhs.bytes().all(is_ascii_digit),
++ ) {
++ (true, true) => {
++ // 0 < 00 < 1 < 01 < 001 < 2 < 02 < 002 < 10
++ let lhval = lhs.trim_start_matches('0');
++ let rhval = rhs.trim_start_matches('0');
++ Ord::cmp(&lhval.len(), &rhval.len())
++ .then_with(|| Ord::cmp(lhval, rhval))
++ .then_with(|| Ord::cmp(&lhs.len(), &rhs.len()))
++ }
++ (true, false) => return Ordering::Less,
++ (false, true) => return Ordering::Greater,
++ (false, false) => Ord::cmp(lhs, rhs),
++ };
++
++ if ordering != Ordering::Equal {
++ return ordering;
++ }
++ }
++
++ if rhs.next().is_none() {
++ Ordering::Equal
++ } else {
++ Ordering::Less
++ }
++ }
++}
++
++impl FromIterator<Comparator> for VersionReq {
++ fn from_iter<I>(iter: I) -> Self
++ where
++ I: IntoIterator<Item = Comparator>,
++ {
++ let comparators = Vec::from_iter(iter);
++ VersionReq { comparators }
++ }
++}
+diff --git a/third_party/rust/semver/src/lib.rs b/third_party/rust/semver/src/lib.rs
+--- a/third_party/rust/semver/src/lib.rs
++++ b/third_party/rust/semver/src/lib.rs
+@@ -1,182 +1,533 @@
+-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
+-// file at the top-level directory of this distribution and at
+-// http://rust-lang.org/COPYRIGHT.
+-//
+-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+-// option. This file may not be copied, modified, or distributed
+-// except according to those terms.
+-
+-//! Semantic version parsing and comparison.
++//! [![github]](https://github.com/dtolnay/semver)&ensp;[![crates-io]](https://crates.io/crates/semver)&ensp;[![docs-rs]](https://docs.rs/semver)
+ //!
+-//! Semantic versioning (see http://semver.org/) is a set of rules for
+-//! assigning version numbers.
++//! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github
++//! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust
++//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logoColor=white&logo=data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDUxMiA1MTIiPjxwYXRoIGZpbGw9IiNmNWY1ZjUiIGQ9Ik00ODguNiAyNTAuMkwzOTIgMjE0VjEwNS41YzAtMTUtOS4zLTI4LjQtMjMuNC0zMy43bC0xMDAtMzcuNWMtOC4xLTMuMS0xNy4xLTMuMS0yNS4zIDBsLTEwMCAzNy41Yy0xNC4xIDUuMy0yMy40IDE4LjctMjMuNCAzMy43VjIxNGwtOTYuNiAzNi4yQzkuMyAyNTUuNSAwIDI2OC45IDAgMjgzLjlWMzk0YzAgMTMuNiA3LjcgMjYuMSAxOS45IDMyLjJsMTAwIDUwYzEwLjEgNS4xIDIyLjEgNS4xIDMyLjIgMGwxMDMuOS01MiAxMDMuOSA1MmMxMC4xIDUuMSAyMi4xIDUuMSAzMi4yIDBsMTAwLTUwYzEyLjItNi4xIDE5LjktMTguNiAxOS45LTMyLjJWMjgzLjljMC0xNS05LjMtMjguNC0yMy40LTMzLjd6TTM1OCAyMTQuOGwtODUgMzEuOXYtNjguMmw4NS0zN3Y3My4zek0xNTQgMTA0LjFsMTAyLTM4LjIgMTAyIDM4LjJ2LjZsLTEwMiA0MS40LTEwMi00MS40di0uNnptODQgMjkxLjFsLTg1IDQyLjV2LTc5LjFsODUtMzguOHY3NS40em0wLTExMmwtMTAyIDQxLjQtMTAyLTQxLjR2LS42bDEwMi0zOC4yIDEwMiAzOC4ydi42em0yNDAgMTEybC04NSA0Mi41di03OS4xbDg1LTM4Ljh2NzUuNHptMC0xMTJsLTEwMiA0MS40LTEwMi00MS40di0uNmwxMDItMzguMiAxMDIgMzguMnYuNnoiPjwvcGF0aD48L3N2Zz4K
+ //!
+-//! ## SemVer overview
+-//!
+-//! Given a version number MAJOR.MINOR.PATCH, increment the:
++//! <br>
+ //!
+-//! 1. MAJOR version when you make incompatible API changes,
+-//! 2. MINOR version when you add functionality in a backwards-compatible
+-//! manner, and
+-//! 3. PATCH version when you make backwards-compatible bug fixes.
+-//!
+-//! Additional labels for pre-release and build metadata are available as
+-//! extensions to the MAJOR.MINOR.PATCH format.
+-//!
+-//! Any references to 'the spec' in this documentation refer to [version 2.0 of
+-//! the SemVer spec](http://semver.org/spec/v2.0.0.html).
++//! A parser and evaluator for Cargo's flavor of Semantic Versioning.
+ //!
+-//! ## SemVer and the Rust ecosystem
+-//!
+-//! Rust itself follows the SemVer specification, as does its standard
+-//! libraries. The two are not tied together.
++//! Semantic Versioning (see <https://semver.org>) is a guideline for how
++//! version numbers are assigned and incremented. It is widely followed within
++//! the Cargo/crates.io ecosystem for Rust.
+ //!
+-//! [Cargo](http://crates.io), Rust's package manager, uses SemVer to determine
+-//! which versions of packages you need installed.
++//! <br>
+ //!
+-//! ## Versions
+-//!
+-//! At its simplest, the `semver` crate allows you to construct `Version`
+-//! objects using the `parse` method:
++//! # Example
+ //!
+-//! ```{rust}
+-//! use semver::Version;
++//! ```
++//! use semver::{BuildMetadata, Prerelease, Version, VersionReq};
+ //!
+-//! assert!(Version::parse("1.2.3") == Ok(Version {
+-//! major: 1,
+-//! minor: 2,
+-//! patch: 3,
+-//! pre: vec!(),
+-//! build: vec!(),
+-//! }));
+-//! ```
+-//!
+-//! If you have multiple `Version`s, you can use the usual comparison operators
+-//! to compare them:
+-//!
+-//! ```{rust}
+-//! use semver::Version;
+-//!
+-//! assert!(Version::parse("1.2.3-alpha") != Version::parse("1.2.3-beta"));
+-//! assert!(Version::parse("1.2.3-alpha2") > Version::parse("1.2.0"));
+-//! ```
++//! fn main() {
++//! let req = VersionReq::parse(">=1.2.3, <1.8.0").unwrap();
+ //!
+-//! If you explicitly need to modify a Version, SemVer also allows you to
+-//! increment the major, minor, and patch numbers in accordance with the spec.
+-//!
+-//! Please note that in order to do this, you must use a mutable Version:
+-//!
+-//! ```{rust}
+-//! use semver::Version;
+-//!
+-//! let mut bugfix_release = Version::parse("1.0.0").unwrap();
+-//! bugfix_release.increment_patch();
++//! // Check whether this requirement matches version 1.2.3-alpha.1 (no)
++//! let version = Version {
++//! major: 1,
++//! minor: 2,
++//! patch: 3,
++//! pre: Prerelease::new("alpha.1").unwrap(),
++//! build: BuildMetadata::EMPTY,
++//! };
++//! assert!(!req.matches(&version));
+ //!
+-//! assert_eq!(Ok(bugfix_release), Version::parse("1.0.1"));
+-//! ```
+-//!
+-//! When incrementing the minor version number, the patch number resets to zero
+-//! (in accordance with section 7 of the spec)
+-//!
+-//! ```{rust}
+-//! use semver::Version;
+-//!
+-//! let mut feature_release = Version::parse("1.4.6").unwrap();
+-//! feature_release.increment_minor();
+-//!
+-//! assert_eq!(Ok(feature_release), Version::parse("1.5.0"));
++//! // Check whether it matches 1.3.0 (yes it does)
++//! let version = Version::parse("1.3.0").unwrap();
++//! assert!(req.matches(&version));
++//! }
+ //! ```
+ //!
+-//! Similarly, when incrementing the major version number, the patch and minor
+-//! numbers reset to zero (in accordance with section 8 of the spec)
++//! <br><br>
+ //!
+-//! ```{rust}
+-//! use semver::Version;
+-//!
+-//! let mut chrome_release = Version::parse("41.5.5377").unwrap();
+-//! chrome_release.increment_major();
++//! # Scope of this crate
+ //!
+-//! assert_eq!(Ok(chrome_release), Version::parse("42.0.0"));
+-//! ```
+-//!
+-//! ## Requirements
+-//!
+-//! The `semver` crate also provides the ability to compare requirements, which
+-//! are more complex comparisons.
+-//!
+-//! For example, creating a requirement that only matches versions greater than
+-//! or equal to 1.0.0:
++//! Besides Cargo, several other package ecosystems and package managers for
++//! other languages also use SemVer:&ensp;RubyGems/Bundler for Ruby, npm for
++//! JavaScript, Composer for PHP, CocoaPods for Objective-C...
+ //!
+-//! ```{rust}
+-//! # #![allow(unstable)]
+-//! use semver::Version;
+-//! use semver::VersionReq;
+-//!
+-//! let r = VersionReq::parse(">= 1.0.0").unwrap();
+-//! let v = Version::parse("1.0.0").unwrap();
++//! The `semver` crate is specifically intended to implement Cargo's
++//! interpretation of Semantic Versioning.
+ //!
+-//! assert!(r.to_string() == ">= 1.0.0".to_string());
+-//! assert!(r.matches(&v))
+-//! ```
+-//!
+-//! It also allows parsing of `~x.y.z` and `^x.y.z` requirements as defined at
+-//! https://www.npmjs.org/doc/misc/semver.html
++//! Where the various tools differ in their interpretation or implementation of
++//! the spec, this crate follows the implementation choices made by Cargo. If
++//! you are operating on version numbers from some other package ecosystem, you
++//! will want to use a different semver library which is appropriate to that
++//! ecosystem.
+ //!
+-//! **Tilde requirements** specify a minimal version with some updates:
+-//!
+-//! ```notrust
+-//! ~1.2.3 := >=1.2.3 <1.3.0
+-//! ~1.2 := >=1.2.0 <1.3.0
+-//! ~1 := >=1.0.0 <2.0.0
+-//! ```
++//! The extent of Cargo's SemVer support is documented in the *[Specifying
++//! Dependencies]* chapter of the Cargo reference.
+ //!
+-//! **Caret requirements** allow SemVer compatible updates to a specified
+-//! verion, `0.x` and `0.x+1` are not considered compatible, but `1.x` and
+-//! `1.x+1` are.
+-//!
+-//! `0.0.x` is not considered compatible with any other version.
+-//! Missing minor and patch versions are desugared to `0` but allow flexibility
+-//! for that value.
+-//!
+-//! ```notrust
+-//! ^1.2.3 := >=1.2.3 <2.0.0
+-//! ^0.2.3 := >=0.2.3 <0.3.0
+-//! ^0.0.3 := >=0.0.3 <0.0.4
+-//! ^0.0 := >=0.0.0 <0.1.0
+-//! ^0 := >=0.0.0 <1.0.0
+-//! ```
+-//!
+-//! **Wildcard requirements** allows parsing of version requirements of the
+-//! formats `*`, `x.*` and `x.y.*`.
+-//!
+-//! ```notrust
+-//! * := >=0.0.0
+-//! 1.* := >=1.0.0 <2.0.0
+-//! 1.2.* := >=1.2.0 <1.3.0
+-//! ```
++//! [Specifying Dependencies]: https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html
++
++#![doc(html_root_url = "https://docs.rs/semver/1.0.9")]
++#![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))]
++#![cfg_attr(no_unsafe_op_in_unsafe_fn_lint, allow(unused_unsafe))]
++#![cfg_attr(no_str_strip_prefix, allow(unstable_name_collisions))]
++#![allow(
++ clippy::cast_lossless,
++ clippy::cast_possible_truncation,
++ clippy::doc_markdown,
++ clippy::items_after_statements,
++ clippy::manual_map,
++ clippy::match_bool,
++ 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
++ clippy::similar_names,
++ clippy::unnested_or_patterns,
++ clippy::unseparated_literal_suffix,
++ clippy::wildcard_imports
++)]
++
++#[cfg(not(no_alloc_crate))]
++extern crate alloc;
++
++mod backport;
++mod display;
++mod error;
++mod eval;
++mod identifier;
++mod impls;
++mod parse;
++
++#[cfg(feature = "serde")]
++mod serde;
++
++use crate::alloc::vec::Vec;
++use crate::identifier::Identifier;
++use core::str::FromStr;
++
++#[allow(unused_imports)]
++use crate::backport::*;
++
++pub use crate::parse::Error;
++
++/// **SemVer version** as defined by <https://semver.org>.
++///
++/// # Syntax
++///
++/// - The major, minor, and patch numbers may be any integer 0 through u64::MAX.
++/// When representing a SemVer version as a string, each number is written as
++/// a base 10 integer. For example, `1.0.119`.
++///
++/// - Leading zeros are forbidden in those positions. For example `1.01.00` is
++/// invalid as a SemVer version.
++///
++/// - The pre-release identifier, if present, must conform to the syntax
++/// documented for [`Prerelease`].
++///
++/// - The build metadata, if present, must conform to the syntax documented for
++/// [`BuildMetadata`].
++///
++/// - Whitespace is not allowed anywhere in the version.
++///
++/// # Total ordering
++///
++/// Given any two SemVer versions, one is less than, greater than, or equal to
++/// the other. Versions may be compared against one another using Rust's usual
++/// comparison operators.
++///
++/// - The major, minor, and patch number are compared numerically from left to
++/// right, lexicographically ordered as a 3-tuple of integers. So for example
++/// version `1.5.0` is less than version `1.19.0`, despite the fact that
++/// "1.19.0" &lt; "1.5.0" as ASCIIbetically compared strings and 1.19 &lt; 1.5
++/// as real numbers.
++///
++/// - When major, minor, and patch are equal, a pre-release version is
++/// considered less than the ordinary release:&ensp;version `1.0.0-alpha.1` is
++/// less than version `1.0.0`.
++///
++/// - Two pre-releases of the same major, minor, patch are compared by
++/// lexicographic ordering of dot-separated components of the pre-release
++/// string.
++///
++/// - Identifiers consisting of only digits are compared
++/// numerically:&ensp;`1.0.0-pre.8` is less than `1.0.0-pre.12`.
++///
++/// - Identifiers that contain a letter or hyphen are compared in ASCII sort
++/// order:&ensp;`1.0.0-pre12` is less than `1.0.0-pre8`.
++///
++/// - Any numeric identifier is always less than any non-numeric
++/// identifier:&ensp;`1.0.0-pre.1` is less than `1.0.0-pre.x`.
++///
++/// Example:&ensp;`1.0.0-alpha`&ensp;&lt;&ensp;`1.0.0-alpha.1`&ensp;&lt;&ensp;`1.0.0-alpha.beta`&ensp;&lt;&ensp;`1.0.0-beta`&ensp;&lt;&ensp;`1.0.0-beta.2`&ensp;&lt;&ensp;`1.0.0-beta.11`&ensp;&lt;&ensp;`1.0.0-rc.1`&ensp;&lt;&ensp;`1.0.0`
++#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
++pub struct Version {
++ pub major: u64,
++ pub minor: u64,
++ pub patch: u64,
++ pub pre: Prerelease,
++ pub build: BuildMetadata,
++}
++
++/// **SemVer version requirement** describing the intersection of some version
++/// comparators, such as `>=1.2.3, <1.8`.
++///
++/// # Syntax
++///
++/// - Either `*` (meaning "any"), or one or more comma-separated comparators.
++///
++/// - A [`Comparator`] is an operator ([`Op`]) and a partial version, separated
++/// by optional whitespace. For example `>=1.0.0` or `>=1.0`.
++///
++/// - Build metadata is syntactically permitted on the partial versions, but is
++/// completely ignored, as it's never relevant to whether any comparator
++/// matches a particular version.
++///
++/// - Whitespace is permitted around commas and around operators. Whitespace is
++/// not permitted within a partial version, i.e. anywhere between the major
++/// version number and its minor, patch, pre-release, or build metadata.
++#[derive(Clone, Eq, PartialEq, Hash, Debug)]
++#[cfg_attr(no_const_vec_new, derive(Default))]
++pub struct VersionReq {
++ pub comparators: Vec<Comparator>,
++}
++
++/// A pair of comparison operator and partial version, such as `>=1.2`. Forms
++/// one piece of a VersionReq.
++#[derive(Clone, Eq, PartialEq, Hash, Debug)]
++pub struct Comparator {
++ pub op: Op,
++ pub major: u64,
++ pub minor: Option<u64>,
++ /// Patch is only allowed if minor is Some.
++ pub patch: Option<u64>,
++ /// Non-empty pre-release is only allowed if patch is Some.
++ pub pre: Prerelease,
++}
++
++/// SemVer comparison operator: `=`, `>`, `>=`, `<`, `<=`, `~`, `^`, `*`.
++///
++/// # Op::Exact
++/// - &ensp;**`=I.J.K`**&emsp;&mdash;&emsp;exactly the version I.J.K
++/// - &ensp;**`=I.J`**&emsp;&mdash;&emsp;equivalent to `>=I.J.0, <I.(J+1).0`
++/// - &ensp;**`=I`**&emsp;&mdash;&emsp;equivalent to `>=I.0.0, <(I+1).0.0`
++///
++/// # Op::Greater
++/// - &ensp;**`>I.J.K`**
++/// - &ensp;**`>I.J`**&emsp;&mdash;&emsp;equivalent to `>=I.(J+1).0`
++/// - &ensp;**`>I`**&emsp;&mdash;&emsp;equivalent to `>=(I+1).0.0`
++///
++/// # Op::GreaterEq
++/// - &ensp;**`>=I.J.K`**
++/// - &ensp;**`>=I.J`**&emsp;&mdash;&emsp;equivalent to `>=I.J.0`
++/// - &ensp;**`>=I`**&emsp;&mdash;&emsp;equivalent to `>=I.0.0`
++///
++/// # Op::Less
++/// - &ensp;**`<I.J.K`**
++/// - &ensp;**`<I.J`**&emsp;&mdash;&emsp;equivalent to `<I.J.0`
++/// - &ensp;**`<I`**&emsp;&mdash;&emsp;equivalent to `<I.0.0`
++///
++/// # Op::LessEq
++/// - &ensp;**`<=I.J.K`**
++/// - &ensp;**`<=I.J`**&emsp;&mdash;&emsp;equivalent to `<I.(J+1).0`
++/// - &ensp;**`<=I`**&emsp;&mdash;&emsp;equivalent to `<(I+1).0.0`
++///
++/// # Op::Tilde&emsp;("patch" updates)
++/// *Tilde requirements allow the **patch** part of the semver version (the third number) to increase.*
++/// - &ensp;**`~I.J.K`**&emsp;&mdash;&emsp;equivalent to `>=I.J.K, <I.(J+1).0`
++/// - &ensp;**`~I.J`**&emsp;&mdash;&emsp;equivalent to `=I.J`
++/// - &ensp;**`~I`**&emsp;&mdash;&emsp;equivalent to `=I`
++///
++/// # Op::Caret&emsp;("compatible" updates)
++/// *Caret requirements allow parts that are **right of the first nonzero** part of the semver version to increase.*
++/// - &ensp;**`^I.J.K`**&ensp;(for I\>0)&emsp;&mdash;&emsp;equivalent to `>=I.J.K, <(I+1).0.0`
++/// - &ensp;**`^0.J.K`**&ensp;(for J\>0)&emsp;&mdash;&emsp;equivalent to `>=0.J.K, <0.(J+1).0`
++/// - &ensp;**`^0.0.K`**&emsp;&mdash;&emsp;equivalent to `=0.0.K`
++/// - &ensp;**`^I.J`**&ensp;(for I\>0 or J\>0)&emsp;&mdash;&emsp;equivalent to `^I.J.0`
++/// - &ensp;**`^0.0`**&emsp;&mdash;&emsp;equivalent to `=0.0`
++/// - &ensp;**`^I`**&emsp;&mdash;&emsp;equivalent to `=I`
++///
++/// # Op::Wildcard
++/// - &ensp;**`I.J.*`**&emsp;&mdash;&emsp;equivalent to `=I.J`
++/// - &ensp;**`I.*`**&ensp;or&ensp;**`I.*.*`**&emsp;&mdash;&emsp;equivalent to `=I`
++#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
++#[cfg_attr(not(no_non_exhaustive), non_exhaustive)]
++pub enum Op {
++ Exact,
++ Greater,
++ GreaterEq,
++ Less,
++ LessEq,
++ Tilde,
++ Caret,
++ Wildcard,
++
++ #[cfg(no_non_exhaustive)] // rustc <1.40
++ #[doc(hidden)]
++ __NonExhaustive,
++}
+
+-#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
+- html_favicon_url = "https://www.rust-lang.org/favicon.ico")]
+-#![deny(missing_docs)]
+-#![cfg_attr(test, deny(warnings))]
++/// Optional pre-release identifier on a version string. This comes after `-` in
++/// a SemVer version, like `1.0.0-alpha.1`
++///
++/// # Examples
++///
++/// Some real world pre-release idioms drawn from crates.io:
++///
++/// - **[mio]** <code>0.7.0-<b>alpha.1</b></code> &mdash; the most common style
++/// for numbering pre-releases.
++///
++/// - **[pest]** <code>1.0.0-<b>beta.8</b></code>,&ensp;<code>1.0.0-<b>rc.0</b></code>
++/// &mdash; this crate makes a distinction between betas and release
++/// candidates.
++///
++/// - **[sassers]** <code>0.11.0-<b>shitshow</b></code> &mdash; ???.
++///
++/// - **[atomic-utils]** <code>0.0.0-<b>reserved</b></code> &mdash; a squatted
++/// crate name.
++///
++/// [mio]: https://crates.io/crates/mio
++/// [pest]: https://crates.io/crates/pest
++/// [atomic-utils]: https://crates.io/crates/atomic-utils
++/// [sassers]: https://crates.io/crates/sassers
++///
++/// *Tip:* Be aware that if you are planning to number your own pre-releases,
++/// you should prefer to separate the numeric part from any non-numeric
++/// identifiers by using a dot in between. That is, prefer pre-releases
++/// `alpha.1`, `alpha.2`, etc rather than `alpha1`, `alpha2` etc. The SemVer
++/// spec's rule for pre-release precedence has special treatment of numeric
++/// components in the pre-release string, but only if there are no non-digit
++/// characters in the same dot-separated component. So you'd have `alpha.2` &lt;
++/// `alpha.11` as intended, but `alpha11` &lt; `alpha2`.
++///
++/// # Syntax
++///
++/// Pre-release strings are a series of dot separated identifiers immediately
++/// following the patch version. Identifiers must comprise only ASCII
++/// alphanumerics and hyphens: `0-9`, `A-Z`, `a-z`, `-`. Identifiers must not be
++/// empty. Numeric identifiers must not include leading zeros.
++///
++/// # Total ordering
++///
++/// Pre-releases have a total order defined by the SemVer spec. It uses
++/// lexicographic ordering of dot-separated components. Identifiers consisting
++/// of only digits are compared numerically. Otherwise, identifiers are compared
++/// in ASCII sort order. Any numeric identifier is always less than any
++/// non-numeric identifier.
++///
++/// Example:&ensp;`alpha`&ensp;&lt;&ensp;`alpha.85`&ensp;&lt;&ensp;`alpha.90`&ensp;&lt;&ensp;`alpha.200`&ensp;&lt;&ensp;`alpha.0a`&ensp;&lt;&ensp;`alpha.1a0`&ensp;&lt;&ensp;`alpha.a`&ensp;&lt;&ensp;`beta`
++#[derive(Default, Clone, Eq, PartialEq, Hash)]
++pub struct Prerelease {
++ identifier: Identifier,
++}
+
+-extern crate semver_parser;
+-
+-// Serialization and deserialization support for version numbers
+-#[cfg(feature = "serde")]
+-extern crate serde;
++/// Optional build metadata identifier. This comes after `+` in a SemVer
++/// version, as in `0.8.1+zstd.1.5.0`.
++///
++/// # Examples
++///
++/// Some real world build metadata idioms drawn from crates.io:
++///
++/// - **[libgit2-sys]** <code>0.12.20+<b>1.1.0</b></code> &mdash; for this
++/// crate, the build metadata indicates the version of the C libgit2 library
++/// that the Rust crate is built against.
++///
++/// - **[mashup]** <code>0.1.13+<b>deprecated</b></code> &mdash; just the word
++/// "deprecated" for a crate that has been superseded by another. Eventually
++/// people will take notice of this in Cargo's build output where it lists the
++/// crates being compiled.
++///
++/// - **[google-bigquery2]** <code>2.0.4+<b>20210327</b></code> &mdash; this
++/// library is automatically generated from an official API schema, and the
++/// build metadata indicates the date on which that schema was last captured.
++///
++/// - **[fbthrift-git]** <code>0.0.6+<b>c7fcc0e</b></code> &mdash; this crate is
++/// published from snapshots of a big company monorepo. In monorepo
++/// development, there is no concept of versions, and all downstream code is
++/// just updated atomically in the same commit that breaking changes to a
++/// library are landed. Therefore for crates.io purposes, every published
++/// version must be assumed to be incompatible with the previous. The build
++/// metadata provides the source control hash of the snapshotted code.
++///
++/// [libgit2-sys]: https://crates.io/crates/libgit2-sys
++/// [mashup]: https://crates.io/crates/mashup
++/// [google-bigquery2]: https://crates.io/crates/google-bigquery2
++/// [fbthrift-git]: https://crates.io/crates/fbthrift-git
++///
++/// # Syntax
++///
++/// Build metadata is a series of dot separated identifiers immediately
++/// following the patch or pre-release version. Identifiers must comprise only
++/// ASCII alphanumerics and hyphens: `0-9`, `A-Z`, `a-z`, `-`. Identifiers must
++/// not be empty. Leading zeros *are* allowed, unlike any other place in the
++/// SemVer grammar.
++///
++/// # Total ordering
++///
++/// Build metadata is ignored in evaluating `VersionReq`; it plays no role in
++/// whether a `Version` matches any one of the comparison operators.
++///
++/// However for comparing build metadatas among one another, they do have a
++/// total order which is determined by lexicographic ordering of dot-separated
++/// components. Identifiers consisting of only digits are compared numerically.
++/// Otherwise, identifiers are compared in ASCII sort order. Any numeric
++/// identifier is always less than any non-numeric identifier.
++///
++/// Example:&ensp;`demo`&ensp;&lt;&ensp;`demo.85`&ensp;&lt;&ensp;`demo.90`&ensp;&lt;&ensp;`demo.090`&ensp;&lt;&ensp;`demo.200`&ensp;&lt;&ensp;`demo.1a0`&ensp;&lt;&ensp;`demo.a`&ensp;&lt;&ensp;`memo`
++#[derive(Default, Clone, Eq, PartialEq, Hash)]
++pub struct BuildMetadata {
++ identifier: Identifier,
++}
+
+-// We take the common approach of keeping our own module system private, and
+-// just re-exporting the interface that we want.
++impl Version {
++ /// Create `Version` with an empty pre-release and build metadata.
++ ///
++ /// Equivalent to:
++ ///
++ /// ```
++ /// # use semver::{BuildMetadata, Prerelease, Version};
++ /// #
++ /// # const fn new(major: u64, minor: u64, patch: u64) -> Version {
++ /// Version {
++ /// major,
++ /// minor,
++ /// patch,
++ /// pre: Prerelease::EMPTY,
++ /// build: BuildMetadata::EMPTY,
++ /// }
++ /// # }
++ /// ```
++ pub const fn new(major: u64, minor: u64, patch: u64) -> Self {
++ Version {
++ major,
++ minor,
++ patch,
++ pre: Prerelease::EMPTY,
++ build: BuildMetadata::EMPTY,
++ }
++ }
++
++ /// Create `Version` by parsing from string representation.
++ ///
++ /// # Errors
++ ///
++ /// Possible reasons for the parse to fail include:
++ ///
++ /// - `1.0` &mdash; too few numeric components. A SemVer version must have
++ /// exactly three. If you are looking at something that has fewer than
++ /// three numbers in it, it's possible it is a `VersionReq` instead (with
++ /// an implicit default `^` comparison operator).
++ ///
++ /// - `1.0.01` &mdash; a numeric component has a leading zero.
++ ///
++ /// - `1.0.unknown` &mdash; unexpected character in one of the components.
++ ///
++ /// - `1.0.0-` or `1.0.0+` &mdash; the pre-release or build metadata are
++ /// indicated present but empty.
++ ///
++ /// - `1.0.0-alpha_123` &mdash; pre-release or build metadata have something
++ /// outside the allowed characters, which are `0-9`, `A-Z`, `a-z`, `-`,
++ /// and `.` (dot).
++ ///
++ /// - `23456789999999999999.0.0` &mdash; overflow of a u64.
++ pub fn parse(text: &str) -> Result<Self, Error> {
++ Version::from_str(text)
++ }
++}
++
++impl VersionReq {
++ /// A `VersionReq` with no constraint on the version numbers it matches.
++ /// Equivalent to `VersionReq::parse("*").unwrap()`.
++ ///
++ /// In terms of comparators this is equivalent to `>=0.0.0`.
++ ///
++ /// Counterintuitively a `*` VersionReq does not match every possible
++ /// version number. In particular, in order for *any* `VersionReq` to match
++ /// a pre-release version, the `VersionReq` must contain at least one
++ /// `Comparator` that has an explicit major, minor, and patch version
++ /// identical to the pre-release being matched, and that has a nonempty
++ /// pre-release component. Since `*` is not written with an explicit major,
++ /// minor, and patch version, and does not contain a nonempty pre-release
++ /// component, it does not match any pre-release versions.
++ #[cfg(not(no_const_vec_new))] // rustc <1.39
++ pub const STAR: Self = VersionReq {
++ comparators: Vec::new(),
++ };
+
+-pub use version::{Version, Identifier, SemVerError};
+-pub use version::Identifier::{Numeric, AlphaNumeric};
+-pub use version_req::{VersionReq, ReqParseError};
++ /// Create `VersionReq` by parsing from string representation.
++ ///
++ /// # Errors
++ ///
++ /// Possible reasons for the parse to fail include:
++ ///
++ /// - `>a.b` &mdash; unexpected characters in the partial version.
++ ///
++ /// - `@1.0.0` &mdash; unrecognized comparison operator.
++ ///
++ /// - `^1.0.0, ` &mdash; unexpected end of input.
++ ///
++ /// - `>=1.0 <2.0` &mdash; missing comma between comparators.
++ ///
++ /// - `*.*` &mdash; unsupported wildcard syntax.
++ pub fn parse(text: &str) -> Result<Self, Error> {
++ VersionReq::from_str(text)
++ }
++
++ /// Evaluate whether the given `Version` satisfies the version requirement
++ /// described by `self`.
++ pub fn matches(&self, version: &Version) -> bool {
++ eval::matches_req(self, version)
++ }
++}
++
++/// The default VersionReq is the same as [`VersionReq::STAR`].
++#[cfg(not(no_const_vec_new))]
++impl Default for VersionReq {
++ fn default() -> Self {
++ VersionReq::STAR
++ }
++}
++
++impl Comparator {
++ pub fn parse(text: &str) -> Result<Self, Error> {
++ Comparator::from_str(text)
++ }
+
+-// SemVer-compliant versions.
+-mod version;
++ pub fn matches(&self, version: &Version) -> bool {
++ eval::matches_comparator(self, version)
++ }
++}
++
++impl Prerelease {
++ pub const EMPTY: Self = Prerelease {
++ identifier: Identifier::empty(),
++ };
++
++ pub fn new(text: &str) -> Result<Self, Error> {
++ Prerelease::from_str(text)
++ }
++
++ pub fn as_str(&self) -> &str {
++ self.identifier.as_str()
++ }
+
+-// advanced version comparisons
+-mod version_req;
++ pub fn is_empty(&self) -> bool {
++ self.identifier.is_empty()
++ }
++}
++
++impl BuildMetadata {
++ pub const EMPTY: Self = BuildMetadata {
++ identifier: Identifier::empty(),
++ };
++
++ pub fn new(text: &str) -> Result<Self, Error> {
++ BuildMetadata::from_str(text)
++ }
++
++ pub fn as_str(&self) -> &str {
++ self.identifier.as_str()
++ }
++
++ pub fn is_empty(&self) -> bool {
++ self.identifier.is_empty()
++ }
++}
+diff --git a/third_party/rust/semver/src/parse.rs b/third_party/rust/semver/src/parse.rs
+new file mode 100644
+--- /dev/null
++++ b/third_party/rust/semver/src/parse.rs
+@@ -0,0 +1,405 @@
++use crate::backport::*;
++use crate::error::{ErrorKind, Position};
++use crate::identifier::Identifier;
++use crate::{BuildMetadata, Comparator, Op, Prerelease, Version, VersionReq};
++use core::str::FromStr;
++
++/// Error parsing a SemVer version or version requirement.
++///
++/// # Example
++///
++/// ```
++/// use semver::Version;
++///
++/// fn main() {
++/// let err = Version::parse("1.q.r").unwrap_err();
++///
++/// // "unexpected character 'q' while parsing minor version number"
++/// eprintln!("{}", err);
++/// }
++/// ```
++pub struct Error {
++ pub(crate) kind: ErrorKind,
++}
++
++impl FromStr for Version {
++ type Err = Error;
++
++ fn from_str(text: &str) -> Result<Self, Self::Err> {
++ let mut pos = Position::Major;
++ let (major, text) = numeric_identifier(text, pos)?;
++ let text = dot(text, pos)?;
++
++ pos = Position::Minor;
++ let (minor, text) = numeric_identifier(text, pos)?;
++ let text = dot(text, pos)?;
++
++ pos = Position::Patch;
++ let (patch, text) = numeric_identifier(text, pos)?;
++
++ if text.is_empty() {
++ return Ok(Version::new(major, minor, patch));
++ }
++
++ let (pre, text) = if let Some(text) = text.strip_prefix('-') {
++ pos = Position::Pre;
++ let (pre, text) = prerelease_identifier(text)?;
++ if pre.is_empty() {
++ return Err(Error::new(ErrorKind::EmptySegment(pos)));
++ }
++ (pre, text)
++ } else {
++ (Prerelease::EMPTY, text)
++ };
++
++ let (build, text) = if let Some(text) = text.strip_prefix('+') {
++ pos = Position::Build;
++ let (build, text) = build_identifier(text)?;
++ if build.is_empty() {
++ return Err(Error::new(ErrorKind::EmptySegment(pos)));
++ }
++ (build, text)
++ } else {
++ (BuildMetadata::EMPTY, text)
++ };
++
++ if let Some(unexpected) = text.chars().next() {
++ return Err(Error::new(ErrorKind::UnexpectedCharAfter(pos, unexpected)));
++ }
++
++ Ok(Version {
++ major,
++ minor,
++ patch,
++ pre,
++ build,
++ })
++ }
++}
++
++impl FromStr for VersionReq {
++ type Err = Error;
++
++ fn from_str(text: &str) -> Result<Self, Self::Err> {
++ let text = text.trim_start_matches(' ');
++ if let Some((ch, text)) = wildcard(text) {
++ let rest = text.trim_start_matches(' ');
++ if rest.is_empty() {
++ #[cfg(not(no_const_vec_new))]
++ return Ok(VersionReq::STAR);
++ #[cfg(no_const_vec_new)] // rustc <1.39
++ return Ok(VersionReq {
++ comparators: Vec::new(),
++ });
++ } else if rest.starts_with(',') {
++ return Err(Error::new(ErrorKind::WildcardNotTheOnlyComparator(ch)));
++ } else {
++ return Err(Error::new(ErrorKind::UnexpectedAfterWildcard));
++ }
++ }
++
++ let depth = 0;
++ let mut comparators = Vec::new();
++ let len = version_req(text, &mut comparators, depth)?;
++ unsafe { comparators.set_len(len) }
++ Ok(VersionReq { comparators })
++ }
++}
++
++impl FromStr for Comparator {
++ type Err = Error;
++
++ fn from_str(text: &str) -> Result<Self, Self::Err> {
++ let text = text.trim_start_matches(' ');
++ let (comparator, pos, rest) = comparator(text)?;
++ if !rest.is_empty() {
++ let unexpected = rest.chars().next().unwrap();
++ return Err(Error::new(ErrorKind::UnexpectedCharAfter(pos, unexpected)));
++ }
++ Ok(comparator)
++ }
++}
++
++impl FromStr for Prerelease {
++ type Err = Error;
++
++ fn from_str(text: &str) -> Result<Self, Self::Err> {
++ let (pre, rest) = prerelease_identifier(text)?;
++ if !rest.is_empty() {
++ return Err(Error::new(ErrorKind::IllegalCharacter(Position::Pre)));
++ }
++ Ok(pre)
++ }
++}
++
++impl FromStr for BuildMetadata {
++ type Err = Error;
++
++ fn from_str(text: &str) -> Result<Self, Self::Err> {
++ let (build, rest) = build_identifier(text)?;
++ if !rest.is_empty() {
++ return Err(Error::new(ErrorKind::IllegalCharacter(Position::Build)));
++ }
++ Ok(build)
++ }
++}
++
++impl Error {
++ fn new(kind: ErrorKind) -> Self {
++ Error { kind }
++ }
++}
++
++impl Op {
++ const DEFAULT: Self = Op::Caret;
++}
++
++fn numeric_identifier(input: &str, pos: Position) -> Result<(u64, &str), Error> {
++ let mut len = 0;
++ let mut value = 0u64;
++
++ while let Some(&digit) = input.as_bytes().get(len) {
++ if digit < b'0' || digit > b'9' {
++ break;
++ }
++ if value == 0 && len > 0 {
++ return Err(Error::new(ErrorKind::LeadingZero(pos)));
++ }
++ match value
++ .checked_mul(10)
++ .and_then(|value| value.checked_add((digit - b'0') as u64))
++ {
++ Some(sum) => value = sum,
++ None => return Err(Error::new(ErrorKind::Overflow(pos))),
++ }
++ len += 1;
++ }
++
++ if len > 0 {
++ Ok((value, &input[len..]))
++ } else if let Some(unexpected) = input[len..].chars().next() {
++ Err(Error::new(ErrorKind::UnexpectedChar(pos, unexpected)))
++ } else {
++ Err(Error::new(ErrorKind::UnexpectedEnd(pos)))
++ }
++}
++
++fn wildcard(input: &str) -> Option<(char, &str)> {
++ if let Some(rest) = input.strip_prefix('*') {
++ Some(('*', rest))
++ } else if let Some(rest) = input.strip_prefix('x') {
++ Some(('x', rest))
++ } else if let Some(rest) = input.strip_prefix('X') {
++ Some(('X', rest))
++ } else {
++ None
++ }
++}
++
++fn dot(input: &str, pos: Position) -> Result<&str, Error> {
++ if let Some(rest) = input.strip_prefix('.') {
++ Ok(rest)
++ } else if let Some(unexpected) = input.chars().next() {
++ Err(Error::new(ErrorKind::UnexpectedCharAfter(pos, unexpected)))
++ } else {
++ Err(Error::new(ErrorKind::UnexpectedEnd(pos)))
++ }
++}
++
++fn prerelease_identifier(input: &str) -> Result<(Prerelease, &str), Error> {
++ let (string, rest) = identifier(input, Position::Pre)?;
++ let identifier = unsafe { Identifier::new_unchecked(string) };
++ Ok((Prerelease { identifier }, rest))
++}
++
++fn build_identifier(input: &str) -> Result<(BuildMetadata, &str), Error> {
++ let (string, rest) = identifier(input, Position::Build)?;
++ let identifier = unsafe { Identifier::new_unchecked(string) };
++ Ok((BuildMetadata { identifier }, rest))
++}
++
++fn identifier(input: &str, pos: Position) -> Result<(&str, &str), Error> {
++ let mut accumulated_len = 0;
++ let mut segment_len = 0;
++ let mut segment_has_nondigit = false;
++
++ loop {
++ match input.as_bytes().get(accumulated_len + segment_len) {
++ Some(b'A'..=b'Z') | Some(b'a'..=b'z') | Some(b'-') => {
++ segment_len += 1;
++ segment_has_nondigit = true;
++ }
++ Some(b'0'..=b'9') => {
++ segment_len += 1;
++ }
++ boundary => {
++ if segment_len == 0 {
++ if accumulated_len == 0 && boundary != Some(&b'.') {
++ return Ok(("", input));
++ } else {
++ return Err(Error::new(ErrorKind::EmptySegment(pos)));
++ }
++ }
++ if pos == Position::Pre
++ && segment_len > 1
++ && !segment_has_nondigit
++ && input[accumulated_len..].starts_with('0')
++ {
++ return Err(Error::new(ErrorKind::LeadingZero(pos)));
++ }
++ accumulated_len += segment_len;
++ if boundary == Some(&b'.') {
++ accumulated_len += 1;
++ segment_len = 0;
++ segment_has_nondigit = false;
++ } else {
++ return Ok(input.split_at(accumulated_len));
++ }
++ }
++ }
++ }
++}
++
++fn op(input: &str) -> (Op, &str) {
++ let bytes = input.as_bytes();
++ if bytes.get(0) == Some(&b'=') {
++ (Op::Exact, &input[1..])
++ } else if bytes.get(0) == Some(&b'>') {
++ if bytes.get(1) == Some(&b'=') {
++ (Op::GreaterEq, &input[2..])
++ } else {
++ (Op::Greater, &input[1..])
++ }
++ } else if bytes.get(0) == Some(&b'<') {
++ if bytes.get(1) == Some(&b'=') {
++ (Op::LessEq, &input[2..])
++ } else {
++ (Op::Less, &input[1..])
++ }
++ } else if bytes.get(0) == Some(&b'~') {
++ (Op::Tilde, &input[1..])
++ } else if bytes.get(0) == Some(&b'^') {
++ (Op::Caret, &input[1..])
++ } else {
++ (Op::DEFAULT, input)
++ }
++}
++
++fn comparator(input: &str) -> Result<(Comparator, Position, &str), Error> {
++ let (mut op, text) = op(input);
++ let default_op = input.len() == text.len();
++ let text = text.trim_start_matches(' ');
++
++ let mut pos = Position::Major;
++ let (major, text) = numeric_identifier(text, pos)?;
++ let mut has_wildcard = false;
++
++ let (minor, text) = if let Some(text) = text.strip_prefix('.') {
++ pos = Position::Minor;
++ if let Some((_, text)) = wildcard(text) {
++ has_wildcard = true;
++ if default_op {
++ op = Op::Wildcard;
++ }
++ (None, text)
++ } else {
++ let (minor, text) = numeric_identifier(text, pos)?;
++ (Some(minor), text)
++ }
++ } else {
++ (None, text)
++ };
++
++ let (patch, text) = if let Some(text) = text.strip_prefix('.') {
++ pos = Position::Patch;
++ if let Some((_, text)) = wildcard(text) {
++ if default_op {
++ op = Op::Wildcard;
++ }
++ (None, text)
++ } else if has_wildcard {
++ return Err(Error::new(ErrorKind::UnexpectedAfterWildcard));
++ } else {
++ let (patch, text) = numeric_identifier(text, pos)?;
++ (Some(patch), text)
++ }
++ } else {
++ (None, text)
++ };
++
++ let (pre, text) = if patch.is_some() && text.starts_with('-') {
++ pos = Position::Pre;
++ let text = &text[1..];
++ let (pre, text) = prerelease_identifier(text)?;
++ if pre.is_empty() {
++ return Err(Error::new(ErrorKind::EmptySegment(pos)));
++ }
++ (pre, text)
++ } else {
++ (Prerelease::EMPTY, text)
++ };
++
++ let text = if patch.is_some() && text.starts_with('+') {
++ pos = Position::Build;
++ let text = &text[1..];
++ let (build, text) = build_identifier(text)?;
++ if build.is_empty() {
++ return Err(Error::new(ErrorKind::EmptySegment(pos)));
++ }
++ text
++ } else {
++ text
++ };
++
++ let text = text.trim_start_matches(' ');
++
++ let comparator = Comparator {
++ op,
++ major,
++ minor,
++ patch,
++ pre,
++ };
++
++ Ok((comparator, pos, text))
++}
++
++fn version_req(input: &str, out: &mut Vec<Comparator>, depth: usize) -> Result<usize, Error> {
++ let (comparator, pos, text) = match comparator(input) {
++ Ok(success) => success,
++ Err(mut error) => {
++ if let Some((ch, mut rest)) = wildcard(input) {
++ rest = rest.trim_start_matches(' ');
++ if rest.is_empty() || rest.starts_with(',') {
++ error.kind = ErrorKind::WildcardNotTheOnlyComparator(ch);
++ }
++ }
++ return Err(error);
++ }
++ };
++
++ if text.is_empty() {
++ out.reserve_exact(depth + 1);
++ unsafe { out.as_mut_ptr().add(depth).write(comparator) }
++ return Ok(depth + 1);
++ }
++
++ let text = if let Some(text) = text.strip_prefix(',') {
++ text.trim_start_matches(' ')
++ } else {
++ let unexpected = text.chars().next().unwrap();
++ return Err(Error::new(ErrorKind::ExpectedCommaFound(pos, unexpected)));
++ };
++
++ const MAX_COMPARATORS: usize = 32;
++ if depth + 1 == MAX_COMPARATORS {
++ return Err(Error::new(ErrorKind::ExcessiveComparators));
++ }
++
++ // Recurse to collect parsed Comparator objects on the stack. We perform a
++ // single allocation to allocate exactly the right sized Vec only once the
++ // total number of comparators is known.
++ let len = version_req(text, out, depth + 1)?;
++ unsafe { out.as_mut_ptr().add(depth).write(comparator) }
++ Ok(len)
++}
+diff --git a/third_party/rust/semver/src/serde.rs b/third_party/rust/semver/src/serde.rs
+new file mode 100644
+--- /dev/null
++++ b/third_party/rust/semver/src/serde.rs
+@@ -0,0 +1,74 @@
++use crate::{Version, VersionReq};
++use core::fmt;
++use serde::de::{Deserialize, Deserializer, Error, Visitor};
++use serde::ser::{Serialize, Serializer};
++
++impl Serialize for Version {
++ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
++ where
++ S: Serializer,
++ {
++ serializer.collect_str(self)
++ }
++}
++
++impl Serialize for VersionReq {
++ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
++ where
++ S: Serializer,
++ {
++ serializer.collect_str(self)
++ }
++}
++
++impl<'de> Deserialize<'de> for Version {
++ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
++ where
++ D: Deserializer<'de>,
++ {
++ struct VersionVisitor;
++
++ impl<'de> Visitor<'de> for VersionVisitor {
++ type Value = Version;
++
++ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
++ formatter.write_str("semver version")
++ }
++
++ fn visit_str<E>(self, string: &str) -> Result<Self::Value, E>
++ where
++ E: Error,
++ {
++ string.parse().map_err(Error::custom)
++ }
++ }
++
++ deserializer.deserialize_str(VersionVisitor)
++ }
++}
++
++impl<'de> Deserialize<'de> for VersionReq {
++ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
++ where
++ D: Deserializer<'de>,
++ {
++ struct VersionReqVisitor;
++
++ impl<'de> Visitor<'de> for VersionReqVisitor {
++ type Value = VersionReq;
++
++ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
++ formatter.write_str("semver version")
++ }
++
++ fn visit_str<E>(self, string: &str) -> Result<Self::Value, E>
++ where
++ E: Error,
++ {
++ string.parse().map_err(Error::custom)
++ }
++ }
++
++ deserializer.deserialize_str(VersionReqVisitor)
++ }
++}
+diff --git a/third_party/rust/semver/src/version.rs b/third_party/rust/semver/src/version.rs
+deleted file mode 100644
+--- a/third_party/rust/semver/src/version.rs
++++ /dev/null
+@@ -1,759 +0,0 @@
+-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
+-// file at the top-level directory of this distribution and at
+-// http://rust-lang.org/COPYRIGHT.
+-//
+-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+-// option. This file may not be copied, modified, or distributed
+-// except according to those terms.
+-
+-//! The `version` module gives you tools to create and compare SemVer-compliant
+-//! versions.
+-
+-use std::cmp::{self, Ordering};
+-use std::fmt;
+-use std::hash;
+-use std::error::Error;
+-
+-use std::result;
+-use std::str;
+-
+-use semver_parser;
+-
+-#[cfg(feature = "serde")]
+-use serde::ser::{Serialize, Serializer};
+-#[cfg(feature = "serde")]
+-use serde::de::{self, Deserialize, Deserializer, Visitor};
+-
+-/// An identifier in the pre-release or build metadata.
+-///
+-/// See sections 9 and 10 of the spec for more about pre-release identifers and
+-/// build metadata.
+-#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+-pub enum Identifier {
+- /// An identifier that's solely numbers.
+- Numeric(u64),
+- /// An identifier with letters and numbers.
+- AlphaNumeric(String),
+-}
+-
+-impl From<semver_parser::version::Identifier> for Identifier {
+- fn from(other: semver_parser::version::Identifier) -> Identifier {
+- match other {
+- semver_parser::version::Identifier::Numeric(n) => Identifier::Numeric(n),
+- semver_parser::version::Identifier::AlphaNumeric(s) => Identifier::AlphaNumeric(s),
+- }
+- }
+-}
+-
+-impl fmt::Display for Identifier {
+- #[inline]
+- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+- match *self {
+- Identifier::Numeric(ref n) => fmt::Display::fmt(n, f),
+- Identifier::AlphaNumeric(ref s) => fmt::Display::fmt(s, f),
+- }
+- }
+-}
+-
+-#[cfg(feature = "serde")]
+-impl Serialize for Identifier {
+- fn serialize<S>(&self, serializer: S) -> result::Result<S::Ok, S::Error>
+- where S: Serializer
+- {
+- // Serialize Identifier as a number or string.
+- match *self {
+- Identifier::Numeric(n) => serializer.serialize_u64(n),
+- Identifier::AlphaNumeric(ref s) => serializer.serialize_str(s),
+- }
+- }
+-}
+-
+-#[cfg(feature = "serde")]
+-impl<'de> Deserialize<'de> for Identifier {
+- fn deserialize<D>(deserializer: D) -> result::Result<Self, D::Error>
+- where D: Deserializer<'de>
+- {
+- struct IdentifierVisitor;
+-
+- // Deserialize Identifier from a number or string.
+- impl<'de> Visitor<'de> for IdentifierVisitor {
+- type Value = Identifier;
+-
+- fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+- formatter.write_str("a SemVer pre-release or build identifier")
+- }
+-
+- fn visit_u64<E>(self, numeric: u64) -> result::Result<Self::Value, E>
+- where E: de::Error
+- {
+- Ok(Identifier::Numeric(numeric))
+- }
+-
+- fn visit_str<E>(self, alphanumeric: &str) -> result::Result<Self::Value, E>
+- where E: de::Error
+- {
+- Ok(Identifier::AlphaNumeric(alphanumeric.to_owned()))
+- }
+- }
+-
+- deserializer.deserialize_any(IdentifierVisitor)
+- }
+-}
+-
+-/// Represents a version number conforming to the semantic versioning scheme.
+-#[derive(Clone, Eq, Debug)]
+-pub struct Version {
+- /// The major version, to be incremented on incompatible changes.
+- pub major: u64,
+- /// The minor version, to be incremented when functionality is added in a
+- /// backwards-compatible manner.
+- pub minor: u64,
+- /// The patch version, to be incremented when backwards-compatible bug
+- /// fixes are made.
+- pub patch: u64,
+- /// The pre-release version identifier, if one exists.
+- pub pre: Vec<Identifier>,
+- /// The build metadata, ignored when determining version precedence.
+- pub build: Vec<Identifier>,
+-}
+-
+-impl From<semver_parser::version::Version> for Version {
+- fn from(other: semver_parser::version::Version) -> Version {
+- Version {
+- major: other.major,
+- minor: other.minor,
+- patch: other.patch,
+- pre: other.pre.into_iter().map(From::from).collect(),
+- build: other.build.into_iter().map(From::from).collect(),
+- }
+- }
+-}
+-
+-#[cfg(feature = "serde")]
+-impl Serialize for Version {
+- fn serialize<S>(&self, serializer: S) -> result::Result<S::Ok, S::Error>
+- where S: Serializer
+- {
+- // Serialize Version as a string.
+- serializer.collect_str(self)
+- }
+-}
+-
+-#[cfg(feature = "serde")]
+-impl<'de> Deserialize<'de> for Version {
+- fn deserialize<D>(deserializer: D) -> result::Result<Self, D::Error>
+- where D: Deserializer<'de>
+- {
+- struct VersionVisitor;
+-
+- // Deserialize Version from a string.
+- impl<'de> Visitor<'de> for VersionVisitor {
+- type Value = Version;
+-
+- fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+- formatter.write_str("a SemVer version as a string")
+- }
+-
+- fn visit_str<E>(self, v: &str) -> result::Result<Self::Value, E>
+- where E: de::Error
+- {
+- Version::parse(v).map_err(de::Error::custom)
+- }
+- }
+-
+- deserializer.deserialize_str(VersionVisitor)
+- }
+-}
+-
+-/// An error type for this crate
+-///
+-/// Currently, just a generic error. Will make this nicer later.
+-#[derive(Clone,PartialEq,Debug,PartialOrd)]
+-pub enum SemVerError {
+- /// An error ocurred while parsing.
+- ParseError(String),
+-}
+-
+-impl fmt::Display for SemVerError {
+- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+- match self {
+- &SemVerError::ParseError(ref m) => write!(f, "{}", m),
+- }
+- }
+-}
+-
+-impl Error for SemVerError {
+- fn description(&self) -> &str {
+- match self {
+- &SemVerError::ParseError(ref m) => m,
+- }
+- }
+-}
+-
+-/// A Result type for errors
+-pub type Result<T> = result::Result<T, SemVerError>;
+-
+-impl Version {
+-
+- /// Contructs the simple case without pre or build.
+- pub fn new(major: u64, minor: u64, patch: u64) -> Version {
+- Version {
+- major: major,
+- minor: minor,
+- patch: patch,
+- pre: Vec::new(),
+- build: Vec::new()
+- }
+- }
+-
+- /// Parse a string into a semver object.
+- pub fn parse(version: &str) -> Result<Version> {
+- let res = semver_parser::version::parse(version);
+-
+- match res {
+- // Convert plain String error into proper ParseError
+- Err(e) => Err(SemVerError::ParseError(e)),
+- Ok(v) => Ok(From::from(v)),
+- }
+- }
+-
+- /// Clears the build metadata
+- fn clear_metadata(&mut self) {
+- self.build = Vec::new();
+- self.pre = Vec::new();
+- }
+-
+- /// Increments the patch number for this Version (Must be mutable)
+- pub fn increment_patch(&mut self) {
+- self.patch += 1;
+- self.clear_metadata();
+- }
+-
+- /// Increments the minor version number for this Version (Must be mutable)
+- ///
+- /// As instructed by section 7 of the spec, the patch number is reset to 0.
+- pub fn increment_minor(&mut self) {
+- self.minor += 1;
+- self.patch = 0;
+- self.clear_metadata();
+- }
+-
+- /// Increments the major version number for this Version (Must be mutable)
+- ///
+- /// As instructed by section 8 of the spec, the minor and patch numbers are
+- /// reset to 0
+- pub fn increment_major(&mut self) {
+- self.major += 1;
+- self.minor = 0;
+- self.patch = 0;
+- self.clear_metadata();
+- }
+-
+- /// Checks to see if the current Version is in pre-release status
+- pub fn is_prerelease(&self) -> bool {
+- !self.pre.is_empty()
+- }
+-}
+-
+-impl str::FromStr for Version {
+- type Err = SemVerError;
+-
+- fn from_str(s: &str) -> Result<Version> {
+- Version::parse(s)
+- }
+-}
+-
+-impl fmt::Display for Version {
+- #[inline]
+- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+- try!(write!(f, "{}.{}.{}", self.major, self.minor, self.patch));
+- if !self.pre.is_empty() {
+- try!(write!(f, "-"));
+- for (i, x) in self.pre.iter().enumerate() {
+- if i != 0 {
+- try!(write!(f, "."))
+- }
+- try!(write!(f, "{}", x));
+- }
+- }
+- if !self.build.is_empty() {
+- try!(write!(f, "+"));
+- for (i, x) in self.build.iter().enumerate() {
+- if i != 0 {
+- try!(write!(f, "."))
+- }
+- try!(write!(f, "{}", x));
+- }
+- }
+- Ok(())
+- }
+-}
+-
+-impl cmp::PartialEq for Version {
+- #[inline]
+- fn eq(&self, other: &Version) -> bool {
+- // We should ignore build metadata here, otherwise versions v1 and v2
+- // can exist such that !(v1 < v2) && !(v1 > v2) && v1 != v2, which
+- // violate strict total ordering rules.
+- self.major == other.major && self.minor == other.minor && self.patch == other.patch &&
+- self.pre == other.pre
+- }
+-}
+-
+-impl cmp::PartialOrd for Version {
+- fn partial_cmp(&self, other: &Version) -> Option<Ordering> {
+- Some(self.cmp(other))
+- }
+-}
+-
+-impl cmp::Ord for Version {
+- fn cmp(&self, other: &Version) -> Ordering {
+- match self.major.cmp(&other.major) {
+- Ordering::Equal => {}
+- r => return r,
+- }
+-
+- match self.minor.cmp(&other.minor) {
+- Ordering::Equal => {}
+- r => return r,
+- }
+-
+- match self.patch.cmp(&other.patch) {
+- Ordering::Equal => {}
+- r => return r,
+- }
+-
+- // NB: semver spec says 0.0.0-pre < 0.0.0
+- // but the version of ord defined for vec
+- // says that [] < [pre] so we alter it here
+- match (self.pre.len(), other.pre.len()) {
+- (0, 0) => Ordering::Equal,
+- (0, _) => Ordering::Greater,
+- (_, 0) => Ordering::Less,
+- (_, _) => self.pre.cmp(&other.pre),
+- }
+- }
+-}
+-
+-impl hash::Hash for Version {
+- fn hash<H: hash::Hasher>(&self, into: &mut H) {
+- self.major.hash(into);
+- self.minor.hash(into);
+- self.patch.hash(into);
+- self.pre.hash(into);
+- }
+-}
+-
+-impl From<(u64,u64,u64)> for Version {
+- fn from(tuple: (u64,u64,u64)) -> Version {
+- let (major, minor, patch) = tuple;
+- Version::new(major, minor, patch)
+- }
+-}
+-
+-#[cfg(test)]
+-mod tests {
+- use std::result;
+- use super::Version;
+- use super::Identifier;
+- use super::SemVerError;
+-
+- #[test]
+- fn test_parse() {
+- fn parse_error(e: &str) -> result::Result<Version, SemVerError> {
+- return Err(SemVerError::ParseError(e.to_string()));
+- }
+-
+- assert_eq!(Version::parse(""),
+- parse_error("Error parsing major identifier"));
+- assert_eq!(Version::parse(" "),
+- parse_error("Error parsing major identifier"));
+- assert_eq!(Version::parse("1"),
+- parse_error("Expected dot"));
+- assert_eq!(Version::parse("1.2"),
+- parse_error("Expected dot"));
+- assert_eq!(Version::parse("1.2.3-"),
+- parse_error("Error parsing prerelease"));
+- assert_eq!(Version::parse("a.b.c"),
+- parse_error("Error parsing major identifier"));
+- assert_eq!(Version::parse("1.2.3 abc"),
+- parse_error("Extra junk after valid version: abc"));
+-
+- assert_eq!(Version::parse("1.2.3"),
+- Ok(Version {
+- major: 1,
+- minor: 2,
+- patch: 3,
+- pre: Vec::new(),
+- build: Vec::new(),
+- }));
+-
+- assert_eq!(Version::parse("1.2.3"),
+- Ok(Version::new(1,2,3)));
+-
+- assert_eq!(Version::parse(" 1.2.3 "),
+- Ok(Version {
+- major: 1,
+- minor: 2,
+- patch: 3,
+- pre: Vec::new(),
+- build: Vec::new(),
+- }));
+- assert_eq!(Version::parse("1.2.3-alpha1"),
+- Ok(Version {
+- major: 1,
+- minor: 2,
+- patch: 3,
+- pre: vec![Identifier::AlphaNumeric(String::from("alpha1"))],
+- build: Vec::new(),
+- }));
+- assert_eq!(Version::parse(" 1.2.3-alpha1 "),
+- Ok(Version {
+- major: 1,
+- minor: 2,
+- patch: 3,
+- pre: vec![Identifier::AlphaNumeric(String::from("alpha1"))],
+- build: Vec::new(),
+- }));
+- assert_eq!(Version::parse("1.2.3+build5"),
+- Ok(Version {
+- major: 1,
+- minor: 2,
+- patch: 3,
+- pre: Vec::new(),
+- build: vec![Identifier::AlphaNumeric(String::from("build5"))],
+- }));
+- assert_eq!(Version::parse(" 1.2.3+build5 "),
+- Ok(Version {
+- major: 1,
+- minor: 2,
+- patch: 3,
+- pre: Vec::new(),
+- build: vec![Identifier::AlphaNumeric(String::from("build5"))],
+- }));
+- assert_eq!(Version::parse("1.2.3-alpha1+build5"),
+- Ok(Version {
+- major: 1,
+- minor: 2,
+- patch: 3,
+- pre: vec![Identifier::AlphaNumeric(String::from("alpha1"))],
+- build: vec![Identifier::AlphaNumeric(String::from("build5"))],
+- }));
+- assert_eq!(Version::parse(" 1.2.3-alpha1+build5 "),
+- Ok(Version {
+- major: 1,
+- minor: 2,
+- patch: 3,
+- pre: vec![Identifier::AlphaNumeric(String::from("alpha1"))],
+- build: vec![Identifier::AlphaNumeric(String::from("build5"))],
+- }));
+- assert_eq!(Version::parse("1.2.3-1.alpha1.9+build5.7.3aedf "),
+- Ok(Version {
+- major: 1,
+- minor: 2,
+- patch: 3,
+- pre: vec![Identifier::Numeric(1),
+- Identifier::AlphaNumeric(String::from("alpha1")),
+- Identifier::Numeric(9),
+- ],
+- build: vec![Identifier::AlphaNumeric(String::from("build5")),
+- Identifier::Numeric(7),
+- Identifier::AlphaNumeric(String::from("3aedf")),
+- ],
+- }));
+- assert_eq!(Version::parse("0.4.0-beta.1+0851523"),
+- Ok(Version {
+- major: 0,
+- minor: 4,
+- patch: 0,
+- pre: vec![Identifier::AlphaNumeric(String::from("beta")),
+- Identifier::Numeric(1),
+- ],
+- build: vec![Identifier::AlphaNumeric(String::from("0851523"))],
+- }));
+-
+- }
+-
+- #[test]
+- fn test_increment_patch() {
+- let mut buggy_release = Version::parse("0.1.0").unwrap();
+- buggy_release.increment_patch();
+- assert_eq!(buggy_release, Version::parse("0.1.1").unwrap());
+- }
+-
+- #[test]
+- fn test_increment_minor() {
+- let mut feature_release = Version::parse("1.4.6").unwrap();
+- feature_release.increment_minor();
+- assert_eq!(feature_release, Version::parse("1.5.0").unwrap());
+- }
+-
+- #[test]
+- fn test_increment_major() {
+- let mut chrome_release = Version::parse("46.1.246773").unwrap();
+- chrome_release.increment_major();
+- assert_eq!(chrome_release, Version::parse("47.0.0").unwrap());
+- }
+-
+- #[test]
+- fn test_increment_keep_prerelease() {
+- let mut release = Version::parse("1.0.0-alpha").unwrap();
+- release.increment_patch();
+-
+- assert_eq!(release, Version::parse("1.0.1").unwrap());
+-
+- release.increment_minor();
+-
+- assert_eq!(release, Version::parse("1.1.0").unwrap());
+-
+- release.increment_major();
+-
+- assert_eq!(release, Version::parse("2.0.0").unwrap());
+- }
+-
+-
+- #[test]
+- fn test_increment_clear_metadata() {
+- let mut release = Version::parse("1.0.0+4442").unwrap();
+- release.increment_patch();
+-
+- assert_eq!(release, Version::parse("1.0.1").unwrap());
+- release = Version::parse("1.0.1+hello").unwrap();
+-
+- release.increment_minor();
+-
+- assert_eq!(release, Version::parse("1.1.0").unwrap());
+- release = Version::parse("1.1.3747+hello").unwrap();
+-
+- release.increment_major();
+-
+- assert_eq!(release, Version::parse("2.0.0").unwrap());
+- }
+-
+- #[test]
+- fn test_eq() {
+- assert_eq!(Version::parse("1.2.3"), Version::parse("1.2.3"));
+- assert_eq!(Version::parse("1.2.3-alpha1"),
+- Version::parse("1.2.3-alpha1"));
+- assert_eq!(Version::parse("1.2.3+build.42"),
+- Version::parse("1.2.3+build.42"));
+- assert_eq!(Version::parse("1.2.3-alpha1+42"),
+- Version::parse("1.2.3-alpha1+42"));
+- assert_eq!(Version::parse("1.2.3+23"), Version::parse("1.2.3+42"));
+- }
+-
+- #[test]
+- fn test_ne() {
+- assert!(Version::parse("0.0.0") != Version::parse("0.0.1"));
+- assert!(Version::parse("0.0.0") != Version::parse("0.1.0"));
+- assert!(Version::parse("0.0.0") != Version::parse("1.0.0"));
+- assert!(Version::parse("1.2.3-alpha") != Version::parse("1.2.3-beta"));
+- }
+-
+- #[test]
+- fn test_show() {
+- assert_eq!(format!("{}", Version::parse("1.2.3").unwrap()),
+- "1.2.3".to_string());
+- assert_eq!(format!("{}", Version::parse("1.2.3-alpha1").unwrap()),
+- "1.2.3-alpha1".to_string());
+- assert_eq!(format!("{}", Version::parse("1.2.3+build.42").unwrap()),
+- "1.2.3+build.42".to_string());
+- assert_eq!(format!("{}", Version::parse("1.2.3-alpha1+42").unwrap()),
+- "1.2.3-alpha1+42".to_string());
+- }
+-
+- #[test]
+- fn test_to_string() {
+- assert_eq!(Version::parse("1.2.3").unwrap().to_string(),
+- "1.2.3".to_string());
+- assert_eq!(Version::parse("1.2.3-alpha1").unwrap().to_string(),
+- "1.2.3-alpha1".to_string());
+- assert_eq!(Version::parse("1.2.3+build.42").unwrap().to_string(),
+- "1.2.3+build.42".to_string());
+- assert_eq!(Version::parse("1.2.3-alpha1+42").unwrap().to_string(),
+- "1.2.3-alpha1+42".to_string());
+- }
+-
+- #[test]
+- fn test_lt() {
+- assert!(Version::parse("0.0.0") < Version::parse("1.2.3-alpha2"));
+- assert!(Version::parse("1.0.0") < Version::parse("1.2.3-alpha2"));
+- assert!(Version::parse("1.2.0") < Version::parse("1.2.3-alpha2"));
+- assert!(Version::parse("1.2.3-alpha1") < Version::parse("1.2.3"));
+- assert!(Version::parse("1.2.3-alpha1") < Version::parse("1.2.3-alpha2"));
+- assert!(!(Version::parse("1.2.3-alpha2") < Version::parse("1.2.3-alpha2")));
+- assert!(!(Version::parse("1.2.3+23") < Version::parse("1.2.3+42")));
+- }
+-
+- #[test]
+- fn test_le() {
+- assert!(Version::parse("0.0.0") <= Version::parse("1.2.3-alpha2"));
+- assert!(Version::parse("1.0.0") <= Version::parse("1.2.3-alpha2"));
+- assert!(Version::parse("1.2.0") <= Version::parse("1.2.3-alpha2"));
+- assert!(Version::parse("1.2.3-alpha1") <= Version::parse("1.2.3-alpha2"));
+- assert!(Version::parse("1.2.3-alpha2") <= Version::parse("1.2.3-alpha2"));
+- assert!(Version::parse("1.2.3+23") <= Version::parse("1.2.3+42"));
+- }
+-
+- #[test]
+- fn test_gt() {
+- assert!(Version::parse("1.2.3-alpha2") > Version::parse("0.0.0"));
+- assert!(Version::parse("1.2.3-alpha2") > Version::parse("1.0.0"));
+- assert!(Version::parse("1.2.3-alpha2") > Version::parse("1.2.0"));
+- assert!(Version::parse("1.2.3-alpha2") > Version::parse("1.2.3-alpha1"));
+- assert!(Version::parse("1.2.3") > Version::parse("1.2.3-alpha2"));
+- assert!(!(Version::parse("1.2.3-alpha2") > Version::parse("1.2.3-alpha2")));
+- assert!(!(Version::parse("1.2.3+23") > Version::parse("1.2.3+42")));
+- }
+-
+- #[test]
+- fn test_ge() {
+- assert!(Version::parse("1.2.3-alpha2") >= Version::parse("0.0.0"));
+- assert!(Version::parse("1.2.3-alpha2") >= Version::parse("1.0.0"));
+- assert!(Version::parse("1.2.3-alpha2") >= Version::parse("1.2.0"));
+- assert!(Version::parse("1.2.3-alpha2") >= Version::parse("1.2.3-alpha1"));
+- assert!(Version::parse("1.2.3-alpha2") >= Version::parse("1.2.3-alpha2"));
+- assert!(Version::parse("1.2.3+23") >= Version::parse("1.2.3+42"));
+- }
+-
+- #[test]
+- fn test_prerelease_check() {
+- assert!(Version::parse("1.0.0").unwrap().is_prerelease() == false);
+- assert!(Version::parse("0.0.1").unwrap().is_prerelease() == false);
+- assert!(Version::parse("4.1.4-alpha").unwrap().is_prerelease());
+- assert!(Version::parse("1.0.0-beta294296").unwrap().is_prerelease());
+- }
+-
+- #[test]
+- fn test_spec_order() {
+- let vs = ["1.0.0-alpha",
+- "1.0.0-alpha.1",
+- "1.0.0-alpha.beta",
+- "1.0.0-beta",
+- "1.0.0-beta.2",
+- "1.0.0-beta.11",
+- "1.0.0-rc.1",
+- "1.0.0"];
+- let mut i = 1;
+- while i < vs.len() {
+- let a = Version::parse(vs[i - 1]);
+- let b = Version::parse(vs[i]);
+- assert!(a < b, "nope {:?} < {:?}", a, b);
+- i += 1;
+- }
+- }
+-
+- #[test]
+- fn test_from_str() {
+- assert_eq!("1.2.3".parse(),
+- Ok(Version {
+- major: 1,
+- minor: 2,
+- patch: 3,
+- pre: Vec::new(),
+- build: Vec::new(),
+- }));
+- assert_eq!(" 1.2.3 ".parse(),
+- Ok(Version {
+- major: 1,
+- minor: 2,
+- patch: 3,
+- pre: Vec::new(),
+- build: Vec::new(),
+- }));
+- assert_eq!("1.2.3-alpha1".parse(),
+- Ok(Version {
+- major: 1,
+- minor: 2,
+- patch: 3,
+- pre: vec![Identifier::AlphaNumeric(String::from("alpha1"))],
+- build: Vec::new(),
+- }));
+- assert_eq!(" 1.2.3-alpha1 ".parse(),
+- Ok(Version {
+- major: 1,
+- minor: 2,
+- patch: 3,
+- pre: vec![Identifier::AlphaNumeric(String::from("alpha1"))],
+- build: Vec::new(),
+- }));
+- assert_eq!("1.2.3+build5".parse(),
+- Ok(Version {
+- major: 1,
+- minor: 2,
+- patch: 3,
+- pre: Vec::new(),
+- build: vec![Identifier::AlphaNumeric(String::from("build5"))],
+- }));
+- assert_eq!(" 1.2.3+build5 ".parse(),
+- Ok(Version {
+- major: 1,
+- minor: 2,
+- patch: 3,
+- pre: Vec::new(),
+- build: vec![Identifier::AlphaNumeric(String::from("build5"))],
+- }));
+- assert_eq!("1.2.3-alpha1+build5".parse(),
+- Ok(Version {
+- major: 1,
+- minor: 2,
+- patch: 3,
+- pre: vec![Identifier::AlphaNumeric(String::from("alpha1"))],
+- build: vec![Identifier::AlphaNumeric(String::from("build5"))],
+- }));
+- assert_eq!(" 1.2.3-alpha1+build5 ".parse(),
+- Ok(Version {
+- major: 1,
+- minor: 2,
+- patch: 3,
+- pre: vec![Identifier::AlphaNumeric(String::from("alpha1"))],
+- build: vec![Identifier::AlphaNumeric(String::from("build5"))],
+- }));
+- assert_eq!("1.2.3-1.alpha1.9+build5.7.3aedf ".parse(),
+- Ok(Version {
+- major: 1,
+- minor: 2,
+- patch: 3,
+- pre: vec![Identifier::Numeric(1),
+- Identifier::AlphaNumeric(String::from("alpha1")),
+- Identifier::Numeric(9),
+- ],
+- build: vec![Identifier::AlphaNumeric(String::from("build5")),
+- Identifier::Numeric(7),
+- Identifier::AlphaNumeric(String::from("3aedf")),
+- ],
+- }));
+- assert_eq!("0.4.0-beta.1+0851523".parse(),
+- Ok(Version {
+- major: 0,
+- minor: 4,
+- patch: 0,
+- pre: vec![Identifier::AlphaNumeric(String::from("beta")),
+- Identifier::Numeric(1),
+- ],
+- build: vec![Identifier::AlphaNumeric(String::from("0851523"))],
+- }));
+-
+- }
+-
+- #[test]
+- fn test_from_str_errors() {
+- fn parse_error(e: &str) -> result::Result<Version, SemVerError> {
+- return Err(SemVerError::ParseError(e.to_string()));
+- }
+-
+- assert_eq!("".parse(), parse_error("Error parsing major identifier"));
+- assert_eq!(" ".parse(), parse_error("Error parsing major identifier"));
+- assert_eq!("1".parse(), parse_error("Expected dot"));
+- assert_eq!("1.2".parse(),
+- parse_error("Expected dot"));
+- assert_eq!("1.2.3-".parse(),
+- parse_error("Error parsing prerelease"));
+- assert_eq!("a.b.c".parse(),
+- parse_error("Error parsing major identifier"));
+- assert_eq!("1.2.3 abc".parse(),
+- parse_error("Extra junk after valid version: abc"));
+- }
+-}
+diff --git a/third_party/rust/semver/src/version_req.rs b/third_party/rust/semver/src/version_req.rs
+deleted file mode 100644
+--- a/third_party/rust/semver/src/version_req.rs
++++ /dev/null
+@@ -1,895 +0,0 @@
+-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
+-// file at the top-level directory of this distribution and at
+-// http://rust-lang.org/COPYRIGHT.
+-//
+-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+-// option. This file may not be copied, modified, or distributed
+-// except according to those terms.
+-
+-use std::error::Error;
+-use std::fmt;
+-use std::result;
+-use std::str;
+-
+-use Version;
+-use version::Identifier;
+-use semver_parser;
+-
+-#[cfg(feature = "serde")]
+-use serde::ser::{Serialize, Serializer};
+-#[cfg(feature = "serde")]
+-use serde::de::{self, Deserialize, Deserializer, Visitor};
+-
+-use self::Op::{Ex, Gt, GtEq, Lt, LtEq, Tilde, Compatible, Wildcard};
+-use self::WildcardVersion::{Major, Minor, Patch};
+-use self::ReqParseError::*;
+-
+-/// A `VersionReq` is a struct containing a list of predicates that can apply to ranges of version
+-/// numbers. Matching operations can then be done with the `VersionReq` against a particular
+-/// version to see if it satisfies some or all of the constraints.
+-#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+-pub struct VersionReq {
+- predicates: Vec<Predicate>,
+-}
+-
+-impl From<semver_parser::range::VersionReq> for VersionReq {
+- fn from(other: semver_parser::range::VersionReq) -> VersionReq {
+- VersionReq { predicates: other.predicates.into_iter().map(From::from).collect() }
+- }
+-}
+-
+-#[cfg(feature = "serde")]
+-impl Serialize for VersionReq {
+- fn serialize<S>(&self, serializer: S) -> result::Result<S::Ok, S::Error>
+- where S: Serializer
+- {
+- // Serialize VersionReq as a string.
+- serializer.collect_str(self)
+- }
+-}
+-
+-#[cfg(feature = "serde")]
+-impl<'de> Deserialize<'de> for VersionReq {
+- fn deserialize<D>(deserializer: D) -> result::Result<Self, D::Error>
+- where D: Deserializer<'de>
+- {
+- struct VersionReqVisitor;
+-
+- /// Deserialize `VersionReq` from a string.
+- impl<'de> Visitor<'de> for VersionReqVisitor {
+- type Value = VersionReq;
+-
+- fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+- formatter.write_str("a SemVer version requirement as a string")
+- }
+-
+- fn visit_str<E>(self, v: &str) -> result::Result<Self::Value, E>
+- where E: de::Error
+- {
+- VersionReq::parse(v).map_err(de::Error::custom)
+- }
+- }
+-
+- deserializer.deserialize_str(VersionReqVisitor)
+- }
+-}
+-
+-#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+-enum WildcardVersion {
+- Major,
+- Minor,
+- Patch,
+-}
+-
+-#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+-enum Op {
+- Ex, // Exact
+- Gt, // Greater than
+- GtEq, // Greater than or equal to
+- Lt, // Less than
+- LtEq, // Less than or equal to
+- Tilde, // e.g. ~1.0.0
+- Compatible, // compatible by definition of semver, indicated by ^
+- Wildcard(WildcardVersion), // x.y.*, x.*, *
+-}
+-
+-impl From<semver_parser::range::Op> for Op {
+- fn from(other: semver_parser::range::Op) -> Op {
+- use semver_parser::range;
+- match other {
+- range::Op::Ex => Op::Ex,
+- range::Op::Gt => Op::Gt,
+- range::Op::GtEq => Op::GtEq,
+- range::Op::Lt => Op::Lt,
+- range::Op::LtEq => Op::LtEq,
+- range::Op::Tilde => Op::Tilde,
+- range::Op::Compatible => Op::Compatible,
+- range::Op::Wildcard(version) => {
+- match version {
+- range::WildcardVersion::Major => Op::Wildcard(WildcardVersion::Major),
+- range::WildcardVersion::Minor => Op::Wildcard(WildcardVersion::Minor),
+- range::WildcardVersion::Patch => Op::Wildcard(WildcardVersion::Patch),
+- }
+- }
+- }
+- }
+-}
+-
+-#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+-struct Predicate {
+- op: Op,
+- major: u64,
+- minor: Option<u64>,
+- patch: Option<u64>,
+- pre: Vec<Identifier>,
+-}
+-
+-impl From<semver_parser::range::Predicate> for Predicate {
+- fn from(other: semver_parser::range::Predicate) -> Predicate {
+- Predicate {
+- op: From::from(other.op),
+- major: other.major,
+- minor: other.minor,
+- patch: other.patch,
+- pre: other.pre.into_iter().map(From::from).collect(),
+- }
+- }
+-}
+-
+-/// A `ReqParseError` is returned from methods which parse a string into a `VersionReq`. Each
+-/// enumeration is one of the possible errors that can occur.
+-#[derive(Clone, Debug, PartialEq)]
+-pub enum ReqParseError {
+- /// The given version requirement is invalid.
+- InvalidVersionRequirement,
+- /// You have already provided an operation, such as `=`, `~`, or `^`. Only use one.
+- OpAlreadySet,
+- /// The sigil you have written is not correct.
+- InvalidSigil,
+- /// All components of a version must be numeric.
+- VersionComponentsMustBeNumeric,
+- /// There was an error parsing an identifier.
+- InvalidIdentifier,
+- /// At least a major version is required.
+- MajorVersionRequired,
+- /// An unimplemented version requirement.
+- UnimplementedVersionRequirement,
+- /// This form of requirement is deprecated.
+- DeprecatedVersionRequirement(VersionReq),
+-}
+-
+-impl fmt::Display for ReqParseError {
+- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+- self.description().fmt(f)
+- }
+-}
+-
+-impl Error for ReqParseError {
+- fn description(&self) -> &str {
+- match self {
+- &InvalidVersionRequirement => "the given version requirement is invalid",
+- &OpAlreadySet => {
+- "you have already provided an operation, such as =, ~, or ^; only use one"
+- },
+- &InvalidSigil => "the sigil you have written is not correct",
+- &VersionComponentsMustBeNumeric => "version components must be numeric",
+- &InvalidIdentifier => "invalid identifier",
+- &MajorVersionRequired => "at least a major version number is required",
+- &UnimplementedVersionRequirement => {
+- "the given version requirement is not implemented, yet"
+- },
+- &DeprecatedVersionRequirement(_) => "This requirement is deprecated",
+- }
+- }
+-}
+-
+-impl From<String> for ReqParseError {
+- fn from(other: String) -> ReqParseError {
+- match &*other {
+- "Null is not a valid VersionReq" => ReqParseError::InvalidVersionRequirement,
+- "VersionReq did not parse properly." => ReqParseError::OpAlreadySet,
+- _ => ReqParseError::InvalidVersionRequirement,
+- }
+- }
+-}
+-
+-impl VersionReq {
+- /// `any()` is a factory method which creates a `VersionReq` with no constraints. In other
+- /// words, any version will match against it.
+- ///
+- /// # Examples
+- ///
+- /// ```
+- /// use semver::VersionReq;
+- ///
+- /// let anything = VersionReq::any();
+- /// ```
+- pub fn any() -> VersionReq {
+- VersionReq { predicates: vec![] }
+- }
+-
+- /// `parse()` is the main constructor of a `VersionReq`. It takes a string like `"^1.2.3"`
+- /// and turns it into a `VersionReq` that matches that particular constraint.
+- ///
+- /// A `Result` is returned which contains a `ReqParseError` if there was a problem parsing the
+- /// `VersionReq`.
+- ///
+- /// # Examples
+- ///
+- /// ```
+- /// use semver::VersionReq;
+- ///
+- /// let version = VersionReq::parse("=1.2.3");
+- /// let version = VersionReq::parse(">1.2.3");
+- /// let version = VersionReq::parse("<1.2.3");
+- /// let version = VersionReq::parse("~1.2.3");
+- /// let version = VersionReq::parse("^1.2.3");
+- /// let version = VersionReq::parse("1.2.3"); // synonym for ^1.2.3
+- /// let version = VersionReq::parse("<=1.2.3");
+- /// let version = VersionReq::parse(">=1.2.3");
+- /// ```
+- ///
+- /// This example demonstrates error handling, and will panic.
+- ///
+- /// ```should-panic
+- /// use semver::VersionReq;
+- ///
+- /// let version = match VersionReq::parse("not a version") {
+- /// Ok(version) => version,
+- /// Err(e) => panic!("There was a problem parsing: {}", e),
+- /// }
+- /// ```
+- pub fn parse(input: &str) -> Result<VersionReq, ReqParseError> {
+- let res = semver_parser::range::parse(input);
+-
+- if let Ok(v) = res {
+- return Ok(From::from(v));
+- }
+-
+- return match VersionReq::parse_deprecated(input) {
+- Some(v) => {
+- Err(ReqParseError::DeprecatedVersionRequirement(v))
+- }
+- None => Err(From::from(res.err().unwrap())),
+- }
+- }
+-
+- fn parse_deprecated(version: &str) -> Option<VersionReq> {
+- return match version {
+- ".*" => Some(VersionReq::any()),
+- "0.1.0." => Some(VersionReq::parse("0.1.0").unwrap()),
+- "0.3.1.3" => Some(VersionReq::parse("0.3.13").unwrap()),
+- "0.2*" => Some(VersionReq::parse("0.2.*").unwrap()),
+- "*.0" => Some(VersionReq::any()),
+- _ => None,
+- }
+- }
+-
+- /// `exact()` is a factory method which creates a `VersionReq` with one exact constraint.
+- ///
+- /// # Examples
+- ///
+- /// ```
+- /// use semver::VersionReq;
+- /// use semver::Version;
+- ///
+- /// let version = Version { major: 1, minor: 1, patch: 1, pre: vec![], build: vec![] };
+- /// let exact = VersionReq::exact(&version);
+- /// ```
+- pub fn exact(version: &Version) -> VersionReq {
+- VersionReq { predicates: vec![Predicate::exact(version)] }
+- }
+-
+- /// `matches()` matches a given `Version` against this `VersionReq`.
+- ///
+- /// # Examples
+- ///
+- /// ```
+- /// use semver::VersionReq;
+- /// use semver::Version;
+- ///
+- /// let version = Version { major: 1, minor: 1, patch: 1, pre: vec![], build: vec![] };
+- /// let exact = VersionReq::exact(&version);
+- ///
+- /// assert!(exact.matches(&version));
+- /// ```
+- pub fn matches(&self, version: &Version) -> bool {
+- // no predicates means anything matches
+- if self.predicates.is_empty() {
+- return true;
+- }
+-
+- self.predicates.iter().all(|p| p.matches(version)) &&
+- self.predicates.iter().any(|p| p.pre_tag_is_compatible(version))
+- }
+-}
+-
+-impl str::FromStr for VersionReq {
+- type Err = ReqParseError;
+-
+- fn from_str(s: &str) -> Result<VersionReq, ReqParseError> {
+- VersionReq::parse(s)
+- }
+-}
+-
+-impl Predicate {
+- fn exact(version: &Version) -> Predicate {
+- Predicate {
+- op: Ex,
+- major: version.major,
+- minor: Some(version.minor),
+- patch: Some(version.patch),
+- pre: version.pre.clone(),
+- }
+- }
+-
+- /// `matches()` takes a `Version` and determines if it matches this particular `Predicate`.
+- pub fn matches(&self, ver: &Version) -> bool {
+- match self.op {
+- Ex => self.is_exact(ver),
+- Gt => self.is_greater(ver),
+- GtEq => self.is_exact(ver) || self.is_greater(ver),
+- Lt => !self.is_exact(ver) && !self.is_greater(ver),
+- LtEq => !self.is_greater(ver),
+- Tilde => self.matches_tilde(ver),
+- Compatible => self.is_compatible(ver),
+- Wildcard(_) => self.matches_wildcard(ver),
+- }
+- }
+-
+- fn is_exact(&self, ver: &Version) -> bool {
+- if self.major != ver.major {
+- return false;
+- }
+-
+- match self.minor {
+- Some(minor) => {
+- if minor != ver.minor {
+- return false;
+- }
+- }
+- None => return true,
+- }
+-
+- match self.patch {
+- Some(patch) => {
+- if patch != ver.patch {
+- return false;
+- }
+- }
+- None => return true,
+- }
+-
+- if self.pre != ver.pre {
+- return false;
+- }
+-
+- true
+- }
+-
+- // https://docs.npmjs.com/misc/semver#prerelease-tags
+- fn pre_tag_is_compatible(&self, ver: &Version) -> bool {
+- // If a version has a prerelease tag (for example, 1.2.3-alpha.3) then it will
+- // only be
+- // allowed to satisfy comparator sets if at least one comparator with the same
+- // [major,
+- // minor, patch] tuple also has a prerelease tag.
+- !ver.is_prerelease() ||
+- (self.major == ver.major && self.minor == Some(ver.minor) &&
+- self.patch == Some(ver.patch) && !self.pre.is_empty())
+- }
+-
+- fn is_greater(&self, ver: &Version) -> bool {
+- if self.major != ver.major {
+- return ver.major > self.major;
+- }
+-
+- match self.minor {
+- Some(minor) => {
+- if minor != ver.minor {
+- return ver.minor > minor;
+- }
+- }
+- None => return false,
+- }
+-
+- match self.patch {
+- Some(patch) => {
+- if patch != ver.patch {
+- return ver.patch > patch;
+- }
+- }
+- None => return false,
+- }
+-
+- if !self.pre.is_empty() {
+- return ver.pre.is_empty() || ver.pre > self.pre;
+- }
+-
+- false
+- }
+-
+- // see https://www.npmjs.org/doc/misc/semver.html for behavior
+- fn matches_tilde(&self, ver: &Version) -> bool {
+- let minor = match self.minor {
+- Some(n) => n,
+- None => return self.major == ver.major,
+- };
+-
+- match self.patch {
+- Some(patch) => {
+- self.major == ver.major && minor == ver.minor &&
+- (ver.patch > patch || (ver.patch == patch && self.pre_is_compatible(ver)))
+- }
+- None => self.major == ver.major && minor == ver.minor,
+- }
+- }
+-
+- // see https://www.npmjs.org/doc/misc/semver.html for behavior
+- fn is_compatible(&self, ver: &Version) -> bool {
+- if self.major != ver.major {
+- return false;
+- }
+-
+- let minor = match self.minor {
+- Some(n) => n,
+- None => return self.major == ver.major,
+- };
+-
+- match self.patch {
+- Some(patch) => {
+- if self.major == 0 {
+- if minor == 0 {
+- ver.minor == minor && ver.patch == patch && self.pre_is_compatible(ver)
+- } else {
+- ver.minor == minor &&
+- (ver.patch > patch || (ver.patch == patch && self.pre_is_compatible(ver)))
+- }
+- } else {
+- ver.minor > minor ||
+- (ver.minor == minor &&
+- (ver.patch > patch || (ver.patch == patch && self.pre_is_compatible(ver))))
+- }
+- }
+- None => {
+- if self.major == 0 {
+- ver.minor == minor
+- } else {
+- ver.minor >= minor
+- }
+- }
+- }
+- }
+-
+- fn pre_is_compatible(&self, ver: &Version) -> bool {
+- ver.pre.is_empty() || ver.pre >= self.pre
+- }
+-
+- // see https://www.npmjs.org/doc/misc/semver.html for behavior
+- fn matches_wildcard(&self, ver: &Version) -> bool {
+- match self.op {
+- Wildcard(Major) => true,
+- Wildcard(Minor) => self.major == ver.major,
+- Wildcard(Patch) => {
+- match self.minor {
+- Some(minor) => self.major == ver.major && minor == ver.minor,
+- None => {
+- // minor and patch version astericks mean match on major
+- self.major == ver.major
+- }
+- }
+- }
+- _ => false, // unreachable
+- }
+- }
+-}
+-
+-impl fmt::Display for VersionReq {
+- fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+- if self.predicates.is_empty() {
+- try!(write!(fmt, "*"));
+- } else {
+- for (i, ref pred) in self.predicates.iter().enumerate() {
+- if i == 0 {
+- try!(write!(fmt, "{}", pred));
+- } else {
+- try!(write!(fmt, ", {}", pred));
+- }
+- }
+- }
+-
+- Ok(())
+- }
+-}
+-
+-impl fmt::Display for Predicate {
+- fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+- match self.op {
+- Wildcard(Major) => try!(write!(fmt, "*")),
+- Wildcard(Minor) => try!(write!(fmt, "{}.*", self.major)),
+- Wildcard(Patch) => {
+- if let Some(minor) = self.minor {
+- try!(write!(fmt, "{}.{}.*", self.major, minor))
+- } else {
+- try!(write!(fmt, "{}.*.*", self.major))
+- }
+- }
+- _ => {
+- try!(write!(fmt, "{}{}", self.op, self.major));
+-
+- match self.minor {
+- Some(v) => try!(write!(fmt, ".{}", v)),
+- None => (),
+- }
+-
+- match self.patch {
+- Some(v) => try!(write!(fmt, ".{}", v)),
+- None => (),
+- }
+-
+- if !self.pre.is_empty() {
+- try!(write!(fmt, "-"));
+- for (i, x) in self.pre.iter().enumerate() {
+- if i != 0 {
+- try!(write!(fmt, "."))
+- }
+- try!(write!(fmt, "{}", x));
+- }
+- }
+- }
+- }
+-
+- Ok(())
+- }
+-}
+-
+-impl fmt::Display for Op {
+- fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+- match *self {
+- Ex => try!(write!(fmt, "= ")),
+- Gt => try!(write!(fmt, "> ")),
+- GtEq => try!(write!(fmt, ">= ")),
+- Lt => try!(write!(fmt, "< ")),
+- LtEq => try!(write!(fmt, "<= ")),
+- Tilde => try!(write!(fmt, "~")),
+- Compatible => try!(write!(fmt, "^")),
+- // gets handled specially in Predicate::fmt
+- Wildcard(_) => try!(write!(fmt, "")),
+- }
+- Ok(())
+- }
+-}
+-
+-#[cfg(test)]
+-mod test {
+- use super::{VersionReq, Op};
+- use super::super::version::Version;
+- use std::hash::{Hash, Hasher};
+-
+- fn req(s: &str) -> VersionReq {
+- VersionReq::parse(s).unwrap()
+- }
+-
+- fn version(s: &str) -> Version {
+- match Version::parse(s) {
+- Ok(v) => v,
+- Err(e) => panic!("`{}` is not a valid version. Reason: {:?}", s, e),
+- }
+- }
+-
+- fn assert_match(req: &VersionReq, vers: &[&str]) {
+- for ver in vers.iter() {
+- assert!(req.matches(&version(*ver)), "did not match {}", ver);
+- }
+- }
+-
+- fn assert_not_match(req: &VersionReq, vers: &[&str]) {
+- for ver in vers.iter() {
+- assert!(!req.matches(&version(*ver)), "matched {}", ver);
+- }
+- }
+-
+- fn calculate_hash<T: Hash>(t: T) -> u64 {
+- use std::collections::hash_map::DefaultHasher;
+-
+- let mut s = DefaultHasher::new();
+- t.hash(&mut s);
+- s.finish()
+- }
+-
+- #[test]
+- fn test_parsing_default() {
+- let r = req("1.0.0");
+-
+- assert_eq!(r.to_string(), "^1.0.0".to_string());
+-
+- assert_match(&r, &["1.0.0", "1.0.1"]);
+- assert_not_match(&r, &["0.9.9", "0.10.0", "0.1.0"]);
+- }
+-
+- #[test]
+- fn test_parsing_exact() {
+- let r = req("=1.0.0");
+-
+- assert!(r.to_string() == "= 1.0.0".to_string());
+- assert_eq!(r.to_string(), "= 1.0.0".to_string());
+-
+- assert_match(&r, &["1.0.0"]);
+- assert_not_match(&r, &["1.0.1", "0.9.9", "0.10.0", "0.1.0", "1.0.0-pre"]);
+-
+- let r = req("=0.9.0");
+-
+- assert_eq!(r.to_string(), "= 0.9.0".to_string());
+-
+- assert_match(&r, &["0.9.0"]);
+- assert_not_match(&r, &["0.9.1", "1.9.0", "0.0.9"]);
+-
+- let r = req("=0.1.0-beta2.a");
+-
+- assert_eq!(r.to_string(), "= 0.1.0-beta2.a".to_string());
+-
+- assert_match(&r, &["0.1.0-beta2.a"]);
+- assert_not_match(&r, &["0.9.1", "0.1.0", "0.1.1-beta2.a", "0.1.0-beta2"]);
+- }
+-
+- #[test]
+- fn test_parse_metadata_see_issue_88_see_issue_88() {
+- for op in &[Op::Compatible, Op::Ex, Op::Gt, Op::GtEq, Op::Lt, Op::LtEq, Op::Tilde] {
+- req(&format!("{} 1.2.3+meta", op));
+- }
+- }
+-
+- #[test]
+- pub fn test_parsing_greater_than() {
+- let r = req(">= 1.0.0");
+-
+- assert_eq!(r.to_string(), ">= 1.0.0".to_string());
+-
+- assert_match(&r, &["1.0.0", "2.0.0"]);
+- assert_not_match(&r, &["0.1.0", "0.0.1", "1.0.0-pre", "2.0.0-pre"]);
+-
+- let r = req(">= 2.1.0-alpha2");
+-
+- assert_match(&r, &["2.1.0-alpha2", "2.1.0-alpha3", "2.1.0", "3.0.0"]);
+- assert_not_match(&r,
+- &["2.0.0", "2.1.0-alpha1", "2.0.0-alpha2", "3.0.0-alpha2"]);
+- }
+-
+- #[test]
+- pub fn test_parsing_less_than() {
+- let r = req("< 1.0.0");
+-
+- assert_eq!(r.to_string(), "< 1.0.0".to_string());
+-
+- assert_match(&r, &["0.1.0", "0.0.1"]);
+- assert_not_match(&r, &["1.0.0", "1.0.0-beta", "1.0.1", "0.9.9-alpha"]);
+-
+- let r = req("<= 2.1.0-alpha2");
+-
+- assert_match(&r, &["2.1.0-alpha2", "2.1.0-alpha1", "2.0.0", "1.0.0"]);
+- assert_not_match(&r,
+- &["2.1.0", "2.2.0-alpha1", "2.0.0-alpha2", "1.0.0-alpha2"]);
+- }
+-
+- #[test]
+- pub fn test_multiple() {
+- let r = req("> 0.0.9, <= 2.5.3");
+- assert_eq!(r.to_string(), "> 0.0.9, <= 2.5.3".to_string());
+- assert_match(&r, &["0.0.10", "1.0.0", "2.5.3"]);
+- assert_not_match(&r, &["0.0.8", "2.5.4"]);
+-
+- let r = req("0.3.0, 0.4.0");
+- assert_eq!(r.to_string(), "^0.3.0, ^0.4.0".to_string());
+- assert_not_match(&r, &["0.0.8", "0.3.0", "0.4.0"]);
+-
+- let r = req("<= 0.2.0, >= 0.5.0");
+- assert_eq!(r.to_string(), "<= 0.2.0, >= 0.5.0".to_string());
+- assert_not_match(&r, &["0.0.8", "0.3.0", "0.5.1"]);
+-
+- let r = req("0.1.0, 0.1.4, 0.1.6");
+- assert_eq!(r.to_string(), "^0.1.0, ^0.1.4, ^0.1.6".to_string());
+- assert_match(&r, &["0.1.6", "0.1.9"]);
+- assert_not_match(&r, &["0.1.0", "0.1.4", "0.2.0"]);
+-
+- assert!(VersionReq::parse("> 0.1.0,").is_err());
+- assert!(VersionReq::parse("> 0.3.0, ,").is_err());
+-
+- let r = req(">=0.5.1-alpha3, <0.6");
+- assert_eq!(r.to_string(), ">= 0.5.1-alpha3, < 0.6".to_string());
+- assert_match(&r,
+- &["0.5.1-alpha3", "0.5.1-alpha4", "0.5.1-beta", "0.5.1", "0.5.5"]);
+- assert_not_match(&r,
+- &["0.5.1-alpha1", "0.5.2-alpha3", "0.5.5-pre", "0.5.0-pre"]);
+- assert_not_match(&r, &["0.6.0", "0.6.0-pre"]);
+- }
+-
+- #[test]
+- pub fn test_parsing_tilde() {
+- let r = req("~1");
+- assert_match(&r, &["1.0.0", "1.0.1", "1.1.1"]);
+- assert_not_match(&r, &["0.9.1", "2.9.0", "0.0.9"]);
+-
+- let r = req("~1.2");
+- assert_match(&r, &["1.2.0", "1.2.1"]);
+- assert_not_match(&r, &["1.1.1", "1.3.0", "0.0.9"]);
+-
+- let r = req("~1.2.2");
+- assert_match(&r, &["1.2.2", "1.2.4"]);
+- assert_not_match(&r, &["1.2.1", "1.9.0", "1.0.9", "2.0.1", "0.1.3"]);
+-
+- let r = req("~1.2.3-beta.2");
+- assert_match(&r, &["1.2.3", "1.2.4", "1.2.3-beta.2", "1.2.3-beta.4"]);
+- assert_not_match(&r, &["1.3.3", "1.1.4", "1.2.3-beta.1", "1.2.4-beta.2"]);
+- }
+-
+- #[test]
+- pub fn test_parsing_compatible() {
+- let r = req("^1");
+- assert_match(&r, &["1.1.2", "1.1.0", "1.2.1", "1.0.1"]);
+- assert_not_match(&r, &["0.9.1", "2.9.0", "0.1.4"]);
+- assert_not_match(&r, &["1.0.0-beta1", "0.1.0-alpha", "1.0.1-pre"]);
+-
+- let r = req("^1.1");
+- assert_match(&r, &["1.1.2", "1.1.0", "1.2.1"]);
+- assert_not_match(&r, &["0.9.1", "2.9.0", "1.0.1", "0.1.4"]);
+-
+- let r = req("^1.1.2");
+- assert_match(&r, &["1.1.2", "1.1.4", "1.2.1"]);
+- assert_not_match(&r, &["0.9.1", "2.9.0", "1.1.1", "0.0.1"]);
+- assert_not_match(&r, &["1.1.2-alpha1", "1.1.3-alpha1", "2.9.0-alpha1"]);
+-
+- let r = req("^0.1.2");
+- assert_match(&r, &["0.1.2", "0.1.4"]);
+- assert_not_match(&r, &["0.9.1", "2.9.0", "1.1.1", "0.0.1"]);
+- assert_not_match(&r, &["0.1.2-beta", "0.1.3-alpha", "0.2.0-pre"]);
+-
+- let r = req("^0.5.1-alpha3");
+- assert_match(&r,
+- &["0.5.1-alpha3", "0.5.1-alpha4", "0.5.1-beta", "0.5.1", "0.5.5"]);
+- assert_not_match(&r,
+- &["0.5.1-alpha1", "0.5.2-alpha3", "0.5.5-pre", "0.5.0-pre", "0.6.0"]);
+-
+- let r = req("^0.0.2");
+- assert_match(&r, &["0.0.2"]);
+- assert_not_match(&r, &["0.9.1", "2.9.0", "1.1.1", "0.0.1", "0.1.4"]);
+-
+- let r = req("^0.0");
+- assert_match(&r, &["0.0.2", "0.0.0"]);
+- assert_not_match(&r, &["0.9.1", "2.9.0", "1.1.1", "0.1.4"]);
+-
+- let r = req("^0");
+- assert_match(&r, &["0.9.1", "0.0.2", "0.0.0"]);
+- assert_not_match(&r, &["2.9.0", "1.1.1"]);
+-
+- let r = req("^1.4.2-beta.5");
+- assert_match(&r,
+- &["1.4.2", "1.4.3", "1.4.2-beta.5", "1.4.2-beta.6", "1.4.2-c"]);
+- assert_not_match(&r,
+- &["0.9.9", "2.0.0", "1.4.2-alpha", "1.4.2-beta.4", "1.4.3-beta.5"]);
+- }
+-
+- #[test]
+- pub fn test_parsing_wildcard() {
+- let r = req("");
+- assert_match(&r, &["0.9.1", "2.9.0", "0.0.9", "1.0.1", "1.1.1"]);
+- assert_not_match(&r, &[]);
+- let r = req("*");
+- assert_match(&r, &["0.9.1", "2.9.0", "0.0.9", "1.0.1", "1.1.1"]);
+- assert_not_match(&r, &[]);
+- let r = req("x");
+- assert_match(&r, &["0.9.1", "2.9.0", "0.0.9", "1.0.1", "1.1.1"]);
+- assert_not_match(&r, &[]);
+- let r = req("X");
+- assert_match(&r, &["0.9.1", "2.9.0", "0.0.9", "1.0.1", "1.1.1"]);
+- assert_not_match(&r, &[]);
+-
+- let r = req("1.*");
+- assert_match(&r, &["1.2.0", "1.2.1", "1.1.1", "1.3.0"]);
+- assert_not_match(&r, &["0.0.9"]);
+- let r = req("1.x");
+- assert_match(&r, &["1.2.0", "1.2.1", "1.1.1", "1.3.0"]);
+- assert_not_match(&r, &["0.0.9"]);
+- let r = req("1.X");
+- assert_match(&r, &["1.2.0", "1.2.1", "1.1.1", "1.3.0"]);
+- assert_not_match(&r, &["0.0.9"]);
+-
+- let r = req("1.2.*");
+- assert_match(&r, &["1.2.0", "1.2.2", "1.2.4"]);
+- assert_not_match(&r, &["1.9.0", "1.0.9", "2.0.1", "0.1.3"]);
+- let r = req("1.2.x");
+- assert_match(&r, &["1.2.0", "1.2.2", "1.2.4"]);
+- assert_not_match(&r, &["1.9.0", "1.0.9", "2.0.1", "0.1.3"]);
+- let r = req("1.2.X");
+- assert_match(&r, &["1.2.0", "1.2.2", "1.2.4"]);
+- assert_not_match(&r, &["1.9.0", "1.0.9", "2.0.1", "0.1.3"]);
+- }
+-
+- #[test]
+- pub fn test_any() {
+- let r = VersionReq::any();
+- assert_match(&r, &["0.0.1", "0.1.0", "1.0.0"]);
+- }
+-
+- #[test]
+- pub fn test_pre() {
+- let r = req("=2.1.1-really.0");
+- assert_match(&r, &["2.1.1-really.0"]);
+- }
+-
+- // #[test]
+- // pub fn test_parse_errors() {
+- // assert_eq!(Err(InvalidVersionRequirement), VersionReq::parse("\0"));
+- // assert_eq!(Err(OpAlreadySet), VersionReq::parse(">= >= 0.0.2"));
+- // assert_eq!(Err(InvalidSigil), VersionReq::parse(">== 0.0.2"));
+- // assert_eq!(Err(VersionComponentsMustBeNumeric),
+- // VersionReq::parse("a.0.0"));
+- // assert_eq!(Err(InvalidIdentifier), VersionReq::parse("1.0.0-"));
+- // assert_eq!(Err(MajorVersionRequired), VersionReq::parse(">="));
+- // }
+-
+- #[test]
+- pub fn test_from_str() {
+- assert_eq!("1.0.0".parse::<VersionReq>().unwrap().to_string(),
+- "^1.0.0".to_string());
+- assert_eq!("=1.0.0".parse::<VersionReq>().unwrap().to_string(),
+- "= 1.0.0".to_string());
+- assert_eq!("~1".parse::<VersionReq>().unwrap().to_string(),
+- "~1".to_string());
+- assert_eq!("~1.2".parse::<VersionReq>().unwrap().to_string(),
+- "~1.2".to_string());
+- assert_eq!("^1".parse::<VersionReq>().unwrap().to_string(),
+- "^1".to_string());
+- assert_eq!("^1.1".parse::<VersionReq>().unwrap().to_string(),
+- "^1.1".to_string());
+- assert_eq!("*".parse::<VersionReq>().unwrap().to_string(),
+- "*".to_string());
+- assert_eq!("1.*".parse::<VersionReq>().unwrap().to_string(),
+- "1.*".to_string());
+- assert_eq!("< 1.0.0".parse::<VersionReq>().unwrap().to_string(),
+- "< 1.0.0".to_string());
+- }
+-
+- // #[test]
+- // pub fn test_from_str_errors() {
+- // assert_eq!(Err(InvalidVersionRequirement), "\0".parse::<VersionReq>());
+- // assert_eq!(Err(OpAlreadySet), ">= >= 0.0.2".parse::<VersionReq>());
+- // assert_eq!(Err(InvalidSigil), ">== 0.0.2".parse::<VersionReq>());
+- // assert_eq!(Err(VersionComponentsMustBeNumeric),
+- // "a.0.0".parse::<VersionReq>());
+- // assert_eq!(Err(InvalidIdentifier), "1.0.0-".parse::<VersionReq>());
+- // assert_eq!(Err(MajorVersionRequired), ">=".parse::<VersionReq>());
+- // }
+-
+- #[test]
+- fn test_cargo3202() {
+- let v = "0.*.*".parse::<VersionReq>().unwrap();
+- assert_eq!("0.*.*", format!("{}", v.predicates[0]));
+-
+- let v = "0.0.*".parse::<VersionReq>().unwrap();
+- assert_eq!("0.0.*", format!("{}", v.predicates[0]));
+-
+- let r = req("0.*.*");
+- assert_match(&r, &["0.5.0"]);
+- }
+-
+- #[test]
+- fn test_eq_hash() {
+- assert!(req("^1") == req("^1"));
+- assert!(calculate_hash(req("^1")) == calculate_hash(req("^1")));
+- assert!(req("^1") != req("^2"));
+- }
+-
+- #[test]
+- fn test_ordering() {
+- assert!(req("=1") < req("*"));
+- assert!(req(">1") < req("*"));
+- assert!(req(">=1") < req("*"));
+- assert!(req("<1") < req("*"));
+- assert!(req("<=1") < req("*"));
+- assert!(req("~1") < req("*"));
+- assert!(req("^1") < req("*"));
+- assert!(req("*") == req("*"));
+- }
+-}
+diff --git a/third_party/rust/semver/tests/deprecation.rs b/third_party/rust/semver/tests/deprecation.rs
+deleted file mode 100644
+--- a/third_party/rust/semver/tests/deprecation.rs
++++ /dev/null
+@@ -1,22 +0,0 @@
+-extern crate semver;
+-
+-#[test]
+-fn test_regressions() {
+- use semver::VersionReq;
+- use semver::ReqParseError;
+-
+- let versions = vec![
+- (".*", VersionReq::any()),
+- ("0.1.0.", VersionReq::parse("0.1.0").unwrap()),
+- ("0.3.1.3", VersionReq::parse("0.3.13").unwrap()),
+- ("0.2*", VersionReq::parse("0.2.*").unwrap()),
+- ("*.0", VersionReq::any()),
+- ];
+-
+- for (version, requirement) in versions.into_iter() {
+- let parsed = VersionReq::parse(version);
+- let error = parsed.err().unwrap();
+-
+- assert_eq!(ReqParseError::DeprecatedVersionRequirement(requirement), error);
+- }
+-}
+diff --git a/third_party/rust/semver/tests/node/mod.rs b/third_party/rust/semver/tests/node/mod.rs
+new file mode 100644
+--- /dev/null
++++ b/third_party/rust/semver/tests/node/mod.rs
+@@ -0,0 +1,43 @@
++#![cfg(test_node_semver)]
++
++use semver::Version;
++use std::fmt::{self, Display};
++use std::process::Command;
++
++#[derive(Default, Eq, PartialEq, Hash, Debug)]
++pub(super) struct VersionReq(semver::VersionReq);
++
++impl VersionReq {
++ pub(super) const STAR: Self = VersionReq(semver::VersionReq::STAR);
++
++ pub(super) fn matches(&self, version: &Version) -> bool {
++ let out = Command::new("node")
++ .arg("-e")
++ .arg(format!(
++ "console.log(require('semver').satisfies('{}', '{}'))",
++ version,
++ self.to_string().replace(',', ""),
++ ))
++ .output()
++ .unwrap();
++ if out.stdout == b"true\n" {
++ true
++ } else if out.stdout == b"false\n" {
++ false
++ } else {
++ let s = String::from_utf8_lossy(&out.stdout) + String::from_utf8_lossy(&out.stderr);
++ panic!("unexpected output: {}", s);
++ }
++ }
++}
++
++impl Display for VersionReq {
++ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
++ Display::fmt(&self.0, formatter)
++ }
++}
++
++#[cfg_attr(not(no_track_caller), track_caller)]
++pub(super) fn req(text: &str) -> VersionReq {
++ VersionReq(crate::util::req(text))
++}
+diff --git a/third_party/rust/semver/tests/regression.rs b/third_party/rust/semver/tests/regression.rs
+deleted file mode 100644
+--- a/third_party/rust/semver/tests/regression.rs
++++ /dev/null
+@@ -1,25 +0,0 @@
+-extern crate semver;
+-extern crate crates_index;
+-extern crate tempdir;
+-
+-// This test checks to see if every existing crate parses successfully. Important to not break the
+-// Rust universe!
+-
+-#[cfg(feature = "ci")]
+-#[test]
+-fn test_regressions() {
+- use tempdir::TempDir;
+- use crates_index::Index;
+- use semver::Version;
+-
+- let dir = TempDir::new("semver").unwrap();
+- let index = Index::new(dir.into_path());
+- index.clone().unwrap();
+-
+- for krate in index.crates() {
+- for version in krate.versions() {
+- let v = version.version();
+- assert!(Version::parse(v).is_ok(), "failed: {} ({})", version.name(), v);
+- }
+- }
+-}
+diff --git a/third_party/rust/semver/tests/serde.rs b/third_party/rust/semver/tests/serde.rs
+deleted file mode 100644
+--- a/third_party/rust/semver/tests/serde.rs
++++ /dev/null
+@@ -1,90 +0,0 @@
+-#![cfg(feature = "serde")]
+-
+-#[macro_use]
+-extern crate serde_derive;
+-
+-extern crate semver;
+-extern crate serde_json;
+-
+-use semver::{Identifier, Version, VersionReq};
+-
+-#[derive(Serialize, Deserialize, PartialEq, Debug)]
+-struct Identified {
+- name: String,
+- identifier: Identifier,
+-}
+-
+-#[derive(Serialize, Deserialize, PartialEq, Debug)]
+-struct Versioned {
+- name: String,
+- vers: Version,
+-}
+-
+-#[test]
+-fn serialize_identifier() {
+- let id = Identified {
+- name: "serde".to_owned(),
+- identifier: Identifier::Numeric(100),
+- };
+- let j = serde_json::to_string(&id).unwrap();
+- assert_eq!(j, r#"{"name":"serde","identifier":100}"#);
+-
+- let id = Identified {
+- name: "serde".to_owned(),
+- identifier: Identifier::AlphaNumeric("b100".to_owned()),
+- };
+- let j = serde_json::to_string(&id).unwrap();
+- assert_eq!(j, r#"{"name":"serde","identifier":"b100"}"#);
+-}
+-
+-#[test]
+-fn deserialize_identifier() {
+- let j = r#"{"name":"serde","identifier":100}"#;
+- let id = serde_json::from_str::<Identified>(j).unwrap();
+- let expected = Identified {
+- name: "serde".to_owned(),
+- identifier: Identifier::Numeric(100),
+- };
+- assert_eq!(id, expected);
+-
+- let j = r#"{"name":"serde","identifier":"b100"}"#;
+- let id = serde_json::from_str::<Identified>(j).unwrap();
+- let expected = Identified {
+- name: "serde".to_owned(),
+- identifier: Identifier::AlphaNumeric("b100".to_owned()),
+- };
+- assert_eq!(id, expected);
+-}
+-
+-#[test]
+-fn serialize_version() {
+- let v = Versioned {
+- name: "serde".to_owned(),
+- vers: Version::parse("1.0.0").unwrap(),
+- };
+- let j = serde_json::to_string(&v).unwrap();
+- assert_eq!(j, r#"{"name":"serde","vers":"1.0.0"}"#);
+-}
+-
+-#[test]
+-fn deserialize_version() {
+- let j = r#"{"name":"serde","vers":"1.0.0"}"#;
+- let v = serde_json::from_str::<Versioned>(j).unwrap();
+- let expected = Versioned {
+- name: "serde".to_owned(),
+- vers: Version::parse("1.0.0").unwrap(),
+- };
+- assert_eq!(v, expected);
+-}
+-
+-#[test]
+-fn serialize_versionreq() {
+- let v = VersionReq::exact(&Version::parse("1.0.0").unwrap());
+-
+- assert_eq!(serde_json::to_string(&v).unwrap(), r#""= 1.0.0""#);
+-}
+-
+-#[test]
+-fn deserialize_versionreq() {
+- assert_eq!("1.0.0".parse::<VersionReq>().unwrap(), serde_json::from_str(r#""1.0.0""#).unwrap());
+-}
+diff --git a/third_party/rust/semver/tests/test_autotrait.rs b/third_party/rust/semver/tests/test_autotrait.rs
+new file mode 100644
+--- /dev/null
++++ b/third_party/rust/semver/tests/test_autotrait.rs
+@@ -0,0 +1,12 @@
++fn assert_send_sync<T: Send + Sync>() {}
++
++#[test]
++fn test() {
++ assert_send_sync::<semver::BuildMetadata>();
++ assert_send_sync::<semver::Comparator>();
++ assert_send_sync::<semver::Error>();
++ assert_send_sync::<semver::Prerelease>();
++ assert_send_sync::<semver::Version>();
++ assert_send_sync::<semver::VersionReq>();
++ assert_send_sync::<semver::Op>();
++}
+diff --git a/third_party/rust/semver/tests/test_identifier.rs b/third_party/rust/semver/tests/test_identifier.rs
+new file mode 100644
+--- /dev/null
++++ b/third_party/rust/semver/tests/test_identifier.rs
+@@ -0,0 +1,45 @@
++#![allow(
++ clippy::eq_op,
++ clippy::needless_pass_by_value,
++ clippy::toplevel_ref_arg,
++ clippy::wildcard_imports
++)]
++
++mod util;
++
++use crate::util::*;
++use semver::Prerelease;
++
++#[test]
++fn test_new() {
++ fn test(identifier: Prerelease, expected: &str) {
++ assert_eq!(identifier.is_empty(), expected.is_empty());
++ assert_eq!(identifier.len(), expected.len());
++ assert_eq!(identifier.as_str(), expected);
++ assert_eq!(identifier, identifier);
++ assert_eq!(identifier, identifier.clone());
++ }
++
++ let ref mut string = String::new();
++ let limit = if cfg!(miri) { 40 } else { 280 }; // miri is slow
++ for _ in 0..limit {
++ test(prerelease(string), string);
++ string.push('1');
++ }
++
++ if !cfg!(miri) {
++ let ref string = string.repeat(20000);
++ test(prerelease(string), string);
++ }
++}
++
++#[test]
++fn test_eq() {
++ assert_eq!(prerelease("-"), prerelease("-"));
++ assert_ne!(prerelease("a"), prerelease("aa"));
++ assert_ne!(prerelease("aa"), prerelease("a"));
++ assert_ne!(prerelease("aaaaaaaaa"), prerelease("a"));
++ assert_ne!(prerelease("a"), prerelease("aaaaaaaaa"));
++ assert_ne!(prerelease("aaaaaaaaa"), prerelease("bbbbbbbbb"));
++ assert_ne!(build_metadata("1"), build_metadata("001"));
++}
+diff --git a/third_party/rust/semver/tests/test_version.rs b/third_party/rust/semver/tests/test_version.rs
+new file mode 100644
+--- /dev/null
++++ b/third_party/rust/semver/tests/test_version.rs
+@@ -0,0 +1,241 @@
++#![allow(
++ clippy::nonminimal_bool,
++ clippy::too_many_lines,
++ clippy::wildcard_imports
++)]
++
++mod util;
++
++use crate::util::*;
++use semver::{BuildMetadata, Prerelease, Version};
++
++#[test]
++fn test_parse() {
++ let err = version_err("");
++ assert_to_string(
++ err,
++ "unexpected end of input while parsing major version number",
++ );
++
++ let err = version_err(" ");
++ assert_to_string(
++ err,
++ "unexpected character ' ' while parsing major version number",
++ );
++
++ let err = version_err("1");
++ assert_to_string(
++ err,
++ "unexpected end of input while parsing major version number",
++ );
++
++ let err = version_err("1.2");
++ assert_to_string(
++ err,
++ "unexpected end of input while parsing minor version number",
++ );
++
++ let err = version_err("1.2.3-");
++ assert_to_string(err, "empty identifier segment in pre-release identifier");
++
++ let err = version_err("a.b.c");
++ assert_to_string(
++ err,
++ "unexpected character 'a' while parsing major version number",
++ );
++
++ let err = version_err("1.2.3 abc");
++ assert_to_string(err, "unexpected character ' ' after patch version number");
++
++ let err = version_err("1.2.3-01");
++ assert_to_string(err, "invalid leading zero in pre-release identifier");
++
++ let parsed = version("1.2.3");
++ let expected = Version::new(1, 2, 3);
++ assert_eq!(parsed, expected);
++ let expected = Version {
++ major: 1,
++ minor: 2,
++ patch: 3,
++ pre: Prerelease::EMPTY,
++ build: BuildMetadata::EMPTY,
++ };
++ assert_eq!(parsed, expected);
++
++ let parsed = version("1.2.3-alpha1");
++ let expected = Version {
++ major: 1,
++ minor: 2,
++ patch: 3,
++ pre: prerelease("alpha1"),
++ build: BuildMetadata::EMPTY,
++ };
++ assert_eq!(parsed, expected);
++
++ let parsed = version("1.2.3+build5");
++ let expected = Version {
++ major: 1,
++ minor: 2,
++ patch: 3,
++ pre: Prerelease::EMPTY,
++ build: build_metadata("build5"),
++ };
++ assert_eq!(parsed, expected);
++
++ let parsed = version("1.2.3+5build");
++ let expected = Version {
++ major: 1,
++ minor: 2,
++ patch: 3,
++ pre: Prerelease::EMPTY,
++ build: build_metadata("5build"),
++ };
++ assert_eq!(parsed, expected);
++
++ let parsed = version("1.2.3-alpha1+build5");
++ let expected = Version {
++ major: 1,
++ minor: 2,
++ patch: 3,
++ pre: prerelease("alpha1"),
++ build: build_metadata("build5"),
++ };
++ assert_eq!(parsed, expected);
++
++ let parsed = version("1.2.3-1.alpha1.9+build5.7.3aedf");
++ let expected = Version {
++ major: 1,
++ minor: 2,
++ patch: 3,
++ pre: prerelease("1.alpha1.9"),
++ build: build_metadata("build5.7.3aedf"),
++ };
++ assert_eq!(parsed, expected);
++
++ let parsed = version("1.2.3-0a.alpha1.9+05build.7.3aedf");
++ let expected = Version {
++ major: 1,
++ minor: 2,
++ patch: 3,
++ pre: prerelease("0a.alpha1.9"),
++ build: build_metadata("05build.7.3aedf"),
++ };
++ assert_eq!(parsed, expected);
++
++ let parsed = version("0.4.0-beta.1+0851523");
++ let expected = Version {
++ major: 0,
++ minor: 4,
++ patch: 0,
++ pre: prerelease("beta.1"),
++ build: build_metadata("0851523"),
++ };
++ assert_eq!(parsed, expected);
++
++ // for https://nodejs.org/dist/index.json, where some older npm versions are "1.1.0-beta-10"
++ let parsed = version("1.1.0-beta-10");
++ let expected = Version {
++ major: 1,
++ minor: 1,
++ patch: 0,
++ pre: prerelease("beta-10"),
++ build: BuildMetadata::EMPTY,
++ };
++ assert_eq!(parsed, expected);
++}
++
++#[test]
++fn test_eq() {
++ assert_eq!(version("1.2.3"), version("1.2.3"));
++ assert_eq!(version("1.2.3-alpha1"), version("1.2.3-alpha1"));
++ assert_eq!(version("1.2.3+build.42"), version("1.2.3+build.42"));
++ assert_eq!(version("1.2.3-alpha1+42"), version("1.2.3-alpha1+42"));
++}
++
++#[test]
++fn test_ne() {
++ assert_ne!(version("0.0.0"), version("0.0.1"));
++ assert_ne!(version("0.0.0"), version("0.1.0"));
++ assert_ne!(version("0.0.0"), version("1.0.0"));
++ assert_ne!(version("1.2.3-alpha"), version("1.2.3-beta"));
++ assert_ne!(version("1.2.3+23"), version("1.2.3+42"));
++}
++
++#[test]
++fn test_display() {
++ assert_to_string(version("1.2.3"), "1.2.3");
++ assert_to_string(version("1.2.3-alpha1"), "1.2.3-alpha1");
++ assert_to_string(version("1.2.3+build.42"), "1.2.3+build.42");
++ assert_to_string(version("1.2.3-alpha1+42"), "1.2.3-alpha1+42");
++}
++
++#[test]
++fn test_lt() {
++ assert!(version("0.0.0") < version("1.2.3-alpha2"));
++ assert!(version("1.0.0") < version("1.2.3-alpha2"));
++ assert!(version("1.2.0") < version("1.2.3-alpha2"));
++ assert!(version("1.2.3-alpha1") < version("1.2.3"));
++ assert!(version("1.2.3-alpha1") < version("1.2.3-alpha2"));
++ assert!(!(version("1.2.3-alpha2") < version("1.2.3-alpha2")));
++ assert!(version("1.2.3+23") < version("1.2.3+42"));
++}
++
++#[test]
++fn test_le() {
++ assert!(version("0.0.0") <= version("1.2.3-alpha2"));
++ assert!(version("1.0.0") <= version("1.2.3-alpha2"));
++ assert!(version("1.2.0") <= version("1.2.3-alpha2"));
++ assert!(version("1.2.3-alpha1") <= version("1.2.3-alpha2"));
++ assert!(version("1.2.3-alpha2") <= version("1.2.3-alpha2"));
++ assert!(version("1.2.3+23") <= version("1.2.3+42"));
++}
++
++#[test]
++fn test_gt() {
++ assert!(version("1.2.3-alpha2") > version("0.0.0"));
++ assert!(version("1.2.3-alpha2") > version("1.0.0"));
++ assert!(version("1.2.3-alpha2") > version("1.2.0"));
++ assert!(version("1.2.3-alpha2") > version("1.2.3-alpha1"));
++ assert!(version("1.2.3") > version("1.2.3-alpha2"));
++ assert!(!(version("1.2.3-alpha2") > version("1.2.3-alpha2")));
++ assert!(!(version("1.2.3+23") > version("1.2.3+42")));
++}
++
++#[test]
++fn test_ge() {
++ assert!(version("1.2.3-alpha2") >= version("0.0.0"));
++ assert!(version("1.2.3-alpha2") >= version("1.0.0"));
++ assert!(version("1.2.3-alpha2") >= version("1.2.0"));
++ assert!(version("1.2.3-alpha2") >= version("1.2.3-alpha1"));
++ assert!(version("1.2.3-alpha2") >= version("1.2.3-alpha2"));
++ assert!(!(version("1.2.3+23") >= version("1.2.3+42")));
++}
++
++#[test]
++fn test_spec_order() {
++ let vs = [
++ "1.0.0-alpha",
++ "1.0.0-alpha.1",
++ "1.0.0-alpha.beta",
++ "1.0.0-beta",
++ "1.0.0-beta.2",
++ "1.0.0-beta.11",
++ "1.0.0-rc.1",
++ "1.0.0",
++ ];
++ let mut i = 1;
++ while i < vs.len() {
++ let a = version(vs[i - 1]);
++ let b = version(vs[i]);
++ assert!(a < b, "nope {:?} < {:?}", a, b);
++ i += 1;
++ }
++}
++
++#[test]
++fn test_align() {
++ let version = version("1.2.3-rc1");
++ assert_eq!("1.2.3-rc1 ", format!("{:20}", version));
++ assert_eq!("*****1.2.3-rc1******", format!("{:*^20}", version));
++ assert_eq!(" 1.2.3-rc1", format!("{:>20}", version));
++}
+diff --git a/third_party/rust/semver/tests/test_version_req.rs b/third_party/rust/semver/tests/test_version_req.rs
+new file mode 100644
+--- /dev/null
++++ b/third_party/rust/semver/tests/test_version_req.rs
+@@ -0,0 +1,443 @@
++#![allow(
++ clippy::missing_panics_doc,
++ clippy::shadow_unrelated,
++ clippy::toplevel_ref_arg,
++ clippy::wildcard_imports
++)]
++
++mod node;
++mod util;
++
++use crate::util::*;
++use std::collections::hash_map::DefaultHasher;
++use std::hash::{Hash, Hasher};
++
++#[cfg(test_node_semver)]
++use node::{req, VersionReq};
++#[cfg(not(test_node_semver))]
++use semver::VersionReq;
++
++#[cfg_attr(not(no_track_caller), track_caller)]
++fn assert_match_all(req: &VersionReq, versions: &[&str]) {
++ for string in versions {
++ let parsed = version(string);
++ assert!(req.matches(&parsed), "did not match {}", string);
++ }
++}
++
++#[cfg_attr(not(no_track_caller), track_caller)]
++fn assert_match_none(req: &VersionReq, versions: &[&str]) {
++ for string in versions {
++ let parsed = version(string);
++ assert!(!req.matches(&parsed), "matched {}", string);
++ }
++}
++
++#[test]
++fn test_basic() {
++ let ref r = req("1.0.0");
++ assert_to_string(r, "^1.0.0");
++ assert_match_all(r, &["1.0.0", "1.1.0", "1.0.1"]);
++ assert_match_none(r, &["0.9.9", "0.10.0", "0.1.0", "1.0.0-pre", "1.0.1-pre"]);
++}
++
++#[test]
++#[cfg(not(no_const_vec_new))]
++fn test_default() {
++ let ref r = VersionReq::default();
++ assert_eq!(r, &VersionReq::STAR);
++}
++
++#[test]
++fn test_exact() {
++ let ref r = req("=1.0.0");
++ assert_to_string(r, "=1.0.0");
++ assert_match_all(r, &["1.0.0"]);
++ assert_match_none(r, &["1.0.1", "0.9.9", "0.10.0", "0.1.0", "1.0.0-pre"]);
++
++ let ref r = req("=0.9.0");
++ assert_to_string(r, "=0.9.0");
++ assert_match_all(r, &["0.9.0"]);
++ assert_match_none(r, &["0.9.1", "1.9.0", "0.0.9", "0.9.0-pre"]);
++
++ let ref r = req("=0.0.2");
++ assert_to_string(r, "=0.0.2");
++ assert_match_all(r, &["0.0.2"]);
++ assert_match_none(r, &["0.0.1", "0.0.3", "0.0.2-pre"]);
++
++ let ref r = req("=0.1.0-beta2.a");
++ assert_to_string(r, "=0.1.0-beta2.a");
++ assert_match_all(r, &["0.1.0-beta2.a"]);
++ assert_match_none(r, &["0.9.1", "0.1.0", "0.1.1-beta2.a", "0.1.0-beta2"]);
++
++ let ref r = req("=0.1.0+meta");
++ assert_to_string(r, "=0.1.0");
++ assert_match_all(r, &["0.1.0", "0.1.0+meta", "0.1.0+any"]);
++}
++
++#[test]
++pub fn test_greater_than() {
++ let ref r = req(">= 1.0.0");
++ assert_to_string(r, ">=1.0.0");
++ assert_match_all(r, &["1.0.0", "2.0.0"]);
++ assert_match_none(r, &["0.1.0", "0.0.1", "1.0.0-pre", "2.0.0-pre"]);
++
++ let ref r = req(">= 2.1.0-alpha2");
++ assert_to_string(r, ">=2.1.0-alpha2");
++ assert_match_all(r, &["2.1.0-alpha2", "2.1.0-alpha3", "2.1.0", "3.0.0"]);
++ assert_match_none(
++ r,
++ &["2.0.0", "2.1.0-alpha1", "2.0.0-alpha2", "3.0.0-alpha2"],
++ );
++}
++
++#[test]
++pub fn test_less_than() {
++ let ref r = req("< 1.0.0");
++ assert_to_string(r, "<1.0.0");
++ assert_match_all(r, &["0.1.0", "0.0.1"]);
++ assert_match_none(r, &["1.0.0", "1.0.0-beta", "1.0.1", "0.9.9-alpha"]);
++
++ let ref r = req("<= 2.1.0-alpha2");
++ assert_match_all(r, &["2.1.0-alpha2", "2.1.0-alpha1", "2.0.0", "1.0.0"]);
++ assert_match_none(
++ r,
++ &["2.1.0", "2.2.0-alpha1", "2.0.0-alpha2", "1.0.0-alpha2"],
++ );
++
++ let ref r = req(">1.0.0-alpha, <1.0.0");
++ assert_match_all(r, &["1.0.0-beta"]);
++
++ let ref r = req(">1.0.0-alpha, <1.0");
++ assert_match_none(r, &["1.0.0-beta"]);
++
++ let ref r = req(">1.0.0-alpha, <1");
++ assert_match_none(r, &["1.0.0-beta"]);
++}
++
++#[test]
++pub fn test_multiple() {
++ let ref r = req("> 0.0.9, <= 2.5.3");
++ assert_to_string(r, ">0.0.9, <=2.5.3");
++ assert_match_all(r, &["0.0.10", "1.0.0", "2.5.3"]);
++ assert_match_none(r, &["0.0.8", "2.5.4"]);
++
++ let ref r = req("0.3.0, 0.4.0");
++ assert_to_string(r, "^0.3.0, ^0.4.0");
++ assert_match_none(r, &["0.0.8", "0.3.0", "0.4.0"]);
++
++ let ref r = req("<= 0.2.0, >= 0.5.0");
++ assert_to_string(r, "<=0.2.0, >=0.5.0");
++ assert_match_none(r, &["0.0.8", "0.3.0", "0.5.1"]);
++
++ let ref r = req("0.1.0, 0.1.4, 0.1.6");
++ assert_to_string(r, "^0.1.0, ^0.1.4, ^0.1.6");
++ assert_match_all(r, &["0.1.6", "0.1.9"]);
++ assert_match_none(r, &["0.1.0", "0.1.4", "0.2.0"]);
++
++ let err = req_err("> 0.1.0,");
++ assert_to_string(
++ err,
++ "unexpected end of input while parsing major version number",
++ );
++
++ let err = req_err("> 0.3.0, ,");
++ assert_to_string(
++ err,
++ "unexpected character ',' while parsing major version number",
++ );
++
++ let ref r = req(">=0.5.1-alpha3, <0.6");
++ assert_to_string(r, ">=0.5.1-alpha3, <0.6");
++ assert_match_all(
++ r,
++ &[
++ "0.5.1-alpha3",
++ "0.5.1-alpha4",
++ "0.5.1-beta",
++ "0.5.1",
++ "0.5.5",
++ ],
++ );
++ assert_match_none(
++ r,
++ &["0.5.1-alpha1", "0.5.2-alpha3", "0.5.5-pre", "0.5.0-pre"],
++ );
++ assert_match_none(r, &["0.6.0", "0.6.0-pre"]);
++
++ // 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 '-'");
++}
++
++#[test]
++pub fn test_whitespace_delimited_comparator_sets() {
++ // https://github.com/steveklabnik/semver/issues/55
++ let err = req_err("> 0.0.9 <= 2.5.3");
++ assert_to_string(err, "expected comma after patch version number, found '<'");
++}
++
++#[test]
++pub fn test_tilde() {
++ let ref r = req("~1");
++ assert_match_all(r, &["1.0.0", "1.0.1", "1.1.1"]);
++ assert_match_none(r, &["0.9.1", "2.9.0", "0.0.9"]);
++
++ let ref r = req("~1.2");
++ assert_match_all(r, &["1.2.0", "1.2.1"]);
++ assert_match_none(r, &["1.1.1", "1.3.0", "0.0.9"]);
++
++ let ref r = req("~1.2.2");
++ assert_match_all(r, &["1.2.2", "1.2.4"]);
++ assert_match_none(r, &["1.2.1", "1.9.0", "1.0.9", "2.0.1", "0.1.3"]);
++
++ let ref r = req("~1.2.3-beta.2");
++ assert_match_all(r, &["1.2.3", "1.2.4", "1.2.3-beta.2", "1.2.3-beta.4"]);
++ assert_match_none(r, &["1.3.3", "1.1.4", "1.2.3-beta.1", "1.2.4-beta.2"]);
++}
++
++#[test]
++pub fn test_caret() {
++ let ref r = req("^1");
++ assert_match_all(r, &["1.1.2", "1.1.0", "1.2.1", "1.0.1"]);
++ assert_match_none(r, &["0.9.1", "2.9.0", "0.1.4"]);
++ assert_match_none(r, &["1.0.0-beta1", "0.1.0-alpha", "1.0.1-pre"]);
++
++ let ref r = req("^1.1");
++ assert_match_all(r, &["1.1.2", "1.1.0", "1.2.1"]);
++ assert_match_none(r, &["0.9.1", "2.9.0", "1.0.1", "0.1.4"]);
++
++ let ref r = req("^1.1.2");
++ assert_match_all(r, &["1.1.2", "1.1.4", "1.2.1"]);
++ assert_match_none(r, &["0.9.1", "2.9.0", "1.1.1", "0.0.1"]);
++ assert_match_none(r, &["1.1.2-alpha1", "1.1.3-alpha1", "2.9.0-alpha1"]);
++
++ let ref r = req("^0.1.2");
++ assert_match_all(r, &["0.1.2", "0.1.4"]);
++ assert_match_none(r, &["0.9.1", "2.9.0", "1.1.1", "0.0.1"]);
++ assert_match_none(r, &["0.1.2-beta", "0.1.3-alpha", "0.2.0-pre"]);
++
++ let ref r = req("^0.5.1-alpha3");
++ assert_match_all(
++ r,
++ &[
++ "0.5.1-alpha3",
++ "0.5.1-alpha4",
++ "0.5.1-beta",
++ "0.5.1",
++ "0.5.5",
++ ],
++ );
++ assert_match_none(
++ r,
++ &[
++ "0.5.1-alpha1",
++ "0.5.2-alpha3",
++ "0.5.5-pre",
++ "0.5.0-pre",
++ "0.6.0",
++ ],
++ );
++
++ let ref r = req("^0.0.2");
++ assert_match_all(r, &["0.0.2"]);
++ assert_match_none(r, &["0.9.1", "2.9.0", "1.1.1", "0.0.1", "0.1.4"]);
++
++ let ref r = req("^0.0");
++ assert_match_all(r, &["0.0.2", "0.0.0"]);
++ assert_match_none(r, &["0.9.1", "2.9.0", "1.1.1", "0.1.4"]);
++
++ let ref r = req("^0");
++ assert_match_all(r, &["0.9.1", "0.0.2", "0.0.0"]);
++ assert_match_none(r, &["2.9.0", "1.1.1"]);
++
++ let ref r = req("^1.4.2-beta.5");
++ assert_match_all(
++ r,
++ &["1.4.2", "1.4.3", "1.4.2-beta.5", "1.4.2-beta.6", "1.4.2-c"],
++ );
++ assert_match_none(
++ r,
++ &[
++ "0.9.9",
++ "2.0.0",
++ "1.4.2-alpha",
++ "1.4.2-beta.4",
++ "1.4.3-beta.5",
++ ],
++ );
++}
++
++#[test]
++pub fn test_wildcard() {
++ let err = req_err("");
++ assert_to_string(
++ err,
++ "unexpected end of input while parsing major version number",
++ );
++
++ let ref r = req("*");
++ assert_match_all(r, &["0.9.1", "2.9.0", "0.0.9", "1.0.1", "1.1.1"]);
++ assert_match_none(r, &["1.0.0-pre"]);
++
++ for s in &["x", "X"] {
++ assert_eq!(*r, req(s));
++ }
++
++ let ref r = req("1.*");
++ assert_match_all(r, &["1.2.0", "1.2.1", "1.1.1", "1.3.0"]);
++ assert_match_none(r, &["0.0.9", "1.2.0-pre"]);
++
++ for s in &["1.x", "1.X", "1.*.*"] {
++ assert_eq!(*r, req(s));
++ }
++
++ let ref r = req("1.2.*");
++ assert_match_all(r, &["1.2.0", "1.2.2", "1.2.4"]);
++ assert_match_none(r, &["1.9.0", "1.0.9", "2.0.1", "0.1.3", "1.2.2-pre"]);
++
++ for s in &["1.2.x", "1.2.X"] {
++ assert_eq!(*r, req(s));
++ }
++}
++
++#[test]
++pub fn test_logical_or() {
++ // https://github.com/steveklabnik/semver/issues/57
++ 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.1 || =1.2.3");
++ assert_to_string(err, "expected comma after minor version number, found '|'");
++
++ let err = req_err("6.* || 8.* || >= 10.*");
++ assert_to_string(err, "expected comma after minor version number, found '|'");
++}
++
++#[test]
++pub fn test_any() {
++ #[cfg(not(no_const_vec_new))]
++ let ref r = VersionReq::STAR;
++ #[cfg(no_const_vec_new)]
++ let ref r = VersionReq {
++ comparators: Vec::new(),
++ };
++ assert_match_all(r, &["0.0.1", "0.1.0", "1.0.0"]);
++}
++
++#[test]
++pub fn test_pre() {
++ let ref r = req("=2.1.1-really.0");
++ assert_match_all(r, &["2.1.1-really.0"]);
++}
++
++#[test]
++pub fn test_parse_errors() {
++ let err = req_err("\0");
++ assert_to_string(
++ err,
++ "unexpected character '\\0' while parsing major version number",
++ );
++
++ let err = req_err(">= >= 0.0.2");
++ assert_to_string(
++ err,
++ "unexpected character '>' while parsing major version number",
++ );
++
++ let err = req_err(">== 0.0.2");
++ assert_to_string(
++ err,
++ "unexpected character '=' while parsing major version number",
++ );
++
++ let err = req_err("a.0.0");
++ assert_to_string(
++ err,
++ "unexpected character 'a' while parsing major version number",
++ );
++
++ let err = req_err("1.0.0-");
++ assert_to_string(err, "empty identifier segment in pre-release identifier");
++
++ let err = req_err(">=");
++ assert_to_string(
++ err,
++ "unexpected end of input while parsing major version number",
++ );
++}
++
++#[test]
++fn test_cargo3202() {
++ let ref r = req("0.*.*");
++ assert_to_string(r, "0.*");
++ assert_match_all(r, &["0.5.0"]);
++
++ let ref r = req("0.0.*");
++ assert_to_string(r, "0.0.*");
++}
++
++#[test]
++fn test_digit_after_wildcard() {
++ let err = req_err("*.1");
++ assert_to_string(err, "unexpected character after wildcard in version req");
++
++ let err = req_err("1.*.1");
++ assert_to_string(err, "unexpected character after wildcard in version req");
++
++ let err = req_err(">=1.*.1");
++ assert_to_string(err, "unexpected character after wildcard in version req");
++}
++
++#[test]
++fn test_eq_hash() {
++ fn calculate_hash(value: impl Hash) -> u64 {
++ let mut hasher = DefaultHasher::new();
++ value.hash(&mut hasher);
++ hasher.finish()
++ }
++
++ assert!(req("^1") == req("^1"));
++ assert!(calculate_hash(req("^1")) == calculate_hash(req("^1")));
++ assert!(req("^1") != req("^2"));
++}
++
++#[test]
++fn test_leading_digit_in_pre_and_build() {
++ for op in &["=", ">", ">=", "<", "<=", "~", "^"] {
++ // digit then alpha
++ req(&format!("{} 1.2.3-1a", op));
++ req(&format!("{} 1.2.3+1a", op));
++
++ // digit then alpha (leading zero)
++ req(&format!("{} 1.2.3-01a", op));
++ req(&format!("{} 1.2.3+01", op));
++
++ // multiple
++ req(&format!("{} 1.2.3-1+1", op));
++ req(&format!("{} 1.2.3-1-1+1-1-1", op));
++ req(&format!("{} 1.2.3-1a+1a", op));
++ req(&format!("{} 1.2.3-1a-1a+1a-1a-1a", op));
++ }
++}
++
++#[test]
++fn test_wildcard_and_another() {
++ let err = req_err("*, 0.20.0-any");
++ assert_to_string(
++ err,
++ "wildcard req (*) must be the only comparator in the version req",
++ );
++
++ let err = req_err("0.20.0-any, *");
++ assert_to_string(
++ err,
++ "wildcard req (*) must be the only comparator in the version req",
++ );
++
++ let err = req_err("0.20.0-any, *, 1.0");
++ assert_to_string(
++ err,
++ "wildcard req (*) must be the only comparator in the version req",
++ );
++}
+diff --git a/third_party/rust/semver/tests/util/mod.rs b/third_party/rust/semver/tests/util/mod.rs
+new file mode 100644
+--- /dev/null
++++ b/third_party/rust/semver/tests/util/mod.rs
+@@ -0,0 +1,39 @@
++#![allow(dead_code)]
++
++use semver::{BuildMetadata, Error, Prerelease, Version, VersionReq};
++use std::fmt::Display;
++
++#[cfg_attr(not(no_track_caller), track_caller)]
++pub(super) fn version(text: &str) -> Version {
++ Version::parse(text).unwrap()
++}
++
++#[cfg_attr(not(no_track_caller), track_caller)]
++pub(super) fn version_err(text: &str) -> Error {
++ Version::parse(text).unwrap_err()
++}
++
++#[cfg_attr(not(no_track_caller), track_caller)]
++pub(super) fn req(text: &str) -> VersionReq {
++ VersionReq::parse(text).unwrap()
++}
++
++#[cfg_attr(not(no_track_caller), track_caller)]
++pub(super) fn req_err(text: &str) -> Error {
++ VersionReq::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 build_metadata(text: &str) -> BuildMetadata {
++ BuildMetadata::new(text).unwrap()
++}
++
++#[cfg_attr(not(no_track_caller), track_caller)]
++pub(super) fn assert_to_string(value: impl Display, expected: &str) {
++ assert_eq!(value.to_string(), expected);
++}
+diff --git a/toolkit/library/rust/shared/Cargo.toml b/toolkit/library/rust/shared/Cargo.toml
+--- a/toolkit/library/rust/shared/Cargo.toml
++++ b/toolkit/library/rust/shared/Cargo.toml
+@@ -16,17 +16,17 @@ nsstring = { path = "../../../../xpcom/r
+ netwerk_helper = { path = "../../../../netwerk/base/rust-helper" }
+ xpcom = { path = "../../../../xpcom/rust/xpcom" }
+ prefs_parser = { path = "../../../../modules/libpref/parser" }
+ static_prefs = { path = "../../../../modules/libpref/init/static_prefs" }
+ profiler_helper = { path = "../../../../tools/profiler/rust-helper", optional = true }
+ mozurl = { path = "../../../../netwerk/base/mozurl" }
+ webrender_bindings = { path = "../../../../gfx/webrender_bindings" }
+ cubeb-coreaudio = { git = "https://github.com/mozilla/cubeb-coreaudio-rs", rev = "44eca95823bb57e964cf7b6d9791ed2ccb4b2108", optional = true }
+-cubeb-pulse = { git = "https://github.com/mozilla/cubeb-pulse-rs", rev="df4dc0288b07b865440f4c7e41ca49ca9ccffc63", optional = true, features=["pulse-dlopen"] }
++cubeb-pulse = { git = "https://github.com/mozilla/cubeb-pulse-rs", rev="1f1fe1e08e01a9a534ec7f079702a583a0899ce7", optional = true, features=["pulse-dlopen"] }
+ cubeb-sys = { version = "0.10", optional = true, features=["gecko-in-tree"] }
+ audioipc2-client = { git = "https://github.com/kinetiknz/audioipc-2", rev = "85e9839059f4bf8f68130825b8fd02c39a6a51b9", optional = true } # macos (v2) branch
+ audioipc2-server = { git = "https://github.com/kinetiknz/audioipc-2", rev = "85e9839059f4bf8f68130825b8fd02c39a6a51b9", optional = true } # macos (v2) branch
+ audioipc-client = { git = "https://github.com/mozilla/audioipc-2", rev = "c144368c4e084ec0f076af6262970655c2d99e8d", optional = true }
+ audioipc-server = { git = "https://github.com/mozilla/audioipc-2", rev = "c144368c4e084ec0f076af6262970655c2d99e8d", optional = true }
+ encoding_glue = { path = "../../../../intl/encoding_glue" }
+ authenticator = "0.3.1"
+ gkrust_utils = { path = "../../../../xpcom/rust/gkrust_utils" }
+diff --git a/xpcom/rust/gkrust_utils/Cargo.toml b/xpcom/rust/gkrust_utils/Cargo.toml
+--- a/xpcom/rust/gkrust_utils/Cargo.toml
++++ b/xpcom/rust/gkrust_utils/Cargo.toml
+@@ -1,8 +1,8 @@
+ [package]
+ name = "gkrust_utils"
+ version = "0.1.0"
+ authors = ["Jonathan Kingston <jkt@mozilla.com>"]
+
+ [dependencies]
+-semver = "0.9"
++semver = "1.0"
+ nsstring = { path = "../nsstring" }
+
+diff --git a/third_party/rust/packed_simd_2/Cargo.toml b/third_party/rust/packed_simd_2/Cargo.toml
+--- a/third_party/rust/packed_simd_2/Cargo.toml
++++ b/third_party/rust/packed_simd_2/Cargo.toml
+@@ -24,7 +24,7 @@ codecov = { repository = "rust-lang/pack
+ core_arch = { version = "0.1.5", optional = true }
+
+ [build-dependencies]
+-rustc_version = "0.2"
++rustc_version = "0.4"
+
+ [features]
+ default = []
+diff --git a/third_party/rust/packed_simd_2/.cargo-checksum.json b/third_party/rust/packed_simd_2/.cargo-checksum.json
+--- a/third_party/rust/packed_simd_2/.cargo-checksum.json
++++ b/third_party/rust/packed_simd_2/.cargo-checksum.json
+@@ -1,1 +1,1 @@
+-{"files":{".appveyor.yml":"f1ed01850e0d725f9498f52a1a63ddf40702ad6e0bf5b2d7c4c04d76e96794a3",".travis.yml":"30a61a5ec53355fc1f3585e1690280308c2b7961701abc11e8389b235b647178","Cargo.toml":"e76b42f3247fccb7174046c499bfaae5430d83cadeb8140259fcae34613483cf","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"fa4dd64f66972217d35b7653338c9e2011ccd8f3008ae7c0103272d4287f9b1d","bors.toml":"dee881dc69b9b7834e4eba5d95c3ed5a416d4628815a167d6a22d4cb4fb064b8","build.rs":"a766fba121243a9b617432c592873801adb74c3a2f4a24d9d45859b8ce9357fc","ci/all.sh":"2ae6b2445b4db83833e40b37efd0016c6b9879ee988b9b3ef94db5439a3e1606","ci/android-install-ndk.sh":"0f1746108cc30bf9b9ba45bcde7b19fc1a8bdf5b0258035b4eb8dc69b75efac4","ci/android-install-sdk.sh":"3490432022c5c8f5a115c084f7a9aca1626f96c0c87ffb62019228c4346b47e4","ci/android-sysimage.sh":"ebf4e5daa1f0fe1b2092b79f0f3f161c4c4275cb744e52352c4d81ab451e4c5a","ci/benchmark.sh":"b61d19ef6b90deba8fb79dee74c8b062d94844676293da346da87bb78a9a49a4","ci/deploy_and_run_on_ios_simulator.rs":"ec8ecf82d92072676aa47f0d1a3d021b60a7ae3531153ef12d2ff4541fc294dc","ci/docker/aarch64-linux-android/Dockerfile":"ace2e7d33c87bc0f6d3962a4a3408c04557646f7f51ab99cfbf574906796b016","ci/docker/aarch64-unknown-linux-gnu/Dockerfile":"da88c0d50f16dc08448c7fdf1fa5ed2cbe576acf9e7dd85b5b818621b2a8c702","ci/docker/arm-linux-androideabi/Dockerfile":"370e55d3330a413a3ccf677b3afb3e0ef9018a5fab263faa97ae8ac017fc2286","ci/docker/arm-unknown-linux-gnueabi/Dockerfile":"bb5f8ae890707c128652290ffc544447643bf12037ddd73c6ad6989f848cb380","ci/docker/arm-unknown-linux-gnueabihf/Dockerfile":"1afaefcbc05b740859acd4e067bc92439be6bcbe8f2e9678474fb434bcd398d9","ci/docker/armv7-unknown-linux-gnueabihf/Dockerfile":"8282ea707a94109beed47a57574755e2d58401735904a03f85fb64c578c53b4f","ci/docker/i586-unknown-linux-gnu/Dockerfile":"49792922269f371bd29da4727e9085101b27be67a6b97755d0196c63317f7abb","ci/docker/i686-unknown-linux-gnu/Dockerfile":"49792922269f371bd29da4727e9085101b27be67a6b97755d0196c63317f7abb","ci/docker/mips-unknown-linux-gnu/Dockerfile":"b2ebc25797612c4f8395fe9d407725156044955bfbcf442036b7f55b43a5f9da","ci/docker/mips64-unknown-linux-gnuabi64/Dockerfile":"b0c1692ac65bc56dd30494b1993d8e929c48cc9c4b92029b7c7592af6d4f9220","ci/docker/mips64el-unknown-linux-gnuabi64/Dockerfile":"4e9249c179300138141d0b2b7401b11897f64aed69f541f078c1db4594df2827","ci/docker/mipsel-unknown-linux-musl/Dockerfile":"3164c52b0dcbb01afa78292b15b5c43503ccf0491cf6eb801ec2bf22ae274e52","ci/docker/powerpc-unknown-linux-gnu/Dockerfile":"786f799d0b56eb54d7b6c4b00e1aed4ce81776e14e44767e083c89d014b72004","ci/docker/powerpc64-unknown-linux-gnu/Dockerfile":"e8bc363837cd9c2d8b22402acb8c1c329efc11ba5d12170603d2fe2eae9da059","ci/docker/powerpc64le-unknown-linux-gnu/Dockerfile":"47998d45b781d797b9e6085ebe898d90de0c952b54537a8db4e8d7503eb032d9","ci/docker/s390x-unknown-linux-gnu/Dockerfile":"93fb44df3d7fd31ead158570667c97b5076a05c3d968af4a84bc13819a8f2db8","ci/docker/sparc64-unknown-linux-gnu/Dockerfile":"da1c39a3ff1fe22e41395fa7c8934e90b4c1788e551b9aec6e38bfd94effc437","ci/docker/thumbv7neon-linux-androideabi/Dockerfile":"c2decd5591bd7a09378901bef629cd944acf052eb55e4f35b79eb9cb4d62246a","ci/docker/thumbv7neon-unknown-linux-gnueabihf/Dockerfile":"51955a8bf3c4d440f47382af6f5426ebff94ab01a04da36175babda9a057740f","ci/docker/wasm32-unknown-unknown/Dockerfile":"5a022299f56730cf8c432a07391e95e199cfa36dc8da2a96c9d185c8de93e913","ci/docker/x86_64-linux-android/Dockerfile":"685040273cf350d5509e580ac451555efa19790c8723ca2af066adadc6880ad2","ci/docker/x86_64-unknown-linux-gnu-emulated/Dockerfile":"44b6203d9290bfdc53d81219f0937e1110847a23dd982ec8c4de388354f01536","ci/docker/x86_64-unknown-linux-gnu/Dockerfile":"7f4e3ca5fa288ea70edb4d1f75309708cd30b192e2e4444e61c4d5b3b58f89cf","ci/dox.sh":"434e9611c52e389312d2b03564adf09429f10cc76fe66a8644adb104903b87b7","ci/linux-s390x.sh":"d6b732d7795b4ba131326aff893bca6228a7d2eb0e9402f135705413dbbe0dce","ci/linux-sparc64.sh":"c92966838b1ab7ad3b7a344833ee726aba6b647cf5952e56f0ad1ba420b13325","ci/lld-shim.rs":"3d7f71ec23a49e2b67f694a0168786f9a954dda15f5a138815d966643fd3fcc3","ci/max_line_width.sh":"0a1518bba4c9ecaa55694cb2e9930d0e19c265baabf73143f17f9cf285aaa5bb","ci/run-docker.sh":"92e036390ad9b0d16f109579df1b5ced2e72e9afea40c7d011400ebd3a2a90de","ci/run.sh":"41dd6a60efaaeae9661a01370cce98b631f78392859a0cf68c946c0a16edf5f7","ci/run_examples.sh":"d1a23c6c35374a0678ba5114b9b8fefd8be0a79e774872a8bf0898d1baca18d0","ci/runtest-android.rs":"145a8e9799a5223975061fe7e586ade5669ee4877a7d7a4cf6b4ab48e8e36c7c","ci/setup_benchmarks.sh":"fae3960023f6f3d1388cd2ad22fdbab4b075f1f29dd4292d7994a20783beb6cf","ci/test-runner-linux":"c8aa6025cff5306f4f31d0c61dc5f9d4dd5a1d189ab613ef8d4c367c694d9ccd","contributing.md":"2d2629310ad4d464c482bdbb5819f0d6ce223c576aeef2cdce6a1f6857085ea5","perf-guide/.gitignore":"fe82c7da551079d832cf74200b0b359b4df9828cb4a0416fa7384f07a2ae6a13","perf-guide/book.toml":"115a98284126c6b180178b44713314cc494f08a71662ee2ce15cf67f17a51064","perf-guide/src/SUMMARY.md":"3e03bffc991fdc2050f3d51842d72d9d21ea6abab56a3baf3b2d5973a78b89e1","perf-guide/src/ascii.css":"29afb08833b2fe2250f0412e1fa1161a2432a0820a14953c87124407417c741a","perf-guide/src/bound_checks.md":"5e4991ff58a183ef0cd9fdc1feb4cd12d083b44bdf87393bbb0927808ef3ce7d","perf-guide/src/float-math/approx.md":"8c09032fa2d795a0c5db1775826c850d28eb2627846d0965c60ee72de63735ad","perf-guide/src/float-math/fma.md":"311076ba4b741d604a82e74b83a8d7e8c318fcbd7f64c4392d1cf5af95c60243","perf-guide/src/float-math/fp.md":"04153e775ab6e4f0d7837bcc515230d327b04edfa34c84ce9c9e10ebaeef2be8","perf-guide/src/float-math/svml.md":"0798873b8eedaeda5fed62dc91645b57c20775a02d3cd74d8bd06958f1516506","perf-guide/src/introduction.md":"9f5a19e9e6751f25d2daad39891a0cc600974527ec4c8305843f9618910671bd","perf-guide/src/prof/linux.md":"447731eb5de7d69166728fdbc5ecb0c0c9db678ea493b45a592d67dd002184c0","perf-guide/src/prof/mca.md":"f56d54f3d20e7aa4d32052186e8237b03d65971eb5d112802b442570ff11d344","perf-guide/src/prof/profiling.md":"8a650c0fd6ede0964789bb6577557eeef1d8226a896788602ce61528e260e43c","perf-guide/src/target-feature/attribute.md":"615f88dca0a707b6c416fa605435dd6e1fb5361cc639429cbf68cd87624bd78b","perf-guide/src/target-feature/features.md":"17077760ff24c006b606dd21889c53d87228f4311f3ba3a574f9afdeacd86165","perf-guide/src/target-feature/inlining.md":"7ed1d7068d8173a00d84c16cfe5871cd68b9f04f8d0cca2d01ebc84957ebf2f6","perf-guide/src/target-feature/practice.md":"c4b371842e0086df178488fec97f20def8f0c62ee588bcd25fd948b9b1fa227e","perf-guide/src/target-feature/runtime.md":"835425f5ee597fb3e51d36e725a81ebee29f4561231d19563cd4da81dbb1cfcb","perf-guide/src/target-feature/rustflags.md":"01197acf6f0adec8db32b8591811f69cecb6555a2b05dc5d5ec27d0e3f7b065e","perf-guide/src/vert-hor-ops.md":"c6211c0ee91e60552ec592d89d9d957eedc21dee3cbd89e1ad6765ea06a27471","rustfmt.toml":"d99a43f3f8ef9e425cf01c333fba9f0051f888f5d87ab4e8f63c2f7d0fe6620f","src/api.rs":"bb1795e9657a8298d37d2349b45443f08e9e455399ad4b727018600728478c10","src/api/bit_manip.rs":"c47a4d0f7451f7e35d07715e4f39a472e07457fd456fdb726864a4f6887252a3","src/api/bitmask.rs":"6d2beefd62ee5d9c8eb060bee6abc641616bf828c99f82abf97b21bf004e894b","src/api/cast.rs":"03b94a3d316ac7b7be7068810044911e965e889a0ace7bae762749ca74a92747","src/api/cast/macros.rs":"b0a14d0c83ad2ebb7a275180f6d9e3f2bc312ba57a7d3d6c39fad4e0f20f9408","src/api/cast/v128.rs":"edd0994efac4379dff26e178423a52dbb3ffeb38b1fc97cae975d744c00b4fb6","src/api/cast/v16.rs":"96bd98c2d21b0663abe6c0ab33005b1fa693f3db7ee6795351391343863484da","src/api/cast/v256.rs":"8c31fe91f5e78ef737dfba6979cc1240210cb094a89d284fe459bf8a991ca24b","src/api/cast/v32.rs":"a99a79dd84d2a5e6adf9db98705675915bd03fd1287d489c7fe38e84d7e4a086","src/api/cast/v512.rs":"c0dd526f41ed7b8a71c3743d91267554ec0a0c75834ccc2e3ecb0ef3004af642","src/api/cast/v64.rs":"6572fdba2a1241a6cd666d3f0cce3306cd2cb7e5e236172e59d5d4351c8a88af","src/api/cmp.rs":"357c3a2a09c6d4611c32dd7fa95be2fae933d513e229026ec9b44451a77b884e","src/api/cmp/eq.rs":"60f70f355bae4cb5b17db53204cacc3890f70670611c17df638d4c04f7cc8075","src/api/cmp/ord.rs":"589f7234761c294fa5df8f525bc4acd5a47cdb602207d524a0d4e19804cd9695","src/api/cmp/partial_eq.rs":"902ccb8aa01fd5738b30ba0b712669c21d4801958907e03bad23432c7dba0198","src/api/cmp/partial_ord.rs":"9db0c37d7434cdfc62d8d66912e972fa3d8c115ab2af051a6f45e414bd3e4f1c","src/api/cmp/vertical.rs":"de3d62f38eba817299aa16f1e1939954c9a447e316509397465c2830852ba053","src/api/default.rs":"67bf21c134127d12a7028c8b88a57f0ceee8ccbd74976da8ca74eb9f16a174d5","src/api/fmt.rs":"67fb804bb86b6cd77cf8cd492b5733ce437071b66fe3297278b8a6552c325dda","src/api/fmt/binary.rs":"02b2b287f7404f8a983813cf70c87108c8da3835578b63ab303116885f609413","src/api/fmt/debug.rs":"56e1c3bdc092747344fffaafff9da7163ee7827857f6fb7cb1c9923eca4f6fa0","src/api/fmt/lower_hex.rs":"558fd592f7f485712fb051509cecc7174a21e6bf62e5ce64766e75afc97bb8e1","src/api/fmt/octal.rs":"3b2e70877a4f368c7704f8e254236c014c365c74d93371c1feb5f030e6c66422","src/api/fmt/upper_hex.rs":"2a442f666bc80e22d41f903f881238fe114dd49344c3ed69849250e853cafc5d","src/api/from.rs":"2e599d8329cb05eaf06224cc441355c4b7b51254fc19256619333be8c149d444","src/api/from/from_array.rs":"dd3fc64fb17d6184bb60343f8da26a05edf0e5f3c14caf55d49fa15e21d948dc","src/api/from/from_vector.rs":"9764371aa9e6005aace74dea14f59e5611a095b7cf42707940924749282c52f0","src/api/hash.rs":"5076ece87969592c876486f5b1ea8affbeaec379d1a14a30859e0aa5592019de","src/api/into_bits.rs":"1ee15923352786b9ab4a31fa506762297116b18cfdb8e72853abc8ad001651d2","src/api/into_bits/arch_specific.rs":"e7445021f3908326bfee758835e5fc5ad56aa1baa77fc1c58abe4350c66c670a","src/api/into_bits/macros.rs":"bb4fe99be2af6a21d805efab44c8e4e61a7b2adb42a65504a0cf26d13efdadcd","src/api/into_bits/v128.rs":"145a44922b09a5ca5b62d88a461d327d399a997a15db4b11d7b17e554a9fa4c0","src/api/into_bits/v16.rs":"f4f4f61ba88aa51b158ec56ca3dce234349aea0daf2b3029a14ab5125d1e41e5","src/api/into_bits/v256.rs":"8cea9c5d9809f11323cb7cdc53b83df593fd17caf926251e412ae9777bed547f","src/api/into_bits/v32.rs":"905ba683d342fa32f4202b80bb46530807bd0a5b588f6c2e8c9f475223c47775","src/api/into_bits/v512.rs":"e25afa1fbf088a5d58e7d75d197b6cd4c56637ea28542ba18e46a451f29d04e7","src/api/into_bits/v64.rs":"d6238022ccff7b92e55b3f6017fc269acb6f36330a6d7e8fb389853a0f1b6478","src/api/math.rs":"8b2a2fc651917a850539f993aa0b9e5bf4da67b11685285b8de8cdca311719ec","src/api/math/float.rs":"61d2794d68262a1090ae473bd30793b5f65cf732f32a6694a3af2ce5d9225616","src/api/math/float/abs.rs":"5b6b2701e2e11135b7ce58a05052ea8120e10e4702c95d046b9d21b827b26bf8","src/api/math/float/consts.rs":"6302c9261da4291d144d5bb53493cdd073498feb40955fb6860ea3c4d06c978a","src/api/math/float/cos.rs":"4c2dd7173728ef189314f1576c9486e03be21b7da98843b2f9011282a7979e31","src/api/math/float/exp.rs":"7c6d5f1e304f498a01cfa23b92380c815d7da0ad94eae3483783bc377d287eef","src/api/math/float/ln.rs":"54c7583f3df793b39ff57534fade27b41bb992439e5dc178252f5ca3190a3e54","src/api/math/float/mul_add.rs":"62cac77660d20159276d4c9ef066eb90c81cbddb808e8e157182c607625ad2eb","src/api/math/float/mul_adde.rs":"bae056ee9f3a70df39ec3c3b2f6437c65303888a7b843ef1a5bcf1f5aca0e602","src/api/math/float/powf.rs":"9ddb938984b36d39d82a82f862f80df8f7fb013f1d222d45698d41d88472f568","src/api/math/float/recpre.rs":"589225794ff1dbf31158dff660e6d4509ecc8befbb57c633900dea5ac0b840d6","src/api/math/float/rsqrte.rs":"a32abdcc318d7ccc8448231f54d75b884b7cbeb03a7d595713ab6243036f4dbf","src/api/math/float/sin.rs":"cbd3622b7df74f19691743001c8cf747a201f8977ad90542fee915f37dcd1e49","src/api/math/float/sqrt.rs":"0c66d5d63fb08e4d99c6b82a8828e41173aff1ac9fa1a2764a11fac217ccf2ac","src/api/math/float/sqrte.rs":"731e1c9f321b662accdd27dacb3aac2e8043b7aecb2f2161dde733bd9f025362","src/api/minimal.rs":"1f22bcc528555444e76de569ec0ae2029b9ae9d04805efeafa93369c8098036b","src/api/minimal/iuf.rs":"819cff26d3e196f807645bcc1d79eb27d9f175edb89910f2274d52a1e913cd11","src/api/minimal/mask.rs":"0cae10ae1fc65f5070e686c0c79bfba27b86b33d6c399367bd4848fb367dcec4","src/api/minimal/ptr.rs":"f65ebf21866a863485344432d9a7a9b7418f7fad5fdf841a4e2fa56ec0766ad0","src/api/ops.rs":"3e273b277a0f3019d42c3c59ca94a5afd4885d5ae6d2182e5089bbeec9de42ee","src/api/ops/scalar_arithmetic.rs":"d2d5ad897a59dd0787544f927e0e7ca4072c3e58b0f4a2324083312b0d5a21d7","src/api/ops/scalar_bitwise.rs":"482204e459ca6be79568e1c9f70adbe2d2151412ddf122fb2161be8ebb51c40c","src/api/ops/scalar_mask_bitwise.rs":"c250f52042e37b22d57256c80d4604104cfd2fbe2a2e127c676267270ca5d350","src/api/ops/scalar_shifts.rs":"c4773d435c3f9da4454327e6fbb2b5b41a1c0ebb1cca7372e69dc7a344a1b6e4","src/api/ops/vector_arithmetic.rs":"ddca15d09ddeef502c2ed66117a62300ca65d87e959e8b622d767bdf1c307910","src/api/ops/vector_bitwise.rs":"b3968f7005b649edcc22a54e2379b14d5ee19045f2e784029805781ae043b5ee","src/api/ops/vector_float_min_max.rs":"76bf8cb607e2c442923c1da1061a6b80d742d607408033c2a3761161114cf2a0","src/api/ops/vector_int_min_max.rs":"a378789c6ff9b32a51fbd0a97ffd36ed102cd1fe6a067d2b02017c1df342def6","src/api/ops/vector_mask_bitwise.rs":"5052d18517d765415d40327e6e8e55a312daaca0a5e2aec959bfa54b1675f9c8","src/api/ops/vector_neg.rs":"5c62f6b0221983cdbd23cd0a3af3672e6ba1255f0dfe8b19aae6fbd6503e231b","src/api/ops/vector_rotates.rs":"ee319eaaa449dc50ea8ef05b89d38519c6faa6753dfdce432ea7bb8520e4e8e7","src/api/ops/vector_shifts.rs":"e510be14127c0ffd58a2573a39701da3557d66bedec09837ac8bbd44d579da00","src/api/ptr.rs":"8a793251bed6130dcfb2f1519ceaa18b751bbb15875928d0fb6deb5a5e07523a","src/api/ptr/gather_scatter.rs":"3d614f9d5b4ca201a9f7e46af4405e1d2c28ecee1620297c23b52e37b92cc0ea","src/api/reductions.rs":"ae5baca81352ecd44526d6c30c0a1feeda475ec73ddd3c3ec6b14e944e5448ee","src/api/reductions/bitwise.rs":"8bf910ae226188bd15fc7e125f058cd2566b6186fcd0cd8fd020f352c39ce139","src/api/reductions/float_arithmetic.rs":"47a5679896db2cbb56c31372fe42143da015b6beae7db5d2f3a0309ddf427ae1","src/api/reductions/integer_arithmetic.rs":"c2df3cf7493cca4174f2c65aea422a3d20d8a23af03f8d57cef72c19fee8f20d","src/api/reductions/mask.rs":"db83327a950e33a317f37fd33ca4e20c347fb415975ec024f3e23da8509425af","src/api/reductions/min_max.rs":"6af8c9aa45c69961b1b6fc205395f4767d4421869fb105fb3d563c5605fc13cd","src/api/select.rs":"6b07e7e8026df561f7307221a896f0fbb272536f41b9109040ac094c24c69331","src/api/shuffle.rs":"26458aec2557bfab41b7765f72aefbff3a7ee08cdc689981a81f133f58ee368b","src/api/shuffle1_dyn.rs":"bfea5a91905b31444e9ef7ca6eddb7a9606b7e22d3f71bb842eb2795a0346620","src/api/slice.rs":"ee87484e8af329547b9a5d4f2a69e8bed6ea10bbd96270d706083843d4eea2ac","src/api/slice/from_slice.rs":"9b6f01ace2d12ef45c84608bb7aad3a122e2cc319b2d99170fc332a568b8de63","src/api/slice/write_to_slice.rs":"244b6bd6ccffa6e5a195f8b1abc66d94251b6d16b2ec3fe4d76d32caec68261e","src/api/swap_bytes.rs":"4a6792a2e49a77475e1b237592b4b2804dbddb79c474331acd0dd71b36934259","src/codegen.rs":"db4f232fb9f5728db310b87dc8c4733be48afacab1053798c06106bef9a42b05","src/codegen/bit_manip.rs":"525ea6ff7ad1e043b6f6136992166f1803ed5563b7f6fc292c1c40257d20e264","src/codegen/llvm.rs":"b4ccbc0bad90038f00fc3c158736462d01d0053df3afa00f9169e67d1a264444","src/codegen/math.rs":"dfcf02ad34e2fdfe22c3f1cc2822001cc895e65031b4d06e585e5047839febb7","src/codegen/math/float.rs":"2c1cbce155bc527ce34d472c0fef6bc3dadb79cd7a357dd7aa5b1ebeb1d77a13","src/codegen/math/float/abs.rs":"d5aaadcf540bdb9b4264dca6471a255fd7bf509e763bef0239c0144a68466fea","src/codegen/math/float/cos.rs":"17f28d2900c852dca221fa9c92a9cd5fe7fd2df8d427bbc60216c749b2be013d","src/codegen/math/float/cos_pi.rs":"dbaf9f443f9846a491d4ec52210a7b5835dd593b03366e3135b05c37d70f9d6c","src/codegen/math/float/exp.rs":"d300058a4bcc7ae7976f216f81902cd73a9e603ad63880dff3bbc866c27a9f37","src/codegen/math/float/ln.rs":"c851e211e43f8256093ba75b03ae0c307c9962ee66d94f09b4dd80068190cbdf","src/codegen/math/float/macros.rs":"fc9924869ed85e4795983af228cacf23158f4f35919adce16c920ad4a3f0a009","src/codegen/math/float/mul_add.rs":"041a5b69d5991d93ef795351b17560c10faf80b78fd26ad7df42a239b32cf9de","src/codegen/math/float/mul_adde.rs":"d71d5f0f3333b62a7439b823cb7adf5340ea1555ce820fb4a3f4cb922f73f5f5","src/codegen/math/float/powf.rs":"9742c3877f1a5509ca5c9492a40884b6579ba6dd11c26b7112e63f70666b395d","src/codegen/math/float/sin.rs":"0e9868d35531566509f3a01d85d5253045eb4afa8525d8407dcc1f5f33c56036","src/codegen/math/float/sin_cos_pi.rs":"8e6b6142d7dd240cdb36669722e82ab9810a2261e86e659f7d97a942ad8b1258","src/codegen/math/float/sin_pi.rs":"bb6d39db8f921e03a301fc5206ac1a61a97def8a2cb83b87ccf189f3fc48d548","src/codegen/math/float/sqrt.rs":"e6ebb0c5f428efad1f672b9a8fe4e58534dbf1ea5a8fe092ce5ce76b52fe89cb","src/codegen/math/float/sqrte.rs":"23acfaea38d0e081a6d9021c1094e813d0cfd12c58c1eca9662aade5e625d51c","src/codegen/pointer_sized_int.rs":"6ca13c214b6cf7e0929dbe18e96a16fc0bb7d8799608df29c4c8115490f99e01","src/codegen/reductions.rs":"8eb18ebac76985d2aa30262a2edd8cb004230b511a765d657525f677a585c12c","src/codegen/reductions/mask.rs":"e67f35a1f4d156a4894a2d6ea5a935b4d898cf70eefb2715f5c1cc165e776c11","src/codegen/reductions/mask/aarch64.rs":"84b101c17cad1ede4eb6d38cada0ac7da239dba8cea3badd3829b967e558431f","src/codegen/reductions/mask/arm.rs":"aaa07129bd078ae7e677cf8b8e67ec9f30536606a0c7ed1baaa18fd1793bb218","src/codegen/reductions/mask/fallback.rs":"3eb9319d2c7cf19216b607b8459612c4e027b643cf11b036937d36896bf76786","src/codegen/reductions/mask/fallback_impl.rs":"76547f396e55ef403327c77c314cf8db8c7a5c9b9819bfb925abeacf130249e5","src/codegen/reductions/mask/x86.rs":"36dcd8af4ab99730a078ed113d3955f74eb1a2876e2e6d9f224e0ff462c216d1","src/codegen/reductions/mask/x86/avx.rs":"3a40868b38c86e35aefb96d7578de6322efe89d8135e0366359b54ddd06f861a","src/codegen/reductions/mask/x86/avx2.rs":"677aed3f056285285daa3adff8bc65e739630b4424defa6d9665e160f027507e","src/codegen/reductions/mask/x86/sse.rs":"8522f6ed03f6c32dd577d4298df477c08aeaaa38563706f29096e1911ed731f2","src/codegen/reductions/mask/x86/sse2.rs":"54ec56e49b0c6841eccb719e4f310d65fe767c04136b2ec20bd8b9d7d9897b9e","src/codegen/shuffle.rs":"1ec2930f4e1acc43ac30b518af298d466a79e9e75734a51c380b7810efd1a27f","src/codegen/shuffle1_dyn.rs":"3f13ca1597378758d05106bf5ff3715eee531f3cb6d88f48b9182bd6c9386b51","src/codegen/swap_bytes.rs":"c67c86e91ca3fc77539e0efcea081a3c62548cccf503963ae408f2e86f4e6a21","src/codegen/v128.rs":"94226b31ec403d18d9d2fe06713f147c9c79e9b5f9105089088266313f843185","src/codegen/v16.rs":"ddec4ffb66b6f7aaffb9a1780c5ddba82557abd74f45073d335047e04cf74924","src/codegen/v256.rs":"6b63917f0444118d6b1595bff2045e59b97c4d24012bd575f69f1f0efc5a0241","src/codegen/v32.rs":"3477b3c5540aed86e61e2f5807dd31db947413cec9181c587d93ed6ec74f0eba","src/codegen/v512.rs":"5854f99d3aabc4cd42b28a20d9ce447756dc2ba024a409a69b6a8ae1f1842fc5","src/codegen/v64.rs":"e9e89caebfe63d10c0cbca61e4dfdba3b7e02ee0989170f80beed23237ddd950","src/codegen/vPtr.rs":"f0753b405cdc865bdf8e82c6505f299ea1f96136239ebbaf7f9ce93d310764b8","src/codegen/vSize.rs":"c89f5fdeb28ac4c8272ed1816fce03d9d95308cc32bb2533bd8b20cd5ac102ac","src/lib.rs":"b6f846d5d30cf6b035a2d18039aba7b2045cf89384733d643572bd68873ae064","src/masks.rs":"70fc0abe4c2907ce2a491c574e1cfb9f3423385da2e1a923a48c9c13f8ba6ed8","src/sealed.rs":"ae7fdeaf5d84cd7710ed730ca72ca7eaba93df6cb0acb183e5c0a7327acf197f","src/testing.rs":"896669c08d8c801448a4d2fadc9d633eda0fbe879d229997e2a182e31278e469","src/testing/macros.rs":"403bbc5ecb7c786fe36156df302d0c07a8122408dbb15f7474d7682224ba1106","src/testing/utils.rs":"41912a92266dfe884647fc035e4242fd746100df8e839808ae0397af3759a3c8","src/v128.rs":"16cf9a8e7156b899ee9b9cd3f2dba9d13ec63289bea8c3ee9ae2e43ad9510288","src/v16.rs":"cb6465cf1e00bf530183af1819b9fe3d7eec978f8765d5e85d9b58a39a4b4045","src/v256.rs":"fe235017da18c7f3c361831c60e3173ad304d8ea1e95d64ebebc79da2d708511","src/v32.rs":"145d347855bac59b2de6508f9e594654e6c330423af9edc0e2ac8f4d1abdf45e","src/v512.rs":"f372f277f3e62eb5c945bb1c460333fdb17b6974fcc876633788ff53bded9599","src/v64.rs":"0b8079881b71575e3414be0b7f8f7eaba65281ba6732f2b2f61f73e95b6f48f7","src/vPtr.rs":"8b3e433d487180bb4304ff71245ecad90f0010f43e139a72027b672abe58facc","src/vSize.rs":"eda5aa020706cbf94d15bada41a0c2a35fc8f3f37cb7c2cd6f34d201399a495e","tests/endianness.rs":"2783d727e8ff8789211e03120634cd3ad9f8972fc484012681b5b63cf89408a7"},"package":null}
+\ No newline at end of file
++{"files":{".appveyor.yml":"f1ed01850e0d725f9498f52a1a63ddf40702ad6e0bf5b2d7c4c04d76e96794a3",".travis.yml":"30a61a5ec53355fc1f3585e1690280308c2b7961701abc11e8389b235b647178","Cargo.toml":"2cab084b3d55d0b307788b02a6206a3ec39fee027535dc62d6421bce70e2e2c1","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"fa4dd64f66972217d35b7653338c9e2011ccd8f3008ae7c0103272d4287f9b1d","bors.toml":"dee881dc69b9b7834e4eba5d95c3ed5a416d4628815a167d6a22d4cb4fb064b8","build.rs":"a766fba121243a9b617432c592873801adb74c3a2f4a24d9d45859b8ce9357fc","ci/all.sh":"2ae6b2445b4db83833e40b37efd0016c6b9879ee988b9b3ef94db5439a3e1606","ci/android-install-ndk.sh":"0f1746108cc30bf9b9ba45bcde7b19fc1a8bdf5b0258035b4eb8dc69b75efac4","ci/android-install-sdk.sh":"3490432022c5c8f5a115c084f7a9aca1626f96c0c87ffb62019228c4346b47e4","ci/android-sysimage.sh":"ebf4e5daa1f0fe1b2092b79f0f3f161c4c4275cb744e52352c4d81ab451e4c5a","ci/benchmark.sh":"b61d19ef6b90deba8fb79dee74c8b062d94844676293da346da87bb78a9a49a4","ci/deploy_and_run_on_ios_simulator.rs":"ec8ecf82d92072676aa47f0d1a3d021b60a7ae3531153ef12d2ff4541fc294dc","ci/docker/aarch64-linux-android/Dockerfile":"ace2e7d33c87bc0f6d3962a4a3408c04557646f7f51ab99cfbf574906796b016","ci/docker/aarch64-unknown-linux-gnu/Dockerfile":"da88c0d50f16dc08448c7fdf1fa5ed2cbe576acf9e7dd85b5b818621b2a8c702","ci/docker/arm-linux-androideabi/Dockerfile":"370e55d3330a413a3ccf677b3afb3e0ef9018a5fab263faa97ae8ac017fc2286","ci/docker/arm-unknown-linux-gnueabi/Dockerfile":"bb5f8ae890707c128652290ffc544447643bf12037ddd73c6ad6989f848cb380","ci/docker/arm-unknown-linux-gnueabihf/Dockerfile":"1afaefcbc05b740859acd4e067bc92439be6bcbe8f2e9678474fb434bcd398d9","ci/docker/armv7-unknown-linux-gnueabihf/Dockerfile":"8282ea707a94109beed47a57574755e2d58401735904a03f85fb64c578c53b4f","ci/docker/i586-unknown-linux-gnu/Dockerfile":"49792922269f371bd29da4727e9085101b27be67a6b97755d0196c63317f7abb","ci/docker/i686-unknown-linux-gnu/Dockerfile":"49792922269f371bd29da4727e9085101b27be67a6b97755d0196c63317f7abb","ci/docker/mips-unknown-linux-gnu/Dockerfile":"b2ebc25797612c4f8395fe9d407725156044955bfbcf442036b7f55b43a5f9da","ci/docker/mips64-unknown-linux-gnuabi64/Dockerfile":"b0c1692ac65bc56dd30494b1993d8e929c48cc9c4b92029b7c7592af6d4f9220","ci/docker/mips64el-unknown-linux-gnuabi64/Dockerfile":"4e9249c179300138141d0b2b7401b11897f64aed69f541f078c1db4594df2827","ci/docker/mipsel-unknown-linux-musl/Dockerfile":"3164c52b0dcbb01afa78292b15b5c43503ccf0491cf6eb801ec2bf22ae274e52","ci/docker/powerpc-unknown-linux-gnu/Dockerfile":"786f799d0b56eb54d7b6c4b00e1aed4ce81776e14e44767e083c89d014b72004","ci/docker/powerpc64-unknown-linux-gnu/Dockerfile":"e8bc363837cd9c2d8b22402acb8c1c329efc11ba5d12170603d2fe2eae9da059","ci/docker/powerpc64le-unknown-linux-gnu/Dockerfile":"47998d45b781d797b9e6085ebe898d90de0c952b54537a8db4e8d7503eb032d9","ci/docker/s390x-unknown-linux-gnu/Dockerfile":"93fb44df3d7fd31ead158570667c97b5076a05c3d968af4a84bc13819a8f2db8","ci/docker/sparc64-unknown-linux-gnu/Dockerfile":"da1c39a3ff1fe22e41395fa7c8934e90b4c1788e551b9aec6e38bfd94effc437","ci/docker/thumbv7neon-linux-androideabi/Dockerfile":"c2decd5591bd7a09378901bef629cd944acf052eb55e4f35b79eb9cb4d62246a","ci/docker/thumbv7neon-unknown-linux-gnueabihf/Dockerfile":"51955a8bf3c4d440f47382af6f5426ebff94ab01a04da36175babda9a057740f","ci/docker/wasm32-unknown-unknown/Dockerfile":"5a022299f56730cf8c432a07391e95e199cfa36dc8da2a96c9d185c8de93e913","ci/docker/x86_64-linux-android/Dockerfile":"685040273cf350d5509e580ac451555efa19790c8723ca2af066adadc6880ad2","ci/docker/x86_64-unknown-linux-gnu-emulated/Dockerfile":"44b6203d9290bfdc53d81219f0937e1110847a23dd982ec8c4de388354f01536","ci/docker/x86_64-unknown-linux-gnu/Dockerfile":"7f4e3ca5fa288ea70edb4d1f75309708cd30b192e2e4444e61c4d5b3b58f89cf","ci/dox.sh":"434e9611c52e389312d2b03564adf09429f10cc76fe66a8644adb104903b87b7","ci/linux-s390x.sh":"d6b732d7795b4ba131326aff893bca6228a7d2eb0e9402f135705413dbbe0dce","ci/linux-sparc64.sh":"c92966838b1ab7ad3b7a344833ee726aba6b647cf5952e56f0ad1ba420b13325","ci/lld-shim.rs":"3d7f71ec23a49e2b67f694a0168786f9a954dda15f5a138815d966643fd3fcc3","ci/max_line_width.sh":"0a1518bba4c9ecaa55694cb2e9930d0e19c265baabf73143f17f9cf285aaa5bb","ci/run-docker.sh":"92e036390ad9b0d16f109579df1b5ced2e72e9afea40c7d011400ebd3a2a90de","ci/run.sh":"41dd6a60efaaeae9661a01370cce98b631f78392859a0cf68c946c0a16edf5f7","ci/run_examples.sh":"d1a23c6c35374a0678ba5114b9b8fefd8be0a79e774872a8bf0898d1baca18d0","ci/runtest-android.rs":"145a8e9799a5223975061fe7e586ade5669ee4877a7d7a4cf6b4ab48e8e36c7c","ci/setup_benchmarks.sh":"fae3960023f6f3d1388cd2ad22fdbab4b075f1f29dd4292d7994a20783beb6cf","ci/test-runner-linux":"c8aa6025cff5306f4f31d0c61dc5f9d4dd5a1d189ab613ef8d4c367c694d9ccd","contributing.md":"2d2629310ad4d464c482bdbb5819f0d6ce223c576aeef2cdce6a1f6857085ea5","perf-guide/.gitignore":"fe82c7da551079d832cf74200b0b359b4df9828cb4a0416fa7384f07a2ae6a13","perf-guide/book.toml":"115a98284126c6b180178b44713314cc494f08a71662ee2ce15cf67f17a51064","perf-guide/src/SUMMARY.md":"3e03bffc991fdc2050f3d51842d72d9d21ea6abab56a3baf3b2d5973a78b89e1","perf-guide/src/ascii.css":"29afb08833b2fe2250f0412e1fa1161a2432a0820a14953c87124407417c741a","perf-guide/src/bound_checks.md":"5e4991ff58a183ef0cd9fdc1feb4cd12d083b44bdf87393bbb0927808ef3ce7d","perf-guide/src/float-math/approx.md":"8c09032fa2d795a0c5db1775826c850d28eb2627846d0965c60ee72de63735ad","perf-guide/src/float-math/fma.md":"311076ba4b741d604a82e74b83a8d7e8c318fcbd7f64c4392d1cf5af95c60243","perf-guide/src/float-math/fp.md":"04153e775ab6e4f0d7837bcc515230d327b04edfa34c84ce9c9e10ebaeef2be8","perf-guide/src/float-math/svml.md":"0798873b8eedaeda5fed62dc91645b57c20775a02d3cd74d8bd06958f1516506","perf-guide/src/introduction.md":"9f5a19e9e6751f25d2daad39891a0cc600974527ec4c8305843f9618910671bd","perf-guide/src/prof/linux.md":"447731eb5de7d69166728fdbc5ecb0c0c9db678ea493b45a592d67dd002184c0","perf-guide/src/prof/mca.md":"f56d54f3d20e7aa4d32052186e8237b03d65971eb5d112802b442570ff11d344","perf-guide/src/prof/profiling.md":"8a650c0fd6ede0964789bb6577557eeef1d8226a896788602ce61528e260e43c","perf-guide/src/target-feature/attribute.md":"615f88dca0a707b6c416fa605435dd6e1fb5361cc639429cbf68cd87624bd78b","perf-guide/src/target-feature/features.md":"17077760ff24c006b606dd21889c53d87228f4311f3ba3a574f9afdeacd86165","perf-guide/src/target-feature/inlining.md":"7ed1d7068d8173a00d84c16cfe5871cd68b9f04f8d0cca2d01ebc84957ebf2f6","perf-guide/src/target-feature/practice.md":"c4b371842e0086df178488fec97f20def8f0c62ee588bcd25fd948b9b1fa227e","perf-guide/src/target-feature/runtime.md":"835425f5ee597fb3e51d36e725a81ebee29f4561231d19563cd4da81dbb1cfcb","perf-guide/src/target-feature/rustflags.md":"01197acf6f0adec8db32b8591811f69cecb6555a2b05dc5d5ec27d0e3f7b065e","perf-guide/src/vert-hor-ops.md":"c6211c0ee91e60552ec592d89d9d957eedc21dee3cbd89e1ad6765ea06a27471","rustfmt.toml":"d99a43f3f8ef9e425cf01c333fba9f0051f888f5d87ab4e8f63c2f7d0fe6620f","src/api.rs":"bb1795e9657a8298d37d2349b45443f08e9e455399ad4b727018600728478c10","src/api/bit_manip.rs":"c47a4d0f7451f7e35d07715e4f39a472e07457fd456fdb726864a4f6887252a3","src/api/bitmask.rs":"6d2beefd62ee5d9c8eb060bee6abc641616bf828c99f82abf97b21bf004e894b","src/api/cast.rs":"03b94a3d316ac7b7be7068810044911e965e889a0ace7bae762749ca74a92747","src/api/cast/macros.rs":"b0a14d0c83ad2ebb7a275180f6d9e3f2bc312ba57a7d3d6c39fad4e0f20f9408","src/api/cast/v128.rs":"edd0994efac4379dff26e178423a52dbb3ffeb38b1fc97cae975d744c00b4fb6","src/api/cast/v16.rs":"96bd98c2d21b0663abe6c0ab33005b1fa693f3db7ee6795351391343863484da","src/api/cast/v256.rs":"8c31fe91f5e78ef737dfba6979cc1240210cb094a89d284fe459bf8a991ca24b","src/api/cast/v32.rs":"a99a79dd84d2a5e6adf9db98705675915bd03fd1287d489c7fe38e84d7e4a086","src/api/cast/v512.rs":"c0dd526f41ed7b8a71c3743d91267554ec0a0c75834ccc2e3ecb0ef3004af642","src/api/cast/v64.rs":"6572fdba2a1241a6cd666d3f0cce3306cd2cb7e5e236172e59d5d4351c8a88af","src/api/cmp.rs":"357c3a2a09c6d4611c32dd7fa95be2fae933d513e229026ec9b44451a77b884e","src/api/cmp/eq.rs":"60f70f355bae4cb5b17db53204cacc3890f70670611c17df638d4c04f7cc8075","src/api/cmp/ord.rs":"589f7234761c294fa5df8f525bc4acd5a47cdb602207d524a0d4e19804cd9695","src/api/cmp/partial_eq.rs":"902ccb8aa01fd5738b30ba0b712669c21d4801958907e03bad23432c7dba0198","src/api/cmp/partial_ord.rs":"9db0c37d7434cdfc62d8d66912e972fa3d8c115ab2af051a6f45e414bd3e4f1c","src/api/cmp/vertical.rs":"de3d62f38eba817299aa16f1e1939954c9a447e316509397465c2830852ba053","src/api/default.rs":"67bf21c134127d12a7028c8b88a57f0ceee8ccbd74976da8ca74eb9f16a174d5","src/api/fmt.rs":"67fb804bb86b6cd77cf8cd492b5733ce437071b66fe3297278b8a6552c325dda","src/api/fmt/binary.rs":"02b2b287f7404f8a983813cf70c87108c8da3835578b63ab303116885f609413","src/api/fmt/debug.rs":"56e1c3bdc092747344fffaafff9da7163ee7827857f6fb7cb1c9923eca4f6fa0","src/api/fmt/lower_hex.rs":"558fd592f7f485712fb051509cecc7174a21e6bf62e5ce64766e75afc97bb8e1","src/api/fmt/octal.rs":"3b2e70877a4f368c7704f8e254236c014c365c74d93371c1feb5f030e6c66422","src/api/fmt/upper_hex.rs":"2a442f666bc80e22d41f903f881238fe114dd49344c3ed69849250e853cafc5d","src/api/from.rs":"2e599d8329cb05eaf06224cc441355c4b7b51254fc19256619333be8c149d444","src/api/from/from_array.rs":"dd3fc64fb17d6184bb60343f8da26a05edf0e5f3c14caf55d49fa15e21d948dc","src/api/from/from_vector.rs":"9764371aa9e6005aace74dea14f59e5611a095b7cf42707940924749282c52f0","src/api/hash.rs":"5076ece87969592c876486f5b1ea8affbeaec379d1a14a30859e0aa5592019de","src/api/into_bits.rs":"1ee15923352786b9ab4a31fa506762297116b18cfdb8e72853abc8ad001651d2","src/api/into_bits/arch_specific.rs":"e7445021f3908326bfee758835e5fc5ad56aa1baa77fc1c58abe4350c66c670a","src/api/into_bits/macros.rs":"bb4fe99be2af6a21d805efab44c8e4e61a7b2adb42a65504a0cf26d13efdadcd","src/api/into_bits/v128.rs":"145a44922b09a5ca5b62d88a461d327d399a997a15db4b11d7b17e554a9fa4c0","src/api/into_bits/v16.rs":"f4f4f61ba88aa51b158ec56ca3dce234349aea0daf2b3029a14ab5125d1e41e5","src/api/into_bits/v256.rs":"8cea9c5d9809f11323cb7cdc53b83df593fd17caf926251e412ae9777bed547f","src/api/into_bits/v32.rs":"905ba683d342fa32f4202b80bb46530807bd0a5b588f6c2e8c9f475223c47775","src/api/into_bits/v512.rs":"e25afa1fbf088a5d58e7d75d197b6cd4c56637ea28542ba18e46a451f29d04e7","src/api/into_bits/v64.rs":"d6238022ccff7b92e55b3f6017fc269acb6f36330a6d7e8fb389853a0f1b6478","src/api/math.rs":"8b2a2fc651917a850539f993aa0b9e5bf4da67b11685285b8de8cdca311719ec","src/api/math/float.rs":"61d2794d68262a1090ae473bd30793b5f65cf732f32a6694a3af2ce5d9225616","src/api/math/float/abs.rs":"5b6b2701e2e11135b7ce58a05052ea8120e10e4702c95d046b9d21b827b26bf8","src/api/math/float/consts.rs":"6302c9261da4291d144d5bb53493cdd073498feb40955fb6860ea3c4d06c978a","src/api/math/float/cos.rs":"4c2dd7173728ef189314f1576c9486e03be21b7da98843b2f9011282a7979e31","src/api/math/float/exp.rs":"7c6d5f1e304f498a01cfa23b92380c815d7da0ad94eae3483783bc377d287eef","src/api/math/float/ln.rs":"54c7583f3df793b39ff57534fade27b41bb992439e5dc178252f5ca3190a3e54","src/api/math/float/mul_add.rs":"62cac77660d20159276d4c9ef066eb90c81cbddb808e8e157182c607625ad2eb","src/api/math/float/mul_adde.rs":"bae056ee9f3a70df39ec3c3b2f6437c65303888a7b843ef1a5bcf1f5aca0e602","src/api/math/float/powf.rs":"9ddb938984b36d39d82a82f862f80df8f7fb013f1d222d45698d41d88472f568","src/api/math/float/recpre.rs":"589225794ff1dbf31158dff660e6d4509ecc8befbb57c633900dea5ac0b840d6","src/api/math/float/rsqrte.rs":"a32abdcc318d7ccc8448231f54d75b884b7cbeb03a7d595713ab6243036f4dbf","src/api/math/float/sin.rs":"cbd3622b7df74f19691743001c8cf747a201f8977ad90542fee915f37dcd1e49","src/api/math/float/sqrt.rs":"0c66d5d63fb08e4d99c6b82a8828e41173aff1ac9fa1a2764a11fac217ccf2ac","src/api/math/float/sqrte.rs":"731e1c9f321b662accdd27dacb3aac2e8043b7aecb2f2161dde733bd9f025362","src/api/minimal.rs":"1f22bcc528555444e76de569ec0ae2029b9ae9d04805efeafa93369c8098036b","src/api/minimal/iuf.rs":"819cff26d3e196f807645bcc1d79eb27d9f175edb89910f2274d52a1e913cd11","src/api/minimal/mask.rs":"0cae10ae1fc65f5070e686c0c79bfba27b86b33d6c399367bd4848fb367dcec4","src/api/minimal/ptr.rs":"f65ebf21866a863485344432d9a7a9b7418f7fad5fdf841a4e2fa56ec0766ad0","src/api/ops.rs":"3e273b277a0f3019d42c3c59ca94a5afd4885d5ae6d2182e5089bbeec9de42ee","src/api/ops/scalar_arithmetic.rs":"d2d5ad897a59dd0787544f927e0e7ca4072c3e58b0f4a2324083312b0d5a21d7","src/api/ops/scalar_bitwise.rs":"482204e459ca6be79568e1c9f70adbe2d2151412ddf122fb2161be8ebb51c40c","src/api/ops/scalar_mask_bitwise.rs":"c250f52042e37b22d57256c80d4604104cfd2fbe2a2e127c676267270ca5d350","src/api/ops/scalar_shifts.rs":"c4773d435c3f9da4454327e6fbb2b5b41a1c0ebb1cca7372e69dc7a344a1b6e4","src/api/ops/vector_arithmetic.rs":"ddca15d09ddeef502c2ed66117a62300ca65d87e959e8b622d767bdf1c307910","src/api/ops/vector_bitwise.rs":"b3968f7005b649edcc22a54e2379b14d5ee19045f2e784029805781ae043b5ee","src/api/ops/vector_float_min_max.rs":"76bf8cb607e2c442923c1da1061a6b80d742d607408033c2a3761161114cf2a0","src/api/ops/vector_int_min_max.rs":"a378789c6ff9b32a51fbd0a97ffd36ed102cd1fe6a067d2b02017c1df342def6","src/api/ops/vector_mask_bitwise.rs":"5052d18517d765415d40327e6e8e55a312daaca0a5e2aec959bfa54b1675f9c8","src/api/ops/vector_neg.rs":"5c62f6b0221983cdbd23cd0a3af3672e6ba1255f0dfe8b19aae6fbd6503e231b","src/api/ops/vector_rotates.rs":"ee319eaaa449dc50ea8ef05b89d38519c6faa6753dfdce432ea7bb8520e4e8e7","src/api/ops/vector_shifts.rs":"e510be14127c0ffd58a2573a39701da3557d66bedec09837ac8bbd44d579da00","src/api/ptr.rs":"8a793251bed6130dcfb2f1519ceaa18b751bbb15875928d0fb6deb5a5e07523a","src/api/ptr/gather_scatter.rs":"3d614f9d5b4ca201a9f7e46af4405e1d2c28ecee1620297c23b52e37b92cc0ea","src/api/reductions.rs":"ae5baca81352ecd44526d6c30c0a1feeda475ec73ddd3c3ec6b14e944e5448ee","src/api/reductions/bitwise.rs":"8bf910ae226188bd15fc7e125f058cd2566b6186fcd0cd8fd020f352c39ce139","src/api/reductions/float_arithmetic.rs":"47a5679896db2cbb56c31372fe42143da015b6beae7db5d2f3a0309ddf427ae1","src/api/reductions/integer_arithmetic.rs":"c2df3cf7493cca4174f2c65aea422a3d20d8a23af03f8d57cef72c19fee8f20d","src/api/reductions/mask.rs":"db83327a950e33a317f37fd33ca4e20c347fb415975ec024f3e23da8509425af","src/api/reductions/min_max.rs":"6af8c9aa45c69961b1b6fc205395f4767d4421869fb105fb3d563c5605fc13cd","src/api/select.rs":"6b07e7e8026df561f7307221a896f0fbb272536f41b9109040ac094c24c69331","src/api/shuffle.rs":"26458aec2557bfab41b7765f72aefbff3a7ee08cdc689981a81f133f58ee368b","src/api/shuffle1_dyn.rs":"bfea5a91905b31444e9ef7ca6eddb7a9606b7e22d3f71bb842eb2795a0346620","src/api/slice.rs":"ee87484e8af329547b9a5d4f2a69e8bed6ea10bbd96270d706083843d4eea2ac","src/api/slice/from_slice.rs":"9b6f01ace2d12ef45c84608bb7aad3a122e2cc319b2d99170fc332a568b8de63","src/api/slice/write_to_slice.rs":"244b6bd6ccffa6e5a195f8b1abc66d94251b6d16b2ec3fe4d76d32caec68261e","src/api/swap_bytes.rs":"4a6792a2e49a77475e1b237592b4b2804dbddb79c474331acd0dd71b36934259","src/codegen.rs":"db4f232fb9f5728db310b87dc8c4733be48afacab1053798c06106bef9a42b05","src/codegen/bit_manip.rs":"525ea6ff7ad1e043b6f6136992166f1803ed5563b7f6fc292c1c40257d20e264","src/codegen/llvm.rs":"b4ccbc0bad90038f00fc3c158736462d01d0053df3afa00f9169e67d1a264444","src/codegen/math.rs":"dfcf02ad34e2fdfe22c3f1cc2822001cc895e65031b4d06e585e5047839febb7","src/codegen/math/float.rs":"2c1cbce155bc527ce34d472c0fef6bc3dadb79cd7a357dd7aa5b1ebeb1d77a13","src/codegen/math/float/abs.rs":"d5aaadcf540bdb9b4264dca6471a255fd7bf509e763bef0239c0144a68466fea","src/codegen/math/float/cos.rs":"17f28d2900c852dca221fa9c92a9cd5fe7fd2df8d427bbc60216c749b2be013d","src/codegen/math/float/cos_pi.rs":"dbaf9f443f9846a491d4ec52210a7b5835dd593b03366e3135b05c37d70f9d6c","src/codegen/math/float/exp.rs":"d300058a4bcc7ae7976f216f81902cd73a9e603ad63880dff3bbc866c27a9f37","src/codegen/math/float/ln.rs":"c851e211e43f8256093ba75b03ae0c307c9962ee66d94f09b4dd80068190cbdf","src/codegen/math/float/macros.rs":"fc9924869ed85e4795983af228cacf23158f4f35919adce16c920ad4a3f0a009","src/codegen/math/float/mul_add.rs":"041a5b69d5991d93ef795351b17560c10faf80b78fd26ad7df42a239b32cf9de","src/codegen/math/float/mul_adde.rs":"d71d5f0f3333b62a7439b823cb7adf5340ea1555ce820fb4a3f4cb922f73f5f5","src/codegen/math/float/powf.rs":"9742c3877f1a5509ca5c9492a40884b6579ba6dd11c26b7112e63f70666b395d","src/codegen/math/float/sin.rs":"0e9868d35531566509f3a01d85d5253045eb4afa8525d8407dcc1f5f33c56036","src/codegen/math/float/sin_cos_pi.rs":"8e6b6142d7dd240cdb36669722e82ab9810a2261e86e659f7d97a942ad8b1258","src/codegen/math/float/sin_pi.rs":"bb6d39db8f921e03a301fc5206ac1a61a97def8a2cb83b87ccf189f3fc48d548","src/codegen/math/float/sqrt.rs":"e6ebb0c5f428efad1f672b9a8fe4e58534dbf1ea5a8fe092ce5ce76b52fe89cb","src/codegen/math/float/sqrte.rs":"23acfaea38d0e081a6d9021c1094e813d0cfd12c58c1eca9662aade5e625d51c","src/codegen/pointer_sized_int.rs":"6ca13c214b6cf7e0929dbe18e96a16fc0bb7d8799608df29c4c8115490f99e01","src/codegen/reductions.rs":"8eb18ebac76985d2aa30262a2edd8cb004230b511a765d657525f677a585c12c","src/codegen/reductions/mask.rs":"e67f35a1f4d156a4894a2d6ea5a935b4d898cf70eefb2715f5c1cc165e776c11","src/codegen/reductions/mask/aarch64.rs":"84b101c17cad1ede4eb6d38cada0ac7da239dba8cea3badd3829b967e558431f","src/codegen/reductions/mask/arm.rs":"aaa07129bd078ae7e677cf8b8e67ec9f30536606a0c7ed1baaa18fd1793bb218","src/codegen/reductions/mask/fallback.rs":"3eb9319d2c7cf19216b607b8459612c4e027b643cf11b036937d36896bf76786","src/codegen/reductions/mask/fallback_impl.rs":"76547f396e55ef403327c77c314cf8db8c7a5c9b9819bfb925abeacf130249e5","src/codegen/reductions/mask/x86.rs":"36dcd8af4ab99730a078ed113d3955f74eb1a2876e2e6d9f224e0ff462c216d1","src/codegen/reductions/mask/x86/avx.rs":"3a40868b38c86e35aefb96d7578de6322efe89d8135e0366359b54ddd06f861a","src/codegen/reductions/mask/x86/avx2.rs":"677aed3f056285285daa3adff8bc65e739630b4424defa6d9665e160f027507e","src/codegen/reductions/mask/x86/sse.rs":"8522f6ed03f6c32dd577d4298df477c08aeaaa38563706f29096e1911ed731f2","src/codegen/reductions/mask/x86/sse2.rs":"54ec56e49b0c6841eccb719e4f310d65fe767c04136b2ec20bd8b9d7d9897b9e","src/codegen/shuffle.rs":"1ec2930f4e1acc43ac30b518af298d466a79e9e75734a51c380b7810efd1a27f","src/codegen/shuffle1_dyn.rs":"3f13ca1597378758d05106bf5ff3715eee531f3cb6d88f48b9182bd6c9386b51","src/codegen/swap_bytes.rs":"c67c86e91ca3fc77539e0efcea081a3c62548cccf503963ae408f2e86f4e6a21","src/codegen/v128.rs":"94226b31ec403d18d9d2fe06713f147c9c79e9b5f9105089088266313f843185","src/codegen/v16.rs":"ddec4ffb66b6f7aaffb9a1780c5ddba82557abd74f45073d335047e04cf74924","src/codegen/v256.rs":"6b63917f0444118d6b1595bff2045e59b97c4d24012bd575f69f1f0efc5a0241","src/codegen/v32.rs":"3477b3c5540aed86e61e2f5807dd31db947413cec9181c587d93ed6ec74f0eba","src/codegen/v512.rs":"5854f99d3aabc4cd42b28a20d9ce447756dc2ba024a409a69b6a8ae1f1842fc5","src/codegen/v64.rs":"e9e89caebfe63d10c0cbca61e4dfdba3b7e02ee0989170f80beed23237ddd950","src/codegen/vPtr.rs":"f0753b405cdc865bdf8e82c6505f299ea1f96136239ebbaf7f9ce93d310764b8","src/codegen/vSize.rs":"c89f5fdeb28ac4c8272ed1816fce03d9d95308cc32bb2533bd8b20cd5ac102ac","src/lib.rs":"b6f846d5d30cf6b035a2d18039aba7b2045cf89384733d643572bd68873ae064","src/masks.rs":"70fc0abe4c2907ce2a491c574e1cfb9f3423385da2e1a923a48c9c13f8ba6ed8","src/sealed.rs":"ae7fdeaf5d84cd7710ed730ca72ca7eaba93df6cb0acb183e5c0a7327acf197f","src/testing.rs":"896669c08d8c801448a4d2fadc9d633eda0fbe879d229997e2a182e31278e469","src/testing/macros.rs":"403bbc5ecb7c786fe36156df302d0c07a8122408dbb15f7474d7682224ba1106","src/testing/utils.rs":"41912a92266dfe884647fc035e4242fd746100df8e839808ae0397af3759a3c8","src/v128.rs":"16cf9a8e7156b899ee9b9cd3f2dba9d13ec63289bea8c3ee9ae2e43ad9510288","src/v16.rs":"cb6465cf1e00bf530183af1819b9fe3d7eec978f8765d5e85d9b58a39a4b4045","src/v256.rs":"fe235017da18c7f3c361831c60e3173ad304d8ea1e95d64ebebc79da2d708511","src/v32.rs":"145d347855bac59b2de6508f9e594654e6c330423af9edc0e2ac8f4d1abdf45e","src/v512.rs":"f372f277f3e62eb5c945bb1c460333fdb17b6974fcc876633788ff53bded9599","src/v64.rs":"0b8079881b71575e3414be0b7f8f7eaba65281ba6732f2b2f61f73e95b6f48f7","src/vPtr.rs":"8b3e433d487180bb4304ff71245ecad90f0010f43e139a72027b672abe58facc","src/vSize.rs":"eda5aa020706cbf94d15bada41a0c2a35fc8f3f37cb7c2cd6f34d201399a495e","tests/endianness.rs":"2783d727e8ff8789211e03120634cd3ad9f8972fc484012681b5b63cf89408a7"},"package":null}
+\ No newline at end of file